Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Паттерны проектирования 5.1

Vitaly Shlyaga
December 07, 2012

Паттерны проектирования 5.1

Паттерн Декоратор.

Vitaly Shlyaga

December 07, 2012
Tweet

More Decks by Vitaly Shlyaga

Other Decks in Education

Transcript

  1. Декоратор Структурный паттерн проектирования, предназначенный для динамического подключения дополнительного поведения

    к объекту. Предоставляет гибкую альтернативу практике создания подклассов с целью расширения функциональности.
  2. Декоратор class EnhancedWriter attr_reader :check_sum def initialize(path) @file = File.open(path,

    "w") @check_sum = 0 @line_number = 1 end def write_line(line) @file.print(line) @file.print("\n") end def checksumming_write_line(data) data.each_byte {|byte| @check_sum = (@check_sum + byte) % 256 } @check_sum += "\n"[0] % 256 write_line(data) end def timestamping_write_line(data) write_line("#{Time.new}: #{data}") end def numbering_write_line(data) write_line("%{@line_number}: #{data}") @line_number += 1 end def close @file.close end end
  3. Декоратор writer = EnhancedWriter.new('out.txt') writer.write_line("A plain line") writer.checksumming_write_line('A line with

    checksum') puts("Checksum is #{writer.check_sum}") writer.timestamping_write_line('with time stamp') writer.numbering_write_line('with line number')
  4. Декоратор class SimpleWriter def initialize(path) @file = File.open(path, 'w') end

    def write_line(line) @file.print(line) @file.print("\n") end def pos @file.pos end def rewind @file.rewind end def close @file.close end end
  5. Декоратор class WriterDecorator def initialize(real_writer) @real_writer = real_writer end def

    write_line(line) @real_writer.write_line(line) end def pos @real_writer.pos end def rewind @real_writer.rewind end def close @real_writer.close end end
  6. Декоратор class NumberingWriter < WriterDecorator def initialize(real_writer) super(real_writer) @line_number =

    1 end def write_line(line) @real_writer.write_line("#{@line_number}: #{line}") @line_number += 1 end end writer = NumberingWriter.new(SimpleWriter.new('final.txt')) writer.write_line('Hello out there')
  7. Декоратор class CheckSummingWriter < WriterDecorator attr_reader :check_sum def initialize(real_writer) @real_writer

    = real_writer @check_sum = 0 end def write_line(line) line.each_byte {|byte| @check_sum = (@check_sum + byte) % 256 } @check_sum += "\n"[0] % 256 @real_writer.write_line(line) end end class TimeStampingWriter < WriterDecorator def write_line(line) @real_writer.write_line("#{Time.new}: #{line}") end end writer = CheckSummingWriter.new(TimeStampingWriter.new( NumberingWriter.new(SimpleWriter.new('final.txt')))) writer.write_line('Hello out there')
  8. Декоратор-2 require 'forwardable' class WriterDecorator extend Forwardable def_delegators :@real_writer, :write_line,

    :rewind, :pos, :close def initialize(real_writer) @real_writer = real_writer end end
  9. Декоратор-3 w = SimpleWriter.new('out') class << w alias old_write_line write_line

    def write_line(line) old_write_line("#{Time.new}: #{line}") end end
  10. Декоратор-4 module TimeStampingWriter def write_line(line) super("#{Time.new}: #{line}") end end module

    NumberingWriter attr_reader :line_number def write_line(line) @line_number = 1 unless @line_number super("#{@line_number}: #{line}") @line_number += 1 end end class Writer define write(line) @f.write(line) end end
  11. Декоратор Используется для конструрования необходимого функционала во время выполнения программы.

    Все декораторы одной группы поддерживают одинаковый интерфейс. Каждый принимает вызов метода, обрабатывает информацию и передаёт её следующему декоратору или конечному компоненту.
  12. Задача 1 Разработать несколько (не менее 3) декораторов для вывода

    на экран элементов массива. Придумать собственные декораторы (не такие как в слайдах).