【设计模式:一】简单工厂
1 背景
设计模式中应该遵循的原则:
五大原则:
- 单一职责原则(SRP):就一个类而言,应该仅有一个引起它变化的原因。即一个类中应该只有一类逻辑。
- 开放-封闭原则(OCP):软件实体(类、模块、函数等等)应该可以扩展,但是不可修改。即开放扩展,封闭修改。
- 依赖倒转原则(DIP):高层模块不应该依赖底层模块。两个都应该依赖抽象;抽象不应该依赖细节。细节应该依赖抽象。即面向接口编程,而不是面向实现编程。
- 里氏代换原则(LSP):子类型必须能够替换掉他们的父类型。
- 合成/聚合复用原则(CARP):尽量使用合成/聚合,尽量不要使用类继承。
迪米特法则:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一方法的话,可以通过第三者转发这个调用。
在Java面向接口编程的思想中,通常用接口来定义行为,由实现类来定义具体实现。接口是实现类对外的外观,通过接口,可以实现不相关类的相同行为。
接口的思想是封装隔离:封装的是行为;隔离的是外部调用和内部实现。外部调用不必关心内部是如何实现的,只需要明白该接口实现了什么样的功能。
简单工厂严格上不属于标准的二十三种设计模式中的任何一种,但其应用广泛,可以看作是工厂方法模式和抽象工厂模式的简化版。
简单工厂的思想是:提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以实接口、抽象类,也可以是具体的类。
2 实现
我现在有一个Vehicle接口,里面定义了run方法。它有两个实现类Train和Subway。
public interface Vehicle {
void run();
}
public class Train implements Vehicle {
@Override
public void run() {
System.out.println("火车run");
}
}
public class Subway implements Vehicle {
@Override
public void run() {
System.out.println("地铁run");
}
}
在外部实例化两个实现类,并调用run方法。
public class Main {
public static void main(String[] args) {
//创建火车
Vehicle train = new Train();
train.run();
//创建地铁
Vehicle subway = new Subway();
subway.run();
}
}
显然,这种客户端调用的方式违背了单一责任原则和迪米特法则。
引入简单工厂。
public class VehicleFactory {
public static Vehicle createVehicle(String s) {
Vehicle res = null;
switch (s) {
case "train":
res = new Train();
break;
case "subway":
res = new Subway();
break;
default:
throw new IllegalArgumentException("参数错误");
}
return res;
}
}
public class Main {
public static void main(String[] args) {
//创建火车
Vehicle train = VehicleFactory.createVehicle("train");
train.run();
//创建地铁
Vehicle subway = VehicleFactory.createVehicle("subway");
subway.run();
}
}
引入简单工厂后遵循迪米特法则。
3 小结
由于是通过静态方法获取实现类,所以简单工厂由叫做静态工厂。
在实际开发中,可以利用枚举,将该静态方法获取实现类的过程交给IoC容器,这样避免新增实现类时修改原方法代码。
简单工厂降低了客户端与具体实现类之间的耦合度,通过简单的封装即可实现面向接口编程。但是,由于使用了静态方法,需要事先定义好参数的含义,这增加了客户端使用难度,部分暴露了内部实现。并且不方便扩展子工厂。
简单工厂的本质是:选择实现。
简单工厂与工厂方法和抽象方法的区别:
工厂方法模式,是将选择具体实现的功能延迟到子类实现,如果将其交给父类实现,就等同于简单工厂。
抽象方法模式,如果顶级工厂接口只有一个实现的话,就相当于退化成了简单工厂。
所以可以把简单工厂看作最基本的工厂模式,有两条演变方向,一个是工厂方法模式,一个是抽象方法模式。
参考《研磨设计模式》
引用博客-月光中的污点-Java 设计模式之工厂模式(二)