一、创建型模式:
1、工厂方法模式(Factory Method)--建立对象实例交给子类:
客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如:如何创建及如何向客户端提供。Factory Method Pattern在父类中规定子类的创建方法,但并没有深入到具体的类名,所的具体的完整的内容都放在子类,根据这个原则,我们大致可以分成产生实例对象大纲(框架)和产生对象实例的类两个方面。
所有参与者描述:它也分两部份,一部分是框架部分,一部分是实现部分。框加部分又分为产品框架和生产框架,产品框架用来限制产品的,这是一个抽象类。生产框架是用来限定实际的工厂类的,它采用了Template Pattern模式,也是定义了几个生产产品的抽象方法和一个对这些抽象方法进行包装的供外部程序真接调用的方法,通过这个方法,程序就可以得到相应的产品。实现部分又分为产品实现和工厂实现。产品实现就是继承产品抽象类,实现具体的产品。工厂实现就是规定制造实际产品的类,它实现了抽象方法。这样在实际的程序中就可以定义一个工厂抽象类型来引用具体的工厂对象,通过对工厂抽象类提供的生产方法就可以生产产品了。
问题:书中提到的产品子类中的构造函数没有采用了缺省的限制条件而没有用public来修饰,这有什么特殊的意义?
解答:默认情况表示构造函数只能在它的类所在的包中 使用。因为在那个例子中定义了两个包,一个是框架所在的framework,, 一个是实现所的idcard包,为了使程序严谨所以采用了默认的方式。
2、建造模式(Builder)--组合复杂的对象实例:
将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。
所有参与者描述:首先要有一个Builder抽象类来定义接口方法,它是规定了产生对象实例的接口,包括产生对象实例各个部分的方法和取得最后结果的方法。再有就是实现它的子类们,每一个子类描述的内容是不一样的,但它的标准是一样的。最后就是再用一个类利用Builder接口来专一建造实例,这个类的构造函数的参数是Builder类型的,当然传入是它的子类。这样通过这个类提供的建造方法就可以建造对象了。
相关Pattern:
Template Pattern:
在Builder Pattern有专门的类来参与控制Builder的子类,而Template Pattern则是父类控制子类。也是Builder类主要的都是抽象的方法,而Template抽象类中定义了一个实现的方法作为总的出口来输出结果。
3、抽象工厂模式(Abstract Factory):
把相关的零件组合成产品。抽象工厂就是把各种抽象零件组合成抽象产品。象模板和建造模型一样,抽象工厂也是由子类完成具体的实现,子类中就会出现具体的工厂利用具体的零件组合成具体的产品。
所有参与者描述:
1、抽象产品(可能还有抽象零件,来组成抽象产品);
2、抽象工厂;
3、具体产品;
4、具体工厂。
4、原始模型模式(Prototype)--复制建立对象实例:
用原型实例指定要创建对象的种类,并且通过拷贝这些原型创建新对象。
所有参与者描述:一个就是原型框架接口,这个接口继承了Cloneable接口,包含了一个对象复制的抽象方法,它的子类就实现了这个复制方法。再一个就是具体操作对象复制的类,它利用前面定义的原型框架接口来进行对象实例复制。利用接口比用实际的类的好处在于没有类名代表着它跟这样对象可以单独修改,用接口也是给其它类沟通的桥梁。实现复制的具体办法是它提供了一个公共方法,在这人方法中首先定义了一个接口类型用来引用具体的它的子类,然后通过这个子类对象来调用它实现的接口的中的复制方法获得复制对象,供程序其它部分调用。
5、单例模式(Singleton)--惟一的对象实例:
实现结构一般式为:
Public class Singleton {
Private static Singleton singleton = new Singleton();
Private Singleton() {
System.out.print(“已产生实例对象”);
}
Public Static Singleton getInstance() {
Return singleton;
}
}
当程序开始执行后,第一次调用getInstance方法时才会初化Singelton类,同时也初始化static字段,产生惟一的一个对象。
所有参与者描述:它只一个参与者,它提供了一个static方法来取得惟一的实例对象。
相关Pattern:
Abstract Factory Pattern,Builder Pattern,Façade Pattern,ProtoType Pattern通常也只一个实例。
问题:为什么下面的类严格的说不是Singleton Pattern呢?(提示给多线程结构有关)
Public class Singleton {
Private static Singleton singleton = null;
Private Singleton() {
System.out.print(“已产生对象实例”);
}
Public static Singleton getInstance() {
if (singleton == null ) {
Singleton = new Singleton();
}
Return singleton;
}
}
解答:当多外线程同时进入getInstance时,由于判断的条件是都为null,这时就有可能出现创建多个实例的可能。
二、结构型模式:
6、适配器模式(Adapter)--换一个包装再度利用:
在程序世界中如果既有内容无法直接利用,通常需要先转化成必要的类型再使用,具有填平“既有内容”和“需要结果”两者落差的设计模式就是Adapter Pattern。Adapter有两种:
1)、类的Adapter Pattern(继承)
2)、对象的Adapter Pattern(委拖)
二者的主要区别在于适配器类处理方式的不同,第一种是它会继承“既用内容”的类,并同时实现“需要结果”的接口,来完在功能的转化。第二种则是适配器类不继承“既用内容”类,而是在它的属性中引用了这个类,同时继承或者实现表示“需要结果”的类或接口。
所有参与者描述:首先要有既有内容的提供者的类,然后要定义Target接口,用来描述适配器的标准以满足需要的结果。而核心就是实现了Target接口的适配器类,对于类它是通过继承内容提供类并实现适配器接口的方式来实现的,对于对象它是通过实现接口并引入内容提供类的方式来实现的(委拖方式)。
相关Pattern:
桥梁模式(Bridge Pattern):
Adapter Pattern是用来连接相异接口(API)的类所使用的设计模式,而Bridge Pattern是连接功能阶段和实现阶段的Pattern。
装饰模式(Decorator Pattern):
Adapter Pattern是用来填补接口(API)间差距的Pattern,Decorator Pattern是不需要更改接口(API)即可新增功能的Pattern
7、桥梁模式(Bridge):
分成功能层次和实现层次。Bridge Pattern沟通着功能的类层次和实现的类层次。
功能的类层次:基本功能放在父类,新增功能放在子类。通过继承来扩展功能。
实现的类层次:父类使用抽象方法来规定接口,子类使用具体方法来实现此接口。这里只涉及功能的实现而不涉及功能的扩展。
二者的桥梁就是在功能类层次的父类中定义的实现类层次的接口变量。在功能类层次只定义功能部分,具体实现由传入的实现类层次中的具体实现类来完成。二者是委拖关系,也就是调用功能类层次中的功能函数实际是调用的传入的具体的实现类层次具体实现类的方法。这样在处理一边有功能扩展的要求一边有实现方法的变化时可考虑此模式。
所有参与者描述:
1、功能类层次的一个基类,它主要就是通过引入实现类层次的一个接口来搭建了一个桥梁,它采用委拖的方式来调用实现类层次接口中的方法;2、功能类层次的扩展类,它主要是继承上面的基类来扩展功能;3、实现类层次的抽象类,它主要定义了用来完成功能类层次中声明的要完成的功能的接口;4、实现类层次的实现类,它主要是继承抽象类来完成具体的功能实现。
相关Pattern:
它与Adapter Pattern很相象似,只不过Adapter是连接不同的类,而Bridge是连接功能和实现的。
8、合成模式(Composite):
对容器和内容一视同仁。象目录和文件一样,在遍历目录时可以把子目录和文件看作一类东西。对容器和内容一视同仁,建立递归结构的设计模式就是Composite Pattern。
所有参与者描述:
1、表示内容的参与者,它不能放任何东西;2、表示容器的参与者;3、对1和2一视同仁的参与者,它就是二者共享的父类。
9、装饰模式(Decorator):
10、门面模式(Facade):
11、享元模式(Flyweight):
12、代理模式(Proxy):
三、行为模式:
13、责任键模式(Chain of responsibleity):
14、命令模式(Command):
命令模式可以用一个形象的比喻来描述:如点菜:作为客户(client)是命令的创建者,服务员是命令的发起者(invoker),而菜单就是命令(command),厨师则是命令的执行者(receiver)。其实就是客户将菜单交给厨师的过程。为了解耦客户和厨师,我们有了服务员。现实中也一样,似乎看到客户直接拿着菜单去找厨师,我们有了服务员。现实中也一样,似乎没看到客户直接拿着菜单就去找厨师的。如图,这里省略了客户将Command塞给invoker的过程。
15、解释器模式(Interprete):
16、迭代模式(Iterator):
迭代子模式可以顺序访问一个聚集中的元素而不必暴露聚集的内部表象。多个对象聚在一起形成的总体称之为聚集,聚集对象是能够包容一组对象的容器对象。迭代子模式将迭代逻辑封装到一个独立的子对象中,从而与聚集本身隔开。迭代子模式简化了聚集的界面。每一个聚集对象都可以有一个或一个以上的迭代子对象,每一个迭代子的迭代状态可以是彼此独立的。迭代算法可以独立于聚集角色变化。
所有参与者描述:1、迭代器部分,它分两层,一层是接口,一层是实现。接口部分定义了访问或遍历元素用到的方法。它的实现类来负责具体的访问或遍历操作(如递增、递减等等),当然实现类要包含对具体聚集类的引用,否则它没有操作的象。2、聚合部份,它也分两层,一层是接口,一层是实现。接口部分定义了迭代器参与者者的接口,用来子类可以获得具体的迭代器。具体的聚合类实现了这个接口,想得那个具体的迭代器可以在继承的方法中实现,因为它的类型是迭代器的接口,所以任何继承迭代器接口的子类都可作为聚合的实际迭代器。
相关设计模式
Visitor Pattern(访问者模式):
Iterator Pattern 是从聚合中逐一取出元素递增上去,虽然递增这个操作是对元素进行某种处理,但Iterator接口并没有实现该处理。Visitor Pattern则是穿梭于多个元素的聚合内,不断重复同一操作。
组合模式(Composit Pattern):
Composit Pattern是一个具有递归结构的Pattern,Iterator Pattern 不适合这个部分。
工厂方法模式(Factory Method Pattern):
Iterator方法在建立Iterator对象实例时,有时会使用Factory Method Pattern。
17、调停者模式(Mediator):
18、备忘录模式(Memento):
19、观察者模式(Abserver):
通知状态变化。又称订阅发布模式。当被观察者设计模式列入观察名单的状态发生变化时,就会通知观察者。
使用场景:在写一些与状态变化有关的处理时,观察者模式是很适合的。
所有参与者描述:
1、被观察者(发布者);
2、2观察者(订阅者)。
首先为发布者定义一个抽象类,为订阅者定义一个接口,发布者抽象类聚合了订阅者接口,发布者抽象类中要实现注册订阅者、删除订阅者和通知订阅者三个功能项其它就是一些抽象的方法(一般处理状态变化,由具体的类来实现)。订阅者接口要定义一个接收通知后的处理函数,这个函数的参数一般定义为发布者抽象类型,这样订阅者接口函数就可以根据具体传入的对象来取得变化的状态。该函数由发布者的通知函数来调用。
相关Pattern:
Mediator Pattern也会通知状态变化,不过允其量也只是Mediator Pattern的一部分,而它的主要目的是还在于Colleague参与者的协调。
Observer Pattern的重点在于对Subject参与者通知Observer参与者状态变化,而且在通知后取得同步。
20、状态模式(State):
21、策略模式(Strategy):
把算法整个换掉。切换整个算法,简化采用其它办法解决同样问题。
所有参与者描述:
1、策略参与者(接口);
2、具体策略;
3、上下文参与者。
上下文参与者是一个具体的类,它聚合了策略接口,二者是委拖关系,根据上下文参与者类中的状态不断变化来选择不同的策略。它调用的是聚合的的策略的接口方法,实际执行是实际传过来的策略对象中的具体实现。策略只关注状态和算法,根据状态选择算法。
22、模板方法模式(Templete Method)--把实际处理交给子类:
作为模板的方法要定义在父类且是抽象的,实现抽象方法的是子类,理论如果不同的子类执行不同的实现,应该能发展出不同的处理结果,不过,无论执行那一个子类的实现,处理的大致流程还是要依据父类所制定的方式。像这样在父类中指定处理大纲,在子类中规定具体内容,这就是模板模式。
所有参与者描述:首先要定义一个模板抽象类,定义的抽象方法由不同的子类具体实现,但模板抽象类中要有一个对这些抽象方法包装的实际的出口方法,供程序调用。再有就是继承模板类的实现子类,它们实现了所有的抽象方法。这样在实际的程序中,我们可以定义一个模板类型的变量,用来接收具体的子类,完成具体的功能。
相关Pattern:
工厂方法(Factory Method Pattern):
将Template Method Pattern应用于产生对象实例的典型示例就是Factory Method Pattern。
策略模式(Strategy Pattern):
Template Method Pattern可以利用继承来更改程序,先父类规定程序的大纲,再在子类中规定较具体实现,相比之下,Strategy Pattern则可利用“委拖”来更改程序,不过,它不是更改部分程序,而是切换整个算法。
问题:
1)、如果把程序更为只能从父类调用Open,Print,Close方法,不能从其它无关的类调用,应如何重载?
解答:把模板类中定义的这三个方法用Protected来修饰,同时在子类中也应该是protected来修饰。
2)、接口和抽象类很类似,但是Template Method Pattern不允许在AbstractClass的参与者使用接口,为什么?
解答:因为接口是不能有任何实现方法,而模板方法模式中要有一个有具体实现的统一的出口方法(如例子中的Display()),所以用接口是实现不了的。
23、访问者模式(Visitor):