设计模式学习
抽象工厂模式
场景: 把同一主题的工厂封装起来,对外提供一致的接口,返回不同的产品。 **使用:**利用接口建立一个抽象工厂,不同的工厂实现这个接口,产出的产品也要有一个接口。在使用时,需要选择具体工厂类(不能new 接口)。 **实例:**提供对不同的数据库访问的支持。IUser和IDepartment是两种不同的抽象产品,它们都有Access和SQL Server这两种不同的实现;IFactory是产生IUser和IDepartment的抽象工厂,根据具体实现(AccessFactory和SqlFactory)产生对应的具体的对象(CAccessUser与CAccessDepartment,或者CSqlUser与CSqlDepartment)。
抽象工厂模式(python)
class IUser:
def GetUser(self):
pass
class IDepartment:
def GetDepartment(self):
pass
class CAccessUser(IUser):
def GetUser(self):
print "Access GetUser"
class CAccessDepartment(IDepartment):
def GetDepartment(self):
print "Access GetDepartment"
class CSqlUser(IUser):
def GetUser(self):
print "Sql GetUser"
class CSqlDepartment(IDepartment):
def GetDepartment(self):
print "Sql GetDepartment"
class IFactory:
def CreateUser(self):
pass
def CreateDepartment(self):
pass
class AccessFactory(IFactory):
def CreateUser(self):
temp=CAccessUser()
return temp
def CreateDepartment(self):
temp = CAccessDepartment()
return temp
class SqlFactory(IFactory):
def CreateUser(self):
temp = CSqlUser()
return temp
def CreateDepartment(self):
temp = CSqlDepartment()
return temp
if __name__ == "__main__":
factory = SqlFactory()
user=factory.CreateUser()
depart=factory.CreateDepartment()
user.GetUser()
depart.GetDepartment()
工厂方法模式/简单工厂
**场景:**创建实体类比较多,抽取出来,根据条件判断要创建哪个实现类。
**使用:**根据不同的参数选择具体的实现类。
**实例:**一个程序要读取图像文件。程序支持多种图像格式,每种格式都有一个对应的ImageReader
类用来读取图像。程序每次读取图像时,需要基于文件信息创建合适类型的ImageReader
。
public class ImageReaderFactory {
public static ImageReader imageReaderFactoryMethod(InputStream is) {
ImageReader product = null;
int imageType = determineImageType(is);
switch (imageType) {
case ImageReaderFactory.GIF:
product = new GifReader(is);
case ImageReaderFactory.JPEG:
product = new JpegReader(is);
//...
}
return product;
}
}
生成器模式/建造者模式
**场景:**和抽象工厂类似,创建复杂的对象。生成器着重在一步一步的构造对象。 **使用:**一个Builder抽象类,一个实现Builder类,有多个方法来构造对象。Director是用来使用builder的。 **实例:**制造Pizza
/** "Product" */
class Pizza {
private String dough = "";
private String sauce = "";
private String topping = "";
public void setDough (String dough) { this.dough = dough; }
public void setSauce (String sauce) { this.sauce = sauce; }
public void setTopping (String topping) { this.topping = topping; }
}
''/** "Abstract Builder" */''
abstract class PizzaBuilder {
protected Pizza pizza;
public Pizza getPizza() { return pizza; }
public void createNewPizzaProduct() { pizza = new Pizza(); }
public abstract void buildDough();
public abstract void buildSauce();
public abstract void buildTopping();
}
/** "ConcreteBuilder" */
class HawaiianPizzaBuilder extends PizzaBuilder {
public void buildDough() { pizza.setDough("cross"); }
public void buildSauce() { pizza.setSauce("mild"); }
public void buildTopping() { pizza.setTopping("ham+pineapple"); }
}
/** "ConcreteBuilder" */
class SpicyPizzaBuilder extends PizzaBuilder {
public void buildDough() { pizza.setDough("pan baked"); }
public void buildSauce() { pizza.setSauce("hot"); }
public void buildTopping() { pizza.setTopping("pepperoni+salami"); }
}
''/** "Director" */''
class Waiter {
private PizzaBuilder pizzaBuilder;
public void setPizzaBuilder (PizzaBuilder pb) { pizzaBuilder = pb; }
public Pizza getPizza() { return pizzaBuilder.getPizza(); }
public void constructPizza() {
pizzaBuilder.createNewPizzaProduct();
pizzaBuilder.buildDough();
pizzaBuilder.buildSauce();
pizzaBuilder.buildTopping();
}
}
/** A customer ordering a pizza. */
class BuilderExample {
public static void main(String[] args) {
Waiter waiter = new Waiter();
PizzaBuilder hawaiian_pizzabuilder = new HawaiianPizzaBuilder();
PizzaBuilder spicy_pizzabuilder = new SpicyPizzaBuilder();
waiter.setPizzaBuilder ( hawaiian_pizzabuilder );
waiter.constructPizza();
Pizza pizza = waiter.getPizza();
}
}
惰性初始模式/惰性工厂
**场景:**延迟创建对象 **使用:**有一个map来存储创建出来的对象,如果没创建过就创建出来放到map里,否则直接返回。要注意要有锁。import java.util.*;
public class Fruit
{
private static final Map<String,Fruit> types = new HashMap<String,Fruit>();
private final String type;
// using a private constructor to force use of the factory method.
private Fruit(String type) {
this.type = type;
}
/**
* Lazy Factory method, gets the Fruit instance associated with a
* certain type. Instantiates new ones as needed.
* @param type Any string that describes a fruit type, e.g. "apple"
* @return The Fruit instance associated with that type.
*/
public static synchronized Fruit getFruit(String type) {
if(!types.containsKey(type))
types.put(type, new Fruit(type)); // Lazy initialization
return types.get(type);
}
}
对象池模式
**场景:**创建实例的时间比较长 **使用:**一开始创建多个实例保存起来,每次用完之后还回池里。
原型模式
**场景:**创建实例的成本比较高,复制实例的成本低。 使用:实现clone()这个方法,每个对象可以从自身克隆。python可以使用deepcopy()方法来拷贝。
/** Prototype Class **/
public class Cookie implements Cloneable {
public Object clone()
{
try{
//In an actual implementation of this pattern you would now attach references to
//the expensive to produce parts from the copies that are held inside the prototype.
return this.getClass().newInstance();
}
catch(InstantiationException e)
{
e.printStackTrace();
return null;
}
}
}
/** Concrete Prototypes to clone **/
public class CoconutCookie extends Cookie { }
/** Client Class**/
public class CookieMachine
{
private Cookie cookie;//cookie必须是可复制的
public CookieMachine(Cookie cookie) {
this.cookie = cookie;
}
public Cookie makeCookie() {
return (Cookie)cookie.clone();
}
public Object clone() { }
public static void main(String args[]){
Cookie tempCookie = null;
Cookie prot = new CoconutCookie();
CookieMachine cm = new CookieMachine(prot); //设置原型
for(int i=0; i<100; i++)
tempCookie = cm.makeCookie();//通过复制原型返回多个cookie
}
}
单例模式
**场景:**只需要创建一个实例,多个使用 **使用:**要注意Java 中的双重检查(Double-Check),可以使用在成员变量初始化、使用volatile变量、对方法sync python单例例子:http://blog.csdn.net/ghostfromheaven/article/details/7671853,python的模块(module)本身是单例的
public class Singleton {
private static volatile Singleton INSTANCE = null;
// Private constructor suppresses
// default public constructor
private Singleton() {}
//thread safe and performance promote
public static Singleton getInstance() {
if(INSTANCE == null){
synchronized(Singleton.class){
//when more than two threads run into the first null check same time, to avoid instanced more than one time, it needs to be checked again.
if(INSTANCE == null){
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
适配器模式
**场景:**和客户需要的接口有差异 **使用:**构建一个Adapter实现客户需要的接口,把对应的方法映射到自己的类上(Adaptee)
class Target:
def Request():
print "common request."
class Adaptee(Target):
def SpecificRequest(self):
print "specific request."
class Adapter(Target):
def __init__(self,ada):
self.adaptee = ada
def Request(self):
self.adaptee.SpecificRequest()
if __name__ == "__main__":
adaptee = Adaptee()
adapter = Adapter(adaptee)
adapter.Request()
桥接模式 /Bridge
**场景:**把抽象(abstraction)和实现(implementor)分离,两者可以独立变化 **使用:**Refined Abstraction是为了调用具体实现类 **实例:**不同的汽车有不同的引擎 参考代码见这里:http://blog.csdn.net/shaopeng5211/article/details/8827507
组合模式
**场景:**把多个对象组成树状结构来表示局部与整体,这样用户可以一样的对待单个对象和对象的组合。 **实例:**公司人员结构
组合模式
class Component:
def __init__(self,strName):
self.m_strName = strName
def Add(self,com):
pass
def Display(self,nDepth):
pass
class Leaf(Component):
def Add(self,com):
print "leaf can't add"
def Display(self,nDepth):
strtemp = ""
for i in range(nDepth):
strtemp=strtemp+"-"
strtemp=strtemp+self.m_strName
print strtemp
class Composite(Component):
def __init__(self,strName):
self.m_strName = strName
self.c = []
def Add(self,com):
self.c.append(com)
def Display(self,nDepth):
strtemp=""
for i in range(nDepth):
strtemp=strtemp+"-"
strtemp=strtemp+self.m_strName
print strtemp
for com in self.c:
com.Display(nDepth+2)
if __name__ == "__main__":
p = Composite("Wong")
p.Add(Leaf("Lee"))
p.Add(Leaf("Zhao"))
p1 = Composite("Wu")
p1.Add(Leaf("San"))
p.Add(p1)
p.Display(1);
装饰模式/Decorator
装饰( Decorator )模式又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。 **场景:**对类扩展方法 代码:http://blog.csdn.net/shaopeng5211/article/details/8803120
外观模式/Facadec
**场景:**为client提供简单的方法,调用具体的多个实现类 代码:http://blog.csdn.net/shaopeng5211/article/details/8813135
享元模式/Flyweight
采用一个共享来避免大量拥有相同内容对象的开销。这种开销中最常见、直观的就是内存的损耗。享元模式以共享的方式高效的支持大量的细粒度对象。 ** **
代理模式/Proxy
所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。 需要与继承区分,继承是静态的增加方法,代理可以实现一些纵切的功能。
职责链模式/Chain of Responsibility
该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的对象之间像链条一样紧密相连,所以被称作职责链模式。 **场景:**如一件事需要多个部门处理,这个部门处理完交给下个部门。 **使用:**每个对象设定下一个处理的对象是什么,并且在handle方法里调用下一个处理的方法。 **代码:**命令物件可以把行动(action) 及其参数封装起来,可以重复执行、取消。
Command Command抽象类。
ConcreteCommand Command的具体实现类。
Receiver 需要被调用的目标对象。
Invorker 通过Invorker执行Command对象。
import java.util.List;
import java.util.ArrayList;
/* The Command interface */
public interface Command {
void execute();
}
/* The Invoker class */
public class Switch {
private List<Command> history = new ArrayList<Command>();
public Switch() {
}
public void storeAndExecute(Command cmd) {
this.history.add(cmd); // optional
cmd.execute();
}
}
/* The Receiver class */
public class Light {
public Light() {
}
public void turnOn() {
System.out.println("The light is on");
}
public void turnOff() {
System.out.println("The light is off");
}
}
/* The Command for turning on the light - ConcreteCommand #1 */
public class FlipUpCommand implements Command {
private Light theLight;
public FlipUpCommand(Light light) {
this.theLight = light;
}
public void execute(){
theLight.turnOn();
}
}
/* The Command for turning off the light - ConcreteCommand #2 */
public class FlipDownCommand implements Command {
private Light theLight;
public FlipDownCommand(Light light) {
this.theLight = light;
}
public void execute() {
theLight.turnOff();
}
}
/* The test class or client */
public class PressSwitch {
public static void main(String[] args){
Light lamp = new Light();
Command switchUp = new FlipUpCommand(lamp);
Command switchDown = new FlipDownCommand(lamp);
Switch mySwitch = new Switch();
try {
if ("ON".equalsIgnoreCase(args[0])) {
mySwitch.storeAndExecute(switchUp);
}
else if ("OFF".equalsIgnoreCase(args[0])) {
mySwitch.storeAndExecute(switchDown);
}
else {
System.out.println("Argument \"ON\" or \"OFF\" is required.");
}
} catch (Exception e) {
System.out.println("Arguments required.");
}
}
}
解释器模式/Interpreter
它建立一个解释器,对于特定的计算机程序设计语言,用来解释预先定义的文法。简单地说,Interpreter模式是一种简单的语法解释器构架。
Context 解释器上下文环境类。用来存储解释器的上下文环境,比如需要解释的文法等。
AbstractExpression 解释器抽象类。
ConcreteExpression 解释器具体实现类
代码:http://blog.csdn.net/shaopeng5211/article/details/8847991
迭代器
提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
中介者模式
**场景:**有多个类需要交互,由中介来调用他们。但中介者会变得复杂。 http://haolloyin.blog.51cto.com/1177454/333810
备忘录模式
用另一个结构一样的类把变量存储起来。。o(╯□╰)o,可以在某个时间还原。 http://blog.csdn.net/shaopeng5211/article/details/8879519
观察者模式
**场景:**一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。 **使用:**Subject提供注册、删除、通知的方法,Observer注册到Subject,Subject状态变化时,就会通知所有注册的Observer。 代码:http://zh.wikipedia.org/wiki/观察者模式
状态模式
State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样。 **使用:**Context维护一个state变量,并且使用这个state的方法。但state变更时,方法自然也变了。
策略模式
策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。 **使用:**新建不同的策略让Context调用,需要与状态模式区分,状态模式的迁移对客户是透明的。
模板模式
模板方法模式定义了一个算法的步骤,并允许次类别为一个或多个步骤提供其实践方式。 http://zh.wikipedia.org/wiki/模板模式
访问者模式
把对象和算法分开,通过使用回调的方式。对象实现accept方法,传入vistor调用它的方法。 http://zh.wikipedia.org/wiki/访问者模式
参考
http://www.cnblogs.com/wuyuegb2312/archive/2013/04/09/3008320.html http://blog.csdn.net/shaopeng5211/ http://zh.wikipedia.org/zh-cn/设计模式_(计算机)