设计模式学习(2)

4、工厂模式(Factory)

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

设计模式学习(2)_第1张图片

Product(产品的抽象类)

     其中包含了产品的一些具体属性和方法;

ConcreteProduct(具体产品类)

   继承自Product,可以覆写父类的方法得到自己的一些特性;

Creator(工厂抽象类)

  一个抽象的工厂方法(factoryMethod),返回一个产品的实例;

ConcreteCreator(具体工厂类)

 实现父类的抽象方法,返回具体的产品;

总结:工厂方法将实例化推迟到了子类中,这种实现是通过继承得来的,子类继承父类实现其中的工厂方法来返回特定的产品类,这里的产品类可以是一种,也可以是很多种,而父类中只是用了产品的抽象,不需要知道子类到底会返回什么样的产品。这样就可以在抽象的父类中做一些对产品通用的操作,而工厂的子类只关心返回具体的产品。

5、单件模式(Singleton)

单件模式确保一个类只有一个实例,并提供一个全局访问点。

总结:单件模式主要说明如何创建一个单独的实例,因此只于自身有关,没有复杂的类图关系。
如何创建一个单独的实例:
(1)将类构造函数私有化;
(2)包含一个自身的静态变量;
(3)提供一个公开的静态方法以使外部可以得到类的实例;
例如:
public class Singleton {
	private static Singleton singleton;
	private Singleton() {};
	public static Singleton getInstance() {
		if(singleton == null) {
			singleton = new Singleton();
		}
		return singleton;
	}
}
使用单件模式在多线程中可能会遇到同步的问题,方法一,在getInstance()方法上加同步关键字synchronized,这种方法确定是会降低程序的性能,因为每次获得实例都要进行一次同步;方法二,提前将对象实例化,
private static Singleton singleton = new Singleton();
这种方法的缺点是可能会占用过多的系统资源;方法三,双重检查加锁,
public class Singleton {
	private volatile static Singleton singleton;
	private Singleton() {};
	public static Singleton getInstance() {
		if(singleton == null) {
			synchronized(Singleton.class) {
				if(singleton == null) {
					singleton = new Singleton();
				}
			}
		}
		return singleton;
	}
}
这种方法确保只在第一次调用getInstance()时候检查同步。

6、命令模式

命令模式将请求封装成对象,以便使用不同的请求、队列或日志来参数化其他对象。命令模式也可支持撤销的操作。
设计模式学习(2)_第2张图片

Command(命令的抽象类)

     包含一个execute()方法,执行命令的统一及接口;
ConcreteCommand(具体的命令)
     继承自Command,构造函数会传入一个执行者Receive的引用;
     在execute()方法中将通过Receiver执行具体的操作;
Receiver(执行者)
    命令的具体执行者;
Invoker(调用者)
内部有一个command的引用;
   setCommand()方法指定具体的命令;
   在接收到命令后,invoker会doSomething()执行命令的execute()方法;

总结:命令模式将发出请求的对象与执行请求的对象分离,使用一个中介(Invoker)来间接传递命令,该过程中使用统一的命令处理方式execute()而不必关心具体命令的执行细节。联系实际,就会发现餐馆点菜下单是类似的。
   举例来说,顾客到餐馆吃饭,先点菜下单,然后服务员把写好的菜单送到厨房,厨师开始做菜,这里顾客(Client),服务员(Invoker),厨师(Receiver),写好的菜单(ConcreteCommand)即与上边的类图对应。顾客实例化菜单,给了服务员相当于setCommand(),然后服务员交给厨师相当于doSomething(),在doSomething()具体做的就是喊一声“菜来咯,赶紧做”,相当于execute()了,在命令里有对厨师(Receiver)的引用,所以在execute()中做的就是厨师开始稀里哗啦action()。这里如果不使用命令模式,那么就只有顾客和厨师这两个关系,顾客要吃饭,就得先到厨房,然后告诉厨师你给我做个这个,再炒个那个,如果换了个厨师是外国的,也就是他们接受命令的接口不一样,那顾客就得用外语把需求说一遍。而命令模式就是将这些过程封装,统一做成菜单,顾客只需写个单子说句下单就可以了。
   但命令模式有一个问题就是产生的具体命令可能会很多,也就是命令类的膨胀。

7、适配器模式(Adapter)

将一个类的接口转换为客户期望的另一个接口,使原本接口不兼容的类可以协同工作。
设计模式学习(2)_第3张图片
Target(目标)
    客户期望使用的接口类;
Adapter(适配器)
    实现了接口Target;
    包含有待适配接口类的引用,在此将接口转换;

Adaptee(待适配类)

实际使用的接口类;

总结:适配器模式将一个接口类转换为另一种接口类,使得使用者可以针对相同的接口编程。

8、外观模式(Facade)

提供一个统一的接口,用来访问子系统中的一组接口,使得子系统更容易使用。
总结:外观模式与适配器不同在于他们的意图,外观模式是为了简化子系统的使用,使一组操作通过一个接口就可以完成;而适配器模式目的在于统一接口,使两个不同的接口类统一起来。


你可能感兴趣的:(设计模式学习(2))