From 582c184acb913afb5a3c1410c53152440880a92a Mon Sep 17 00:00:00 2001 From: Artem Darius Weber Date: Fri, 3 Jan 2025 11:49:25 +0300 Subject: [PATCH] refactor: remove Contact class and integrate contact attributes directly into Person and Student classes --- lab2/contact.rb | 71 ------------------------------------------- lab2/main.rb | 24 ++++++++------- lab2/person.rb | 57 ++++++++++++++++++++++++++-------- lab2/student.rb | 35 +++++++++++---------- lab2/student_short.rb | 32 +++++++++++++++---- 5 files changed, 101 insertions(+), 118 deletions(-) delete mode 100644 lab2/contact.rb diff --git a/lab2/contact.rb b/lab2/contact.rb deleted file mode 100644 index cfde7f3..0000000 --- a/lab2/contact.rb +++ /dev/null @@ -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 \ No newline at end of file diff --git a/lab2/main.rb b/lab2/main.rb index 58fd1f7..c8863aa 100644 --- a/lab2/main.rb +++ b/lab2/main.rb @@ -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) diff --git a/lab2/person.rb b/lab2/person.rb index ae90c5a..6b9700f 100644 --- a/lab2/person.rb +++ b/lab2/person.rb @@ -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 diff --git a/lab2/student.rb b/lab2/student.rb index 38793b4..7aac56e 100644 --- a/lab2/student.rb +++ b/lab2/student.rb @@ -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 \ No newline at end of file diff --git a/lab2/student_short.rb b/lab2/student_short.rb index 2abc464..5f950f0 100644 --- a/lab2/student_short.rb +++ b/lab2/student_short.rb @@ -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 \ No newline at end of file