浏览 2918 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-07-31
下面是ruby版本的strategy模式体现,参考Head first design 设计模式中文版本第一章策略模式.由于ruby相对于java的不同,没有了接口的概念,也没有抽象类的概念,但是我闷可以变相的实现抽象和接口的应用,在ruby中 # #鸭子抽象类 class Duck attr_accessor :fly_behavior, :quack_behavior def display raise "this is a abstract method" end def perform_fly if fly_behavior.is_a?(FlyBehavior) fly_behavior.fly end end def perform_quack if quack_behavior.kind_of?(QuackBehavior) quack_behavior.quack end end end # #具体鸭子类 class MallarDuck < Duck def initialize @fly_behavior = FlyWithWings.new @quack_behavior = Quack.new end def display puts "I'm a real Mallard duck" end end # #具体鸭子类 class ModelDuck < Duck def initialize @fly_behavior = FlyNoWay.new @quack_behavior = Quack.new end def display puts "I'm a real Model duck" end end # #抽象类,具体方法让子类去实现 class FlyBehavior def fly raise "Abstract method call" end end class QuackBehavior def quack raise "Abstract method call" end end # #实现抽象类行为的子类 class FlyWithWings < FlyBehavior def fly puts "I'm flying!!!" end end class FlyNoWay < FlyBehavior def fly puts "I can't fly!!" end end class FlyRocketPowered < FlyBehavior def fly puts "I'm flying with a rocket" end end class Quack < QuackBehavior def quack puts "Quack!!!" end end # #测试方法 require 'benchmark' puts "strategry pattern start!!!" mallard = MallarDuck.new mallard.display mallard.perform_fly mallard.perform_quack modeld = ModelDuck.new modeld.display modeld.perform_fly modeld.fly_behavior = FlyRocketPowered.new modeld.perform_fly 输出--------------------- strategry pattern start!!! I'm a real Mallard duck I'm flying!!! Quack!!! I'm a real Model duck I can't fly!! I'm flying with a rocket 多多交流谢谢! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-07-31
另外一个例子,设计到排序算法[系转载]
# # The GoF Strategy pattern # written by Matthieu Tanguay-Carel # # Sorter is the Context object. It allows to choose between sorting # implementations. # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # class QuickSort def sort arr return [] if arr.length == 0 x, *xs = *arr smaller, bigger = xs.partition{ |other| other < x } sort(smaller) + [x] + sort(bigger) end end class MergeSort def sort array if array.length <= 1 return array end middle = array.length / 2 left = array[0...middle] right = array[middle...array.length] left = sort left right = sort right return merge(left,right) end def merge left,right result = [] while left.length > 0 and right.length > 0 left.first <= right.first ? result << left.shift : result << right.shift end result.push(*left) if left.length > 0 result.push(*right) if right.length > 0 return result end end class Sorter @@default_strategy = QuickSort.new def self.sort arr, strategy=nil strategy ||= @@default_strategy strategy.sort(arr) end end def print_elems arr arr.each {|elem| $stdout.write "#{elem} "} puts '' end def get_random_array size arr = [] size.times do arr << rand(100) end arr end require 'benchmark' #if __FILE__ == $0 arr_length = 1000 arr1 = get_random_array arr_length puts "Sorting first array" #print_elems arr1 puts "Time taken for QuickSort: #{Benchmark.measure { arr1 = Sorter.sort(arr1, QuickSort.new) print_elems arr1[0...40] }}" puts "\nSorting second array" arr2 = get_random_array arr_length #print_elems arr2 puts "Time taken for MergeSort: #{Benchmark.measure { arr2 = Sorter.sort(arr2, MergeSort.new) print_elems arr2[0...40] }}" #end |
|
返回顶楼 | |
发表时间:2008-07-31
我用了近1年的ruby,可能是由于没有开发过所谓的“大系统”,我发现:
很少会用设计模式。 我会经常用ruby的闭包,mix-in特性来解耦。 还有一些内小的class,最多200行。 |
|
返回顶楼 | |
发表时间:2008-07-31
dazuiba 写道 我用了近1年的ruby,可能是由于没有开发过所谓的“大系统”,我发现:
很少会用设计模式。 实际上很多“经典的”面向对象设计模式之所以存在只是为了克服C++/JAVA/C#的一切固有的设计缺陷想出来的workaround 照搬到Ruby里面就是脱了裤子放屁 比如说楼主的这个鸭子的例子…哎,还不要说Ruby了,哪怕你是用Java,我怎么就看不出来MallarDuck和ModelDuck这两个子类存在的价值是什么呢?行为的差异已经抽到strategies里面去了,就为了表达两个字符串的差异就创建出两个子类,我怎么就不理解这个设计到底优雅在哪儿呢? 至于这个sort的例子,sigh,真的,只能说惨不忍睹啊 (很多时候我想对一些年轻程序员说,你们别再看什么设计模式了。你们用用脑子,睁开眼睛,去看看系统里哪些东西在变化,哪些东西保持不变,哪些地方有重复代码,哪些设计是脱了裤子放屁。) |
|
返回顶楼 | |
发表时间:2008-07-31
100行ruby代码能干不少事呢,在提倡节约型社会的年代,楼主显得太浪费了。
非要弄那么多类,居然还要有抽象类,太过份了。方法级别的组合加上duck typing原则就够了,第一个例子玩花样可以用用forwardable/delegate,或者花几行代码搞个DSL。 |
|
返回顶楼 | |
发表时间:2008-07-31
我看这个帖子标题后就在想,好像怎么想也想不出来ruby里面用这个设计模式该怎么玩,有没有必要玩,然后看完帖子之后,才发现,确实是“脱裤子放屁--多此一举”,呵呵
|
|
返回顶楼 | |
发表时间:2008-07-31
这个,lz,没有打击你的意思,我没想到有什么好处啊……
为什么我觉得这纯粹是用java的方法来写ruby应用呢? |
|
返回顶楼 | |
发表时间:2008-08-01
只能说,你了解了 Java 中 Strategy 的目的,但是有必要在 Ruby 中再现这种模式么?感觉很迂腐,为了设计而设计。
做开发始终要记住,设计是为了达到某个目的。既然 Ruby 提供如此多的特性,根本就不需要这么多的模式。Duck Typing,Mix-In,等等,都比照抄 Java 的设计模式强得多。用所谓的设计模式把事情复杂化,就是和自己过不去。 |
|
返回顶楼 | |
发表时间:2009-06-04
你还不了解ruby,不要把他当java用。
|
|
返回顶楼 | |