设计模式之创建型

设计模式分类

  1. 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
  2. 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
  3. 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

设计模式的六大原则

1、开闭原则(Open Close Principle)
2、里氏代换原则(Liskov Substitution Principle)
3、依赖倒转原则(Dependence Inversion Principle)
4、接口隔离原则(Interface Segregation Principle)
5、迪米特法则(最少知道原则)(Demeter Principle)
6、合成复用原则(Composite Reuse Principle)

创建型模式

1.单例模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//饿汉 传递activity的context,可能造成内存泄漏
public class Factory {
private static Factory f = null;
private Factory() {
System.out.println("instance");
}
}
public static synchronized Factory getInstance() {
if(f ==null) {
f = new Factory();
}
return f;
}
}

1
2
3
4
5
6
7
8
9
10
11
//饱汉
public class Factory {
private static Factory f = new Factory();
private Factory() {
System.out.println("instance");
}
}
public static Factory getInstance() {
return f;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//多线程下使用 可能失效
public class Factory {
private static Factory f = null;
private Factory() {
System.out.println("instance");
}
public static Factory getInstance() {
if(f ==null) {
synchronized (Factory.class){
if(f == null) {
f = new Factory();
}
}
}
return f;
}
}
1
2
3
4
5
6
7
8
9
10
//静态内部类 保证唯一性,线程安全,延迟实例化 推荐使用
class OkHttp{
public static OkHttp newInstance(){
return OkHttpHolder.OKHTTP_INSTANCE;
}
private static class OkHttpHolder{
private static final OkHttp OKHTTP_INSTANCE = new OkHttp();
}
}

2.工厂方法模式
定义接口

1
2
3
public interface BMWCar{
public void getCar();
}

实现类

1
2
3
4
5
6
7
8
9
10
public class BMWz3 implements BMWCar{
public void getCar(){
System.out.println("this is BMz3");
}
}
public class BMWz4 implements BMWCar{
public void getCar(){
System.out.println("this is BMz4");
}
}

创建工厂类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
A.普通工厂模式
public class BMWFactory1{
public BMWCar produce(String type) {
if ("z3".equals(type)) {
return new BMWz3();
} else if ("z4".equals(type)) {
return new BMWz4();
} else {
System.out.println("请输入正确的类型!");
return null;
}
}
}
B.多个工厂方法模式
public class BMWFactory2{
public BMWCar producez3(){
return new BMWz3();
}
public BMWCar producez4(){
return new BMWz4();
}
}
C.静态工厂方法模式
public class BMWFactory3 {
public static BMWCar producez3(){
return new BMWz3();
}
public static BMWCar producez4(){
return new BMWz4();
}
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args){
BMWFactory1 factory1 = new BMWFactory1();
BMWFactory2 factory2 = new BMWFactory2();
//A
BMWz3 myz3a = factory1.produce("z3");
BMWz4 myz4a = factory1.produce("z4");
//B
BMWz3 myz3b = factory2.producez3();
BMWz4 myz4b = factory2.producez3();
//C
BMWz3 myz3c = BMWFactory3.producez3();
BMWz4 myz4c = BMWFactory3.producez3();
}

3.抽象工厂模式
创建工厂类与2不同

创建工厂接口

1
2
3
public interface Factory {
public BMWCar produceCar();
}

1
2
3
4
5
6
7
8
9
10
11
public class BMWFactoryz3 implements Factory{
public BMWCar produceCar(){
return new BMWz3();
}
}
public class BMWFactoryz4 implements Factory{
public BMWCar produceCar(){
return new BMWz4();
}
}

4.建造者模式(Builder)
工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Builder {
private List<BMWCar> list = new ArrayList<BMWCar>();
public void produceBMWCarz3(int count){
for(int i=0; i<count; i++){
list.add(new BMWz3());
}
}
public void produceBMWCarz4(int count){
for(int i=0; i<count; i++){
list.add(new BMWz4());
}
}
}

5.原型模式(Prototype)
将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。实现Cloneable接口,写clone方法即可
浅复制:将一个对象复制后,基本数据类型的变量重新创建,而引用类型,指向的还是原对象所指向的
深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的

1
2
3
4
5
6
7
8
//浅复制
public class Prototype implements Cloneable {
public Object clone() throws CloneNotSupportedException {
Prototype proto = (Prototype) super.clone();
return proto;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//深复制
public class Prototype implements Cloneable {
public Object deepClone() throws IOException, ClassNotFoundException {
/* 写入当前对象的二进制流 */
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
/* 读出二进制流产生的新对象 */
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
}