工厂模式的优缺点
优点:
1、一个调用者想创建一个对象,只要知道其名称就可以了。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
一、简单工厂模式
抽象产品类(如汽车)
__具体实现类(继承抽象产品类)如:宝马
__具体实现类(继承抽象产品类)如:奔驰
...
工厂类
__创建产品方法(接受一个参数以确定需要哪种产品)使用switch语句根据参数创建并返回相应对象。
客户类
__创建一个工厂对象,调用创建产品方法并传入代码所需对象的参数以获取需要的对象。
简单工厂模式的弊端
在增加产品时,需要改动代码(工厂类中switch语句),不符合设计模式的开闭原则。
二、工厂方法模式
是在简单工厂模式的基础上对工厂类进行优化,提供一个工厂接口,可以通过实现工厂接口来建造属于这个产品的专属工厂,在客户类中需要某种产品时,通过创建这个产品的工厂类对象来调用创建产品的方法,来获取相应的产品对象。
工厂方法模式的弊端
如果需要多种对象时,就会需要创建许多工厂对象。
三、抽象工厂模式
在工厂方法模式中对产品类进行解耦,可以有多个抽象产品类,工厂类不再创建具体产品,而是具有多个装配此产品的配件,产品抽象类变为一个接口,可以有多个产品抽象类,具体实现类实现此接口。
具体的使用中,我们不需要可以去了解具体使用了哪种工厂模式,根据不同的使用场景来选择合适的解决方案,这几种是可以来回自由切换的,毕竟招式是死的,武功是灵活运用这些招式。
四、原型模式浅谈
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能,属于创建型模式。
使用场景:当直接创建对象的代价比较大(类初始化需要资源比较多、new一个对象比较繁琐)时使用原型模式,因为Object类的clone()是一个native方法,native方法的效率远高于Java的非native方法。
具体实现:在需要的类中实现Cloneable接口,说明此类的对象是可以被clone的,此接口没有任何方法,然后合适的覆盖clone方法(《Effictive Java》第46页第11条“谨慎的覆盖clone”),原型模式一般很少单独出现,一般与工厂模式同时使用,使用一个工厂模式维护一个或多个对象,在需要此对象的时候,返回此对象的复制品。
例子实现:
抽象类Car1
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
33package com.lizx.clone;
/**
* 车类
*
* @date 2018/1/27 09:57:08
* @auther Pyctay
*/
public abstract class Car implements Cloneable {
private int id;
private String carName;
public abstract void drive();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCarName() {
return carName;
}
public void setCarName(String carName) {
this.carName = carName;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
实现类BenZ、BMW略。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
32package com.lizx.clone;
import java.util.HashMap;
/**
* 存放车对象
*
* @date 2018/1/27 10:03:00
* @auther Pyctay
*/
public class CarCache {
private static HashMap<Integer,Car> carMap = new HashMap<Integer,Car>();
public static void loadCar(){
BenZ benZ = new BenZ();
benZ.setCarName("奔驰");
benZ.setId(1);
carMap.put(benZ.getId(),benZ);
BMW bmw = new BMW();
bmw.setCarName("宝马");
bmw.setId(2);
carMap.put(bmw.getId(),bmw);
}
public static Car getCar(int id){
Car car = null;
try {
car = (Car)carMap.get(id).clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return car;
}
}
我个人认为,在设计模式的学习中,以理解为主在理解之后就要忘记他们的构造,能够在使用中应该选择合适的解决办法,而不是强行使用设计模式,这样做不仅没有达到设计模式的初衷,甚至会拖累系统,使系统更加复杂,就像武侠中的破而后立
完整代码实现:https://github.com/pyctay/Factory.git
同时欢迎关注我的微信公众号:猿人族永不为奴。
二维码: