Но если изменение в А требует изменения в B, а то, в свою очередь, изменения в C и т.д. — это плохо. Если сразу определить части системы, которые могут меняться, можно отделить их от всего остального. Конечно, правки всё равно придётся вносить, но это будут правки в рамках одного конкретного модуля, а не правки размазанные по всей системе.
двигатель end def stop_engine # Остановить двигатель end end class Car < Vehicle def sunday_drive start_engine # Покататься stop_engine end end Vehicle Car start_engine() stop_engine()
двигатель end def stop # Остановить двигатель end end class Car def initialize @engine = Engine.new end def sunday_drive @engine.start # Покататься @engine.stop end end Vehicle Car start_engine() stop_engine() Engine
sunday_drive @engine.start # Покататься @engine.stop end def switch_to_diesel @engine = DieselEngine.new end def start_engine @engine.start end def stop_engine @engine.stop end end
***") elsif format == :html puts('<html>') puts(' <head>') puts(" <title>#{@title}</title>") puts(' </head>') puts(' <body>') else raise "Unknown format: #{format}" end @text.each do |line| if format == :plain puts(line) else puts(" <p>#{line}</p>" ) end end if format == :html puts(' </body>') puts('</html>') end end
с форматом. Вывести заголовок отчёта. Вывести каждую строчку отчёта. Вывести конечную служебную информацию, которая требуется в соответствии с форматом.
различное поведение, изменяя составные части базового алгоритма. Базовый класс может не реализовывать детали функционала, а только реализовывать базовый алгоритм — в таком случае детали полностью лежат на подклассах. Либо базовый класс может представлять реализацию по-умолчанию, которую подклассы могут переопределять.
абстрактный метод' end end class HTMLFormatter < Formatter def output_report( title, text ) puts('<html>') puts(' <head>') puts(" <title>#{title}</title>") puts(' </head>') puts(' <body>') text.each do |line| puts(" <p>#{line}</p>" ) end puts(' </body>') puts('</html>') end end
с помощью делегирования, а не наследования. Позволяет на лету менять поведение «главного» объекта, выбирая разные объекты-стратегии. Можно передавать отдельные параметры в стратегию или сам экземпляр главного объекта. В Ruby удобно «стратегии» реализовывать с помощью Proc-объектов.
и выполняет некоторую математическую операцию (def calculate) над ними. С помощью паттернов Template Method и Strategy реализовать сложение, умножение и возведение в степень этих чисел. Реализовать класс Math «в стиле Ruby», используя Proc для передачи алгоритма в контекст.