refactor: remove Contact class and integrate contact attributes directly into Person and Student classes

lab2
Artem-Darius Weber 7 days ago
parent a78cbb3a67
commit 582c184acb

@ -1,71 +0,0 @@
class Contact
attr_reader :phone, :telegram, :email
def initialize(args = {})
self.phone = args[:phone]
self.telegram = args[:telegram]
self.email = args[:email]
raise ArgumentError, "Необходимо указать хотя бы один контакт (телефон, Telegram или email)" unless present?
end
def present?
@phone || @telegram || @email
end
def get_single_contact
return "Phone: #{@phone}" if @phone
return "Telegram: #{@telegram}" if @telegram
return "Email: #{@email}" if @email
'No contact available'
end
def phone=(phone)
if phone && !self.class.valid_phone_number?(phone)
raise ArgumentError, "Недопустимый номер телефона: #{phone}"
end
@phone = phone
end
def telegram=(telegram)
if telegram && !self.class.valid_telegram?(telegram)
raise ArgumentError, "Некорректный Telegram: #{telegram}"
end
@telegram = telegram
end
def email=(email)
if email && !self.class.valid_email?(email)
raise ArgumentError, "Некорректный email: #{email}"
end
@email = email
end
def self.valid_phone_number?(phone)
/\A\+?[0-9]{9,15}\z/.match?(phone)
end
def self.valid_telegram?(telegram)
/\A@[A-Za-z0-9_]{5,32}\z/.match?(telegram)
end
def self.valid_email?(email)
/\A[^@\s]+@[^@\s]+\.[^@\s]+\z/.match?(email)
end
def self.new_from_info(info_string)
info_string = info_string.sub(/^Contact: /, '').strip
case info_string
when /\APhone: (.+)\z/i
new(phone: Regexp.last_match(1).strip)
when /\ATelegram: (.+)\z/i
new(telegram: Regexp.last_match(1).strip)
when /\AEmail: (.+)\z/i
new(email: Regexp.last_match(1).strip)
else
raise ArgumentError, "Некорректный формат строки контакта: #{info_string}"
end
end
end

@ -1,5 +1,4 @@
require 'date'
require_relative 'contact'
require_relative 'person'
require_relative 'student'
require_relative 'student_short'
@ -7,20 +6,19 @@ require_relative 'student_repository'
require_relative 'binary_search_tree'
def test_classes
contact = Contact.new(phone: '+798912465', telegram: '@example_user', email: 'test@example.com')
puts "Contact Info: #{contact.get_single_contact}"
person = Person.new(id: '1', git: 'https://github.com/example', contact: contact)
person = Person.new(id: '1', git: 'https://github.com/example', phone: '+798912465', telegram: '@example_user', email: 'test@example.com')
puts "Person Contact Info: #{person.contact_info}"
student = Student.new(
id: '2',
git: 'https://github.com/student_example',
contact: contact,
surname: 'Иванов',
name: 'Иван',
patronymic: 'Иванович',
birth_date: Date.new(2000, 5, 15)
birth_date: Date.new(2000, 5, 15),
phone: '+79891234567',
telegram: '@student_ivan',
email: 'ivanov@example.com'
)
puts "Student Full Info: #{student.to_s}"
puts "Student Initials: #{student.surname_and_initials}"
@ -55,20 +53,24 @@ def test_binary_search_tree
student1 = Student.new(
id: '1',
git: 'https://github.com/student1',
contact: Contact.new(phone: '+123456789', telegram: '@student1', email: 'student1@example.com'),
surname: 'Смирнов',
name: 'Алексей',
patronymic: 'Иванович',
birth_date: Date.new(1999, 2, 15)
birth_date: Date.new(1999, 2, 15),
phone: '+123456789',
telegram: '@student1',
email: 'student1@example.com'
)
student2 = Student.new(
id: '2',
git: 'https://github.com/student2',
contact: Contact.new(phone: '+987654321', telegram: '@student2', email: 'student2@example.com'),
surname: 'Иванов',
name: 'Иван',
patronymic: 'Сергеевич',
birth_date: Date.new(2001, 5, 10)
birth_date: Date.new(2001, 5, 10),
phone: '+987654321',
telegram: '@student2',
email: 'student2@example.com'
)
bst.add(student1)

@ -1,13 +1,15 @@
class Person
attr_reader :id, :git, :contact
attr_reader :id, :git, :phone, :telegram, :email
def initialize(id:, git:, contact: Contact.new)
def initialize(id:, git:, phone: nil, telegram: nil, email: nil)
self.class.validate_id(id)
self.class.validate_contact(contact)
self.phone = phone
self.telegram = telegram
self.email = email
raise ArgumentError, "Необходимо указать хотя бы один контакт (телефон, Telegram или email)" unless contact_present?
@id = id
@git = git
@contact = contact
end
def git_present?
@ -15,11 +17,48 @@ class Person
end
def contact_present?
@contact.present?
@phone || @telegram || @email
end
def contact_info
@contact.get_single_contact
return "Phone: #{@phone}" if @phone
return "Telegram: #{@telegram}" if @telegram
return "Email: #{@email}" if @email
'No contact available'
end
def self.valid_phone_number?(phone)
/\A\+?[0-9]{9,15}\z/.match?(phone)
end
def self.valid_telegram?(telegram)
/\A@[A-Za-z0-9_]{5,32}\z/.match?(telegram)
end
def self.valid_email?(email)
/\A[^@\s]+@[^@\s]+\.[^@\s]+\z/.match?(email)
end
def phone=(phone)
if phone && !self.class.valid_phone_number?(phone)
raise ArgumentError, "Недопустимый номер телефона: #{phone}"
end
@phone = phone
end
def telegram=(telegram)
if telegram && !self.class.valid_telegram?(telegram)
raise ArgumentError, "Некорректный Telegram: #{telegram}"
end
@telegram = telegram
end
def email=(email)
if email && !self.class.valid_email?(email)
raise ArgumentError, "Некорректный email: #{email}"
end
@email = email
end
def git=(git)
@ -27,7 +66,6 @@ class Person
@git = git
end
# Методы класса
def self.validate_id(id)
raise ArgumentError, 'ID is required and must be a non-empty string' unless valid_id?(id)
end
@ -37,11 +75,6 @@ class Person
raise ArgumentError, 'Invalid Git link format' unless valid_git?(git)
end
def self.validate_contact(contact)
raise ArgumentError, 'Contact must be a valid Contact object' unless contact.is_a?(Contact)
raise ArgumentError, 'Contact must have at least one valid field' unless contact.present?
end
def self.valid_git?(git)
/\Ahttps:\/\/github\.com\/[A-Za-z0-9_\-]+\z/.match?(git)
end

@ -1,5 +1,4 @@
require_relative 'person'
require_relative 'contact'
class Student < Person
attr_accessor :surname, :name, :patronymic, :birth_date
@ -10,12 +9,12 @@ class Student < Person
public
def initialize(id:, git:, contact:, surname: nil, name: nil, patronymic: nil, birth_date: nil)
super(id: id, git: git, contact: contact)
@surname = surname
@name = name
@patronymic = patronymic
@birth_date = birth_date
def initialize(id:, git:, surname:, name:, patronymic:, birth_date:, phone: nil, telegram: nil, email: nil)
super(id: id, git: git, phone: phone, telegram: telegram, email: email)
self.surname = surname
self.name = name
self.patronymic = patronymic
self.birth_date = birth_date
end
def self.from_string(student_string)
@ -33,16 +32,16 @@ class Student < Person
git = parts[5].split(': ').last
birth_date = Date.parse(parts[6].split(': ').last)
contact = Contact.new(phone: phone, telegram: telegram, email: email)
new(
id: id,
git: git,
contact: contact,
surname: surname,
name: name,
patronymic: patronymic,
birth_date: birth_date
birth_date: birth_date,
phone: phone,
telegram: telegram,
email: email
)
end
@ -52,8 +51,8 @@ class Student < Person
def to_s
"#{@surname} #{@name} #{@patronymic} | ID: #{@id} | " \
"Phone: #{@contact.phone || 'N/A'} | Telegram: #{@contact.telegram || 'N/A'} | " \
"Email: #{@contact.email || 'N/A'} | Git: #{@git} | Birth Date: #{@birth_date}"
"Phone: #{@phone || 'N/A'} | Telegram: #{@telegram || 'N/A'} | " \
"Email: #{@email || 'N/A'} | Git: #{@git} | Birth Date: #{@birth_date}"
end
def get_info
@ -62,21 +61,21 @@ class Student < Person
def surname=(surname)
raise ArgumentError, 'Surname is required' if surname.nil? || surname.strip.empty?
raise ArgumentError, "Invalid surname format: #{surname}" unless valid_name?(surname)
raise ArgumentError, "Invalid surname format: #{surname}" unless self.class.valid_name?(surname)
@surname = surname
end
def name=(name)
raise ArgumentError, 'Name is required' if name.nil? || name.strip.empty?
raise ArgumentError, "Invalid name format: #{name}" unless valid_name?(name)
raise ArgumentError, "Invalid name format: #{name}" unless self.class.valid_name?(name)
@name = name
end
def patronymic=(patronymic)
raise ArgumentError, 'Patronymic is required' if patronymic.nil? || patronymic.strip.empty?
raise ArgumentError, "Invalid patronymic format: #{patronymic}" unless valid_name?(patronymic)
raise ArgumentError, "Invalid patronymic format: #{patronymic}" unless self.class.valid_name?(patronymic)
@patronymic = patronymic
end
@ -101,4 +100,4 @@ class Student < Person
def patronymic_initial(patronymic)
patronymic[0].upcase
end
end
end

@ -3,8 +3,8 @@ require_relative 'person'
class StudentShort < Person
attr_reader :surname_initials
def initialize(id:, git:, surname_initials:, contact:)
super(id: id, git: git, contact: contact)
def initialize(id:, git:, surname_initials:, phone: nil, telegram: nil, email: nil)
super(id: id, git: git, phone: phone, telegram: telegram, email: email)
@surname_initials = surname_initials
end
@ -13,7 +13,9 @@ class StudentShort < Person
id: student.id,
git: student.git,
surname_initials: student.surname_and_initials,
contact: student.contact
phone: student.phone,
telegram: student.telegram,
email: student.email
)
end
@ -25,17 +27,35 @@ class StudentShort < Person
git = parts[1].split(': ').last.strip
contact_string = parts[2].split(': ', 2).last.strip
contact = Contact.new_from_info(contact_string)
phone, telegram, email = parse_contact_string(contact_string)
new(
id: id,
git: git,
surname_initials: surname_initials,
contact: contact
phone: phone,
telegram: telegram,
email: email
)
end
def to_s
"#{@surname_initials}, Git: #{@git}, Contact: #{@contact}"
contact_info = contact_info()
"#{@surname_initials}, Git: #{@git}, Contact: #{contact_info}"
end
private
def self.parse_contact_string(contact_string)
case contact_string
when /\APhone: (.+)\z/i
[Regexp.last_match(1).strip, nil, nil]
when /\ATelegram: (.+)\z/i
[nil, Regexp.last_match(1).strip, nil]
when /\AEmail: (.+)\z/i
[nil, nil, Regexp.last_match(1).strip]
else
raise ArgumentError, "Invalid contact string format: #{contact_string}"
end
end
end
Loading…
Cancel
Save