Принципы проектирование ООП приложений - Скалкин...
Transcript of Принципы проектирование ООП приложений - Скалкин...
/evrone.
ХОРОШО ПОДДЕРЖИВАЕМЫЙ КОД
▸ Изменения не имеют неожиданных побочных эффектов
▸ Незначительные изменения в требованиях несут незначительные изменения в коде
▸ Код легко поддается повторному использованию
/evrone.
ИНСТРУМЕНТЫ ПРОЕКТИРОВАНИЯ
▸ Принципы проектирования
▸ Шаблоны проектирования
▸ Опыт и здравый смысл
/evrone.
SINGLE RESPONSIBILITY PRINCIPLE
▸ Делает бороду более шелковистой
▸ Классы и методы становятся небольшими и легко читаемыми
▸ SRP позволяет строить более четкую архитектуру классов
▸ Код легче тестировать
/evrone.
SINGLE RESPONSIBILITY PRINCIPLE
О чем говорит принцип единственной обязанности?
▸ Loose coupling / High cohension
▸ Класс должен иметь одну причину для изменения. Эта причина и называется ответственностью
/evrone.
SINGLE RESPONSIBILITY PRINCIPLE
class VideoFilesController
def publish
video.update_attribute(:published, true)
VideoMailer.deliver_video_published(video)
end
end
/evrone.
SINGLE RESPONSIBILITY PRINCIPLE
class Video
after_save :deliver_published, if: -> { cond. }
private
def deliver_published
VideoMailer.deliver_video_published(self)
end
end
class VideosController
def publish
video.update_attribute(:published, true)
VideoMailer.deliver_video_published(video)
end
end
/evrone.
SINGLE RESPONSIBILITY PRINCIPLE
class VideosController
def publish
VideoPublisher.new(video).publish
end
end
class VideoPublisher
….
def publish
video.update_attribute(:published, true)
VideoMailer.deliver_video_published(video)
end
end
/evrone.
OPEN / CLOSED PRINCIPLE
▸ Классы должны быть открыты для расширения
▸ Классы должны быть закрыты для модификации
/evrone.
OPEN / CLOSED PRINCIPLE
class FileConverter
attr_reader :file
def initialize(file)
@file = file
end
…
def convert!
case file.format
when :image
convert_image
when :video
convert_video
end
end
/evrone.
OPEN / CLOSED PRINCIPLE
class FileConverter
attr_reader :file, converter
def initialize(file, converter)
@file = file
@converter = converter
end
…
def convert!
converter.convert(file)
end
/evrone.
OPEN / CLOSED PRINCIPLE
class ImageConverter
def convert(image)
end
end
class VideoConverter
def convert(image)
end
end
/evrone.
LISKOV SUBSTITUTION PRINCIPLE
“Пусть q(x) бла бла бла x бла бла бла T. Тогда q(y) бла бла бла y бла бла бла S, где S является
подтипом типа T.” -
формальное описание принципа подстановки Барбары Лисков
/evrone.
LISKOV SUBSTITUTION PRINCIPLE
Программа должна иметь возможность заменить любое вхождение базового класса на инстанс его
потомка без негативных сайд эффектов.
/evrone.
INTERFACE SEGREGATION PRINCIPLE
class Video
def publish; end
def delete; end
end
class VideoPublisher
extend Forwardable
def_delegators :@video, :publish
def initialize(video); @video = video; end
end
VideoPublisher.new(video).publish # => true
VideoPublisher.new(video).delete #=> NoMethorError
/evrone.
DEPENDENCY INVERSION PRINCIPLE
Высокоуровневые объекты не должны опираться на детали реализации низкоуровневых объектов
/evrone.
DRY
Когда DRY goes wrong
1. Программист А видит дублирование кода и выносит его в отдельный метод. Это создает новую абстракцию.
2. Приходят новые требования, которые почти подходят этой абстракции.
3. Программист Б решает сохранить предыдущую абстракцию, добавив новый параметр методу и условие.
4. Так продолжается, пока абстракция становится не поддерживаемой.
/evrone.
LAW OF DEMETER
Метод объекта должен вызывать только методы следующих объектов:
▸ самого себя;
▸ его параметров;
▸ объектов, которые он создает;
▸ компонентов объекта.
/evrone.
LAW OF DEMETER
Аналогия от Peter Van Rooijen:
▸ You can play with yourself.
▸ You can play with your own toys (but you can’t take them apart),
▸ You can play with toys that were given to you.
▸ And you can play with toys you’ve made yourself.
/evrone.
LAW OF DEMETER
class Video
delegate :email, to: :user, prefix: :true
end
def user_email
video.user_email
end