传统的proxy:
class VirtualAccountProxy
def initialize(starting_balance=0)
@starting_balance=starting_balance
end
def deposit(amount)
s = subject
return s.deposit(amount)
end
def subject
@subject || (@subject = BankAccount.new(@starting_balance))
end
end
如果是传代码块就能把创建subject外放到创建proxy的时候...
class VirtualAccountProxy
def initialize(&creation_block)
@creation_block = creation_block
end
# Other methods omitted ...
def subject
@subject || (@subject = @creation_block.call)
end
end
account = VirtualAccountProxy.new { BankAccount.new(10)}
更进一步,创建一个代理,把所有对proxy的method调用都转给subject,但是有权限访问(本质上ruby是这么调用方法的
tmm.send(:goodbye, 'cruel', 'world')--用symbol ):
class AccountProtectionProxy
def initialize(real_account, owner_name)
@subject = real_account
@owner_name = owner_name
end
def method_missing(name, *args)
check_access
@subject.send( name, *args )
end
def check_access
raise "Illegal access: #{Etc.getlogin} cannot access account." if Etc.getlogin != @owner_name
end
end
这个模式要注意的就是如果用了method_missing之类的方法proxy和subject的角色,某些方法是针对proxcy的,某些是subject,容易搞混...如果是每个方法都显示的声明问题就不大了,不过那样代码量就上去了...
decorator 给一个具体的操作添加一系列的修饰,形成一系列的类:
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
writer = CheckSummingWriter.new(TimeStampingWriter.new(
NumberingWriter.new(SimpleWriter.new('final.txt'))))
writer.write_line('Hello out there')
还可以动态修改一个对象的类方法...
w = SimpleWriter.new('out')
class << w
alias old_write_line write_line
def write_line(line)
old_write_line("#{Time.new}: #{line}")
end
end
或者写一个module,用extend方法动态的载入这个module
module TimeStampingWriter
def write_line(line)
super("#{Time.new}: #{line}")
end
end
class Writer
def write_line(line)
puts(line)
end
end
w = Writer.new()
w.extend(TimeStampingWriter)
w.write_line('hello')
singleton
等同于java的static,类方法,用@@变量
class SimpleLogger
@@instance = SimpleLogger.new
def self.instance
return @@instance
end
private_class_method :new
end
上面用了private方法屏蔽了singleton可能的new
factory...把类的创建推迟到子类
一个concrete factory有几个具体的create_product method
在abstract factory里面只是create_product占了个位
jungle_organism_factory = OrganismFactory.new(Tree, Tiger)
pond_organism_factory = OrganismFactory.new(WaterLily, Frog)
jungle = Habitat.new(1, 4, jungle_organism_factory)
jungle.simulate_one_day
pond = Habitat.new( 2, 4, pond_organism_factory)
pond.simulate_one_day
in ruby all class is constant const_get就是拿到那个变量:
class IOFactory
def initialize(format)
@reader_class = self.class.const_get("#{format}Reader")
@writer_class = self.class.const_get("#{format}Writer")
end
def new_reader
@reader_class.new
end
end
html_factory = IOFactory.new('HTML')
html_reader = html_factory.new_reader
builder:
builder = ComputerBuilder.new
builder.turbo
builder.add_cd(true)
builder.add_dvd
builder.add_hard_disk(100000)
...
computer = builder.computer
interpreter
...这个东西要写好太烦琐了...
dsl
class Jungle < CompositeBase
composite_of(:population)
end
这类composite_of方法的实现方法...(也就是activerecord里面众多has_one, belings_to)
def self.member_of(composite_name)
code = %Q{
attr_accessor :parent_#{composite_name}
}
class_eval(code)
end
最后书中特别提出了: convention over configuration
这东西还是看情况的,规定死了,默认的条条框框多了,自然乱七八糟的东西就少了
一言堂带来更高的生产力,民主导致低效...
民主是最不坏的,但不会是最有效的o(∩_∩)o...
--------------
chenjinlai
2008-04-28
class VirtualAccountProxy
def initialize(starting_balance=0)
@starting_balance=starting_balance
end
def deposit(amount)
s = subject
return s.deposit(amount)
end
def subject
@subject || (@subject = BankAccount.new(@starting_balance))
end
end
如果是传代码块就能把创建subject外放到创建proxy的时候...
class VirtualAccountProxy
def initialize(&creation_block)
@creation_block = creation_block
end
# Other methods omitted ...
def subject
@subject || (@subject = @creation_block.call)
end
end
account = VirtualAccountProxy.new { BankAccount.new(10)}
更进一步,创建一个代理,把所有对proxy的method调用都转给subject,但是有权限访问(本质上ruby是这么调用方法的
tmm.send(:goodbye, 'cruel', 'world')--用symbol ):
class AccountProtectionProxy
def initialize(real_account, owner_name)
@subject = real_account
@owner_name = owner_name
end
def method_missing(name, *args)
check_access
@subject.send( name, *args )
end
def check_access
raise "Illegal access: #{Etc.getlogin} cannot access account." if Etc.getlogin != @owner_name
end
end
这个模式要注意的就是如果用了method_missing之类的方法proxy和subject的角色,某些方法是针对proxcy的,某些是subject,容易搞混...如果是每个方法都显示的声明问题就不大了,不过那样代码量就上去了...
decorator 给一个具体的操作添加一系列的修饰,形成一系列的类:
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
writer = CheckSummingWriter.new(TimeStampingWriter.new(
NumberingWriter.new(SimpleWriter.new('final.txt'))))
writer.write_line('Hello out there')
还可以动态修改一个对象的类方法...
w = SimpleWriter.new('out')
class << w
alias old_write_line write_line
def write_line(line)
old_write_line("#{Time.new}: #{line}")
end
end
或者写一个module,用extend方法动态的载入这个module
module TimeStampingWriter
def write_line(line)
super("#{Time.new}: #{line}")
end
end
class Writer
def write_line(line)
puts(line)
end
end
w = Writer.new()
w.extend(TimeStampingWriter)
w.write_line('hello')
singleton
等同于java的static,类方法,用@@变量
class SimpleLogger
@@instance = SimpleLogger.new
def self.instance
return @@instance
end
private_class_method :new
end
上面用了private方法屏蔽了singleton可能的new
factory...把类的创建推迟到子类
一个concrete factory有几个具体的create_product method
在abstract factory里面只是create_product占了个位
jungle_organism_factory = OrganismFactory.new(Tree, Tiger)
pond_organism_factory = OrganismFactory.new(WaterLily, Frog)
jungle = Habitat.new(1, 4, jungle_organism_factory)
jungle.simulate_one_day
pond = Habitat.new( 2, 4, pond_organism_factory)
pond.simulate_one_day
in ruby all class is constant const_get就是拿到那个变量:
class IOFactory
def initialize(format)
@reader_class = self.class.const_get("#{format}Reader")
@writer_class = self.class.const_get("#{format}Writer")
end
def new_reader
@reader_class.new
end
end
html_factory = IOFactory.new('HTML')
html_reader = html_factory.new_reader
builder:
builder = ComputerBuilder.new
builder.turbo
builder.add_cd(true)
builder.add_dvd
builder.add_hard_disk(100000)
...
computer = builder.computer
interpreter
...这个东西要写好太烦琐了...
dsl
class Jungle < CompositeBase
composite_of(:population)
end
这类composite_of方法的实现方法...(也就是activerecord里面众多has_one, belings_to)
def self.member_of(composite_name)
code = %Q{
attr_accessor :parent_#{composite_name}
}
class_eval(code)
end
最后书中特别提出了: convention over configuration
这东西还是看情况的,规定死了,默认的条条框框多了,自然乱七八糟的东西就少了
一言堂带来更高的生产力,民主导致低效...
民主是最不坏的,但不会是最有效的o(∩_∩)o...
--------------
chenjinlai
2008-04-28