美文网首页
《松本行弘的程序世界》之设计模式

《松本行弘的程序世界》之设计模式

作者: Hollow_Knight | 来源:发表于2018-10-05 16:48 被阅读0次

什么是设计模式

设计模式是个编程术语,它是指设计上经常反复使用的模式。

主要的23中设计模式

模式名 内 容
Abstract Factory 可配置的方法生成有关的对象群
Adapter(适配器) 变换对象的接口
Bridge(桥接) 分离类之间的实现
Builder(生成器) 分离复杂对象的生成过程
Chain of Responsibility(职责链) 用多个对象来处理请求
Command(命令) 把请求分装成对象
Composite(组合) 用树结构来构成对象
Decorator(装饰) 给对象动态增加新的功能
Facade(外观) 隐藏子系统的详细内容,提供统一的接口
Factory Method(工厂方法) 在父类只定义生成对象的接口,具体的生成过程由派生类来实现
Flyweight(享元) 以共有的方式提高大量小对象的实现效率
Interpreter(解释器) 语言解释器
Iterator(迭代器) 提供按顺序访问一组对象的方法
Mediator(中介者) 封装对象之间的相互作用?
Memento(备忘录) 记录对象之间的相互作用
Observer(观察者) 记录对象的内部状态
Prototype(原型) 提供生成对象的原型
Proxy(代理) 提供控制对象访问的代理(容器)
Singleton(单间) 用来保证某个类的实例只有一个
State(状态) 吧对象的内部状态独立出来,封装状态变化
Strategy(策略) 封装算法,使之具有可变换性
Template Method(模板方法) 父类定义框架,派生类具体实现其中一部分
Visitor(访问者) 对集合的元素进行操作

Singleton模式

用来保证某个类的实例只有一个。
有时候我们可能全局只有一个对象,比如说在Python的框架Django中admin组件就是使用了Singleton模式在全局只操作一个对象。
我们来看看Ruby中的实现方法

class PrintSpooler
  def spool(doc)
    ...
  end
end
# 把唯一的对象赋值给一个固定的变量
# 实例化后也是一个对象
Spooler = PrintSpooler.new
Spooler.spool(document)

在编程上下点功夫来实现Singleton模式

Spooler = Object.new
  def Spooler.spool(doc)  
    ...
  end
Spooler.spool(document)

Proxy模式

为什么需要代理模式?
假设有个生成代价非常大的对象。如果在还不知道是否真正需要该对象的时候就事先生成它的话,可能会带来很大的浪费。但是如果不生成对象的话就什么事也做不了。这时候代理对象就有了用武之地。

比如说Tempfile类与实际负责文件输出的IO类没有继承关系,它的有关输入,输出处理的方法都是通过Proxy转送到实际的IO类对象。因此,通过使用Tempfile类的对象那个,在任何有必要的时候也都可以使用相关的IO对象。

# 生成Template
f = Tempfile.new('foo')
# 往Template输出
f.print("foo\n")
f.close
# 再打开
f.open
# 读取数据
p f.gets #=> "foo\n"

一般都把调用的方法传送到本来的对象那里去。

require 'delegate'
# 生成一个obj代理对象
proxy = SimpleDelegator.new(obj)
# 通过proxy来调用obj的some_method
Proxy.some_method

其中使用的是method_missing方法

class Proxy
  def initialize(orig)
    @obj = orig
  end
  
  def method_missing(name, *args)
    @obj.send(name, *args)
  end
end

proxy = Proxy.new(obj)

但是Proxy类固有的方法被调用的时候,是不会传送带method_missing方法的。delegate库使用起来虽然很简单,但方法传送的对象仅限于既有的对象。因此,如果想要达到延迟图像生成的目的,直接使用delegate是不行的可以按照如下代码实现

require 'delegate'
class ImageProxy < Delegator
  # 延迟传递所需要的数据
  def initialize(data)
    @data = data
    @image = nil
  end

  # 下面的方法用来在访问时调查传送的对象
  def __getobj__
    if @image == nil
      @image = LoadImage(@data)
    end
    @image
  end
end

相关文章

网友评论

      本文标题:《松本行弘的程序世界》之设计模式

      本文链接:https://www.haomeiwen.com/subject/onpxaftx.html