什么是设计模式
设计模式是个编程术语,它是指设计上经常反复使用的模式。
主要的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











网友评论