单例模式
Ensure a class has only one instance, and provide a global point of access to it.
单例模式没什么好说的,因为只有一个实例,可以节省内存、节省创建对象的耗时。。等等等等等。。。。。。。。。。
enum Singleton{
INSTANCE;
public static Singleton getInstance(){
return INSTANCE;
}
}
原型模式
Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
原型模式该叫克隆模式or复制模式。。。。就是把原始对象复制一份。
import java.util.ArrayList;
import java.util.List;
public class PrototypeClass implements Cloneable{
private List list = new ArrayList();
public void doSomething(){
System.out.println("do something...");
}
public PrototypeClass clone(){
PrototypeClass p = null;
try{
p = (PrototypeClass)super.clone();
p.list = (List)((ArrayList)list).clone();
}catch(Exception e){
System.out.println("fail to clone");
}
return p;
}
}
注意点:
- cloneable只是一个标识,表示这个对象可以复制
- clone()方法是属于Object的,不是cloneable接口的
- 拷贝的时候通过二进制码直接复制的,而不是调用构造函数的,如果构造函数的调用代价很大,拷贝就很合算的。
- 注意浅拷贝的问题
原型模式可以用在备忘录模式中,所谓备忘录模式就是在更改自己状态前要保存下以方便恢复原始状态。
public class A implements Cloneable{
private String state;
private A backup;
public void saveState(){
backup = clone();
}
public A clone(){
A a = null;
try{
a = (A)super.clone();
}catch(Exception e){
System.out.println("fail to clone");
}
return a;
}
public void doSomething(){
System.out.println("do something..");
}
}
工厂方法模式
Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.
工厂方法的实质就是通过一个类来封装new对象的过程,由于经过了类的封装,它可以控制对象的产生过程:比如可以用hashMap装入一定数量的对象,然后每次申请对象的时候将已经有的对象送给高层控制新创建对象的数量(享元模式);比如可以在这个类中可以只有一个实例,每次高层模块请求对象的时候返回这个唯一的实例(单例模式)。
但如果不进行这种额外的创建操作,直接函数内部进行new对象然后返回,实在不知道工厂方法模式的优点在哪里。书中的例子通过class<T>参数返回实现同一接口的不同实例,但这个和new运算符生成不同对象好像也没什么区别。都是具体显示知道我要生成的是什么类型的对象。
public interface Human {
public void doSomething();
}
public abstract class AbstractHumanFactory{
public abstract <T extends Human> T createHuman(Class<T> c);
}
/*
* 任何实现了Human接口都可以通过工厂生成对象
* 但高层模块调用的时候还是要既知道工厂又知道对象
* */
public class HumanFactory extends AbstractHumanFactory{
public <T extends Human> T createHuman(Class<T> c){
Human h = null;
try{
h = (Human)Class.forName(c.getName()).newInstance();
}catch(Exception e){
System.out.println("fail to create");
}
return (T)h;
}
}
//类似的更简单的,但实在看不出有什么好处
//工厂没有接口or抽象类叫做简单工厂
public class HumanFactory{
return new Human(){
public void doSomething(){
System.out.println("do something...");
}
};
}
抽象工厂模式
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
抽象工厂和和工厂方法不同的是抽象工厂有产品族的概念,可以说是工厂方法的升级版,它的内部不会像工厂只生产一个对象,而是产生一组产品,比如书上的左车门和右车门,一个抽象工厂内肯定可以同时生产这两个。但具体一个左车门对应一个右车门还是两个,也就是具体的产品族的比例不归工厂管,放在调用工厂的高层模块中。
public interface AbstractProductA {
public void doSomethingA();
}
public interface AbstractProductB {
public void doSomethingB();
}
public interface AbstractCreator{
public AbstractProductA createA();
public AbstractProductB createB();
}
public class Creator1 implements AbstractCreator{
public AbstractProductA createA() {
return new AbstractProductA(){
public void doSomethingA() {
System.out.println("do Something A");
}
};
}
public AbstractProductB createB() {
return new AbstractProductB(){
public void doSomethingB() {
System.out.println("do Something B");
}
};
}
}
建造者模式
Separate the construction of a complex object from its representation so that the same construction process can create different representations.
建造者模式可以看成抽象工厂的升级版,不同的是抽象工厂表示的是产品之间的比例在高层模块组装,而建造者模式先通过产品的碎片然后按照需要的比例通过类组装,组装过程也在本层模块,返回给高层模块的是组装好的整个对象。
建造者模式中的Builder和Director对象总觉得有点角色重合,完全可以在导演类中将原始对象组合好然后返回的。
public interface AbstractProduct{
public void part1();
public void part2();
public void doSomething();
}
public class Product implements AbstractProduct{
public void part1() {}
public void part2() {}
public void doSomething() {}
}
public interface AbstractBuilder{
public void setPart();
public AbstractProduct getInstance();
}
public class Builder implements AbstractBuilder{
private AbstractProduct ap = new Product();
public void setPart(){
ap.part1();
ap.part2();
}
public AbstractProduct getInstance(){
return ap;
}
}
public class Director{
AbstractBuilder b = new Builder();
public void setPart(){
b.setPart();
}
public AbstractProduct getInstance(){
return b.getInstance();
}
}