装饰器模式:为已经存在对象添加增强的功能,避免出现将所有方法置于同一个类中。

具体操作:生成装饰类基类,通过装饰类子类的形式来添加对象的功能。

#待装饰的类和对象
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.colse
  end
end

#装饰器基类
class WriterDecorator
  def initialize(real_writer)
    @real_writer = real_writer
  end

  def write_line
    @real_writer.write_line
  end

  def pos
    @real_writer.pos
  end

  def rewind
    @real_writer.rewind
  end

  def close
    @real_writer.close
  end
end

#装饰器子类
class TimeStampingWriter < WriterDecorator
  def write_line(line)
    @real_writer.write_line("#{Time.now}: #{line}")
  end
end
#添加对象的功能
demo = TimeStampingWriter.new(SimpleWriter.new("./mix.txt"))
demo.write_line("hello,world")

#cat mix.txt
2018-06-19 15:03:57 +0800: hello,world

可以实现链式操作,为对象一点一点增加功能。

#添加另外一个装饰器子类
class NumberingWriter < WriterDecorator
  attr_accessor :line_number

  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

#链式操作
demo = NumberingWriter.new(TimeStampingWriter.new(SimpleWriter.new("./demo.txt")))
demo.write_line("hello,world")

#cat.txt
2018-06-19 15:19:31 +0800: 1:hello,world  #添加了NumberingWriter和TimeStampingWriter的两个功能

使用装饰器的extend形式

#被装饰类SimpleWriter如上所示,没有修改
#添加如下的module
module TimeStampingWriter
  def write_line(line)
    super("#{Time.now}: #{line}")
  end
end

module NumberingWriter
  attr_accessor :line_number

  def write_line(line)
    @line_number = 1 unless @line_number
    super("#{@line_number}:#{line}")
    @line_number += 1
  end
end


demo = SimpleWriter.new("./demo.txt")
demo.extend(NumberingWriter)
demo.extend(TimeStampingWriter)
demo.write_line("hello,ruby")

#cat demo.txt
1:2018-06-19 15:34:04 +0800: hello,ruby  #依次执行TimeStampingWriter、NumberingWriter中的方法

使用装饰器的alias形式

#被装饰类SimpleWriter如上所示,没有修改
#添加如下的alias关键词
demo = SimpleWriter.new("./demo.txt")
class << demo
  alias old_write_line write_line

  def write_line(line)
    old_write_line("#{Time.now}:#{line}")
  end
end

demo.write_line("hello,world")

#cat demo.txt
2018-06-19 15:45:15 +0800:hello,world

results matching ""

    No results matching ""