ref: Extract common functionality into Person superclass

- Created a new superclass `Person` to encapsulate common attributes and methods for `Student` and `StudentShort`.
- Moved validation methods, contact handling, and common logic from `Student` and `StudentShort` into `Person`.
- Updated `Student` to inherit from `Person`, simplifying initialization and validation.
- Updated `StudentShort` to inherit from `Person`, reducing redundancy and aligning with the new superclass structure.
- Improved code maintainability by eliminating duplicated code and clarifying class responsibilities.
pull/4/head
Artem-Darius Weber 4 months ago
parent 68ca94d4e9
commit d387e12d7d

@ -0,0 +1,65 @@
class Person
attr_accessor :id, :git
def initialize(args = {})
@id = args[:id] || nil
@git = args[:git]
validate
end
def set_contacts(phone: nil, telegram: nil, email: nil)
@phone = phone
raise ArgumentError, "Invalid phone number format: #{@phone}" if @phone && !self.class.valid_phone_number?(@phone)
@telegram = telegram
raise ArgumentError, "Invalid telegram format: #{@telegram}" if @telegram && !self.class.valid_telegram?(@telegram)
@email = email
raise ArgumentError, "Invalid email format: #{@email}" if @email && !self.class.valid_email?(@email)
end
def self.valid_phone_number?(phone)
phone.match?(/\A\+?[0-9]{10,15}\z/)
end
def self.valid_name?(name)
name.match?(/\A[А-Яа-яЁёA-Za-z\-]+\z/)
end
def self.valid_telegram?(telegram)
telegram.nil? || telegram.match?(/\A@[A-Za-z0-9_]{5,32}\z/)
end
def self.valid_email?(email)
email.nil? || email.match?(/\A[^@\s]+@[^@\s]+\.[^@\s]+\z/)
end
def self.valid_git?(git)
git.nil? || git.match?(/\Ahttps:\/\/github\.com\/[A-Za-z0-9_\-]+\z/)
end
def git_present?
!@git.nil? && !@git.empty?
end
def contact_present?
!(@phone.nil? || @phone.empty?) || !(@telegram.nil? || @telegram.empty?) || !(@email.nil? || @email.empty?)
end
def validate
raise ArgumentError, "Git link is required" unless git_present?
raise ArgumentError, "At least one contact (phone, telegram, or email) is required" unless contact_present?
end
def contact_info
return "Phone: #{@phone}" if @phone
return "Telegram: #{@telegram}" if @telegram
return "Email: #{@email}" if @email
'No contact available'
end
private
attr_reader :phone, :telegram, :email
attr_writer :phone, :telegram, :email
end

@ -1,48 +1,24 @@
class Student
attr_accessor :id, :surname, :name, :patronymic, :git
require_relative 'person'
def self.valid_phone_number?(phone)
phone.match?(/\A\+?[0-9]{10,15}\z/)
end
def self.valid_name?(name)
name.match?(/\A[А-Яа-яЁёA-Za-z\-]+\z/)
end
def self.valid_telegram?(telegram)
telegram.nil? || telegram.match?(/\A@[A-Za-z0-9_]{5,32}\z/)
end
def self.valid_email?(email)
email.nil? || email.match?(/\A[^@\s]+@[^@\s]+\.[^@\s]+\z/)
end
def self.valid_git?(git)
git.nil? || git.match?(/\Ahttps:\/\/github\.com\/[A-Za-z0-9_\-]+\z/)
end
class Student < Person
attr_accessor :surname, :name, :patronymic
def initialize(args = {})
super(args)
@surname = args.fetch(:surname)
raise ArgumentError, "Invalid surname format: #{@surname}" unless Student.valid_name?(@surname)
raise ArgumentError, "Invalid surname format: #{@surname}" unless self.class.valid_name?(@surname)
@name = args.fetch(:name)
raise ArgumentError, "Invalid name format: #{@name}" unless Student.valid_name?(@name)
raise ArgumentError, "Invalid name format: #{@name}" unless self.class.valid_name?(@name)
@patronymic = args.fetch(:patronymic)
raise ArgumentError, "Invalid patronymic format: #{@patronymic}" unless Student.valid_name?(@patronymic)
@id = args[:id] || nil
raise ArgumentError, "Invalid patronymic format: #{@patronymic}" unless self.class.valid_name?(@patronymic)
set_contacts(
phone: args[:phone],
telegram: args[:telegram],
email: args[:email]
)
@git = args[:git]
raise ArgumentError, "Invalid git format: #{@git}" unless Student.valid_git?(@git)
validate
end
def self.from_string(student_string)
@ -66,28 +42,8 @@ class Student
)
end
def set_contacts(phone: nil, telegram: nil, email: nil)
@phone = phone
raise ArgumentError, "Invalid phone number format: #{@phone}" if @phone && !Student.valid_phone_number?(@phone)
@telegram = telegram
raise ArgumentError, "Invalid telegram format: #{@telegram}" if @telegram && !Student.valid_telegram?(@telegram)
@email = email
raise ArgumentError, "Invalid email format: #{@email}" if @email && !Student.valid_email?(@email)
end
def git_present?
!@git.nil? && !@git.empty?
end
def contact_present?
!(@phone.nil? || @phone.empty?) || !(@telegram.nil? || @telegram.empty?) || !(@email.nil? || @email.empty?)
end
def validate
raise ArgumentError, "Git link is required" unless git_present?
raise ArgumentError, "At least one contact (phone, telegram, or email) is required" unless contact_present?
def surname_and_initials
"#{@surname} #{name[0]}.#{patronymic[0]}."
end
def to_s
@ -99,25 +55,4 @@ class Student
def get_info
"#{surname_and_initials}, Git: #{git_info}, Contact: #{contact_info}"
end
def surname_and_initials
"#{@surname} #{name[0]}.#{patronymic[0]}."
end
def git_info
@git
end
def contact_info
return "Phone: #{@phone}" if @phone
return "Telegram: #{@telegram}" if @telegram
return "Email: #{@email}" if @email
'No contact available'
end
private
attr_reader :phone, :telegram, :email
attr_writer :phone, :telegram, :email
end

@ -1,10 +1,11 @@
class StudentShort
attr_reader :id, :surname_initials, :git, :contact
require_relative 'person'
class StudentShort < Person
attr_reader :surname_initials, :contact
def initialize(student)
@id = student.id
super(id: student.id, git: student.git_info)
@surname_initials = student.surname_and_initials
@git = student.git_info
@contact = student.contact_info
end

Loading…
Cancel
Save