ruby设计模式(大话设计模式)

1、简单工厂模式
2、策略模式
3、单一职责原则
4、开放-封闭原则
5、依赖倒转原则
8、工厂方法模式

1、简单工厂模式
降低耦合度的方式包括封装、继承和多态。下面介绍各个的抽象解释

封装:通过实现一个类
继承:子类继承父类
多态:同一个方法实现不同的功能

简单工厂模式是指用一个单独的类来实现创造实例的过程。下面是一个计算器的实现。代码如下所示,在下面的代码中,通过OperationFactory类来实现对象创造的过程,如果要增加一个计算方法,只要增加一个Operation的子类,以及增加相应的case表达式。

#运算类
class Operation
  attr_accessor :number_a,:number_b

  def initialize(number_a = nil, number_b = nil)
    @number_a = number_a
    @number_b = number_b
  end

  def result
  end
end

#加法类
class OperationAdd < Operation
  def result
    number_a + number_b
  end
end

#减法类
class OperationSub < Operation
  def result
    number_a - number_b
  end
end

#乘法类
class OperationMul < Operation
  def result
    number_a * number_b
  end
end

#除法类
class OperationDiv < Operation
  def result
    raise '除数不能为0' if number_b == 0
    number_a / number_b
  end
end

#工厂类
class OperationFactory
  def self.create_operate(operate)
    case operate
    when '+'
      OperationAdd.new()
    when '-'
      OperationSub.new()
    when '*'
      OperationMul.new()
    when '/'
      OperationDiv.new()
    end
  end
end

oper = OperationFactory.create_operate('/')
oper.number_a = 1
oper.number_b = 1
p oper.result

2、策略模式
是用来封装算法的。选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象,比如下面的例子中的CashContent的对象,下面的代码是工厂模式和策略模式的结合使用。

class CashSuper
  def accept_cash(money)
  end
end

#正常收费子类
class CashNormal < CashSuper
  def accept_cash(money)
    money
  end
end

#打折收费子类
class CashRebate < CashSuper
  attr_accessor :mony_rebate

  def initialize(mony_rebate)
    @mony_rebate = mony_rebate
  end

  def accept_cash(money)
    money * mony_rebate
  end
end

#返利收费子类
class CashReturn < CashSuper
  attr_accessor :mony_condition, :mony_return

  def initialize(mony_condition, mony_return)
    @mony_condition = mony_condition
    @mony_return = mony_return
  end

  def accept_cash(money)
    if money > mony_condition
      money - (money/mony_condition) * mony_return
    end
  end
end

class CashContext

  attr_accessor :cs

  def initialize(type)
    case type
    when '正常收费'
      @cs = CashNormal.new()
    when '打8折'
      @cs = CashRebate.new(0.8)
    when '满三百减100'
      @cs = CashReturn.new(300,100)
    end
  end

  def result(money)
    cs.accept_cash(money)
  end
end

dd=CashContext.new('打8折')
puts dd.result(700)

在上面的代码中result方法中的cs方法返回的是CashRebate对象,下面的代码可以说明问题:

class Demo
  attr_accessor :one

  def initialize(one)
    @one = Example.new
  end
end

class Example
end
obj = Demo.new("hh")
puts obj.one.class

3、单一职责原则
一个类对应一个职责,如果这个类有多余一个职责,则需要建立另外一个类。

4、开放-封闭原则
对扩展开放,对修改封闭。比如工厂模式中要增加加法这个功能,在没有使用工厂模式的情况下,可以为Operation增加这个方法,这破坏的对修改封闭原则,所以这里采用的方法是增加一个加法类,并且继承自Operation,体现了对扩展开放原则。

5、依赖倒转原则
依赖倒转原则
1,高层模块不应该依赖低层模块,两个都应该依赖抽象。
2,抽象不应该依赖细节,细节应该依赖抽象。针对接口编程,不应该针对实现编程。
里氏代换原则
子类型必须能够替换掉他们的父类型。

8、工厂方法模式
简单工厂模式的缺点:增加功能的时候,就需要增加case的条件分支,也就是要修改工厂类,违背了“开放-封闭原则”。下面介绍工厂方法模式:

#运算类
class Operation
  attr_accessor :number_a,:number_b
    
  def initialize(number_a = nil, number_b = nil)
    @number_a = number_a
    @number_b = number_b
  end
    
  def result
  end
end

#加法类
class OperationAdd < Operation
  def result
    number_a + number_b
  end
end

#减法类
class OperationSub < Operation
  def result
    number_a - number_b
  end
end

#乘法类
class OperationMul < Operation
  def result
    number_a * number_b
  end
end

#除法类
class OperationDiv < Operation
  def result
    raise '除数不能为0' if number_b == 0    
    number_a / number_b
  end
end


module FactoryModule
  def create_operation
  end
end
#加法工厂
class AddFactory
  include FactoryModule
    
  def create_operation
    OperationAdd.new
  end    
end

#减法工厂
class SubFactory
  include FactoryModule
    
  def create_operation
    OperationSub.new
  end
end
#乘法工厂
class MulFactory
  include FactoryModule
    
  def create_operation
    OperationMul.new
  end    
end
#除法工厂
class DivFactory
  include FactoryModule
    
  def create_operation
    OperationDiv.new
  end    
end

factory = AddFactory.new
oper = factory.create_operation
oper.number_a = 1
oper.number_b = 2
p oper.result

相比于简单工厂模式,这里的变化是移除了工厂类,取而代之的是具体的运算工厂,分别是加法工厂、减法工厂、乘法工厂和除法工厂。
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法是一个类的实例化延迟到了子类。
这么做的好处是,克服了简单工厂违背“开放-封闭原则”的缺点,又保持了封装对象创建过程的优点。存在的问题是逻辑分支的判断依然需要实现,只不过是从工厂类中转移到了客户端,利用反射?可以解决分支判断的问题。

你可能感兴趣的:(ruby设计模式(大话设计模式))