装饰器模式:为已经存在对象添加增强的功能,避免出现将所有方法置于同一个类中。
具体操作:生成装饰类基类,通过装饰类子类的形式来添加对象的功能。
#待装饰的类和对象
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