一、简单工厂模式
定义:简单工厂模式属于创建型模式,又叫静态工厂方法模式,是由一个工厂对象根据传入的对象动态的决定创建出哪一种产品类的实例。这些产品类继承自一个父类或者接口。
优点:工厂类包含了必要的逻辑判断,根据外界传入参数创建具体类的实例。外界不必直接创建对象,仅仅消费对象即可,不必知道对象的如何创建的。明确各自的职责有利于软件体系结构的优化
缺点:工厂类包含所有实例的创建逻辑。违反单一职责,当产品的类别不断增多时,工厂类因为对外部传入条件的判断和对产品类型的判断耦合在一起工厂类会越来越臃肿。系统就很难维护和扩展。
使用场景:根据外部条件判断需要实例化不同的对象(产品较少时简单情况下应用)
实现显卡订单,根据用户的要求创建不同的显卡
传统实现:
//显卡抽象类
abstract class GraphicsCard {
public abstract void memory();
public void inteface() {
System.out.printf("安装统一标准的显卡接口");
}
}
//1060
class GXT1060 extends GraphicsCard {
@Override
public void memory() {
System.out.println("配置6G显存");
}
}
//1060
class GXT1070 extends GraphicsCard {
@Override
public void memory() {
System.out.println("配置8G显存");
}
}
//显卡订单
class GraphicsCardOrder {
public GraphicsCard gc;
public GraphicsCardOrder(String type) {
if ("1060".equals(type)) {
gc = new GXT1060();
} else if ("1070".equals(type)) {
gc = new GXT1070();
}
}
}
传统写法分析:
1、代码简单容易理解,易操作。
2、但是违反了OCP(开闭)原则,既对扩展开放、对修改关闭,当扩展功能时需要修改GraphicsCardOrder的构造方法,就可能会影响到原有的代码的功能。
3、扩展功能时代码的修改是可以接受的,但是如果我们在其他地方也有创建GraphicsCard的代码,那就需要同步的修改,往往创建GraphicsCard的位置有多处。
例如:订单增加3080TI,需要新增3080TI类,修改GraphicsCardOrder的构造方法
........
//新增3080TI
class GXT3080TI extends GraphicsCard {
@Override
public void memory() {
System.out.println("配置12G显存");
}
}
//显卡订单
class GraphicsCardOrder {
public GraphicsCard gc;
public GraphicsCardOrder(String type) {
if ("1060".equals(type)) {
gc = new GXT1060();
} else if ("1070".equals(type)) {
gc = new GXT1070();
} else if ("3080".equals(type)) {
gc = new GXT3080TI(); //支持3080
}
}
}
使用简单工厂改造实现方式
//显卡订单
class GraphicsCardOrder {
public GraphicsCard gc;
public GraphicsCardOrder(String type) {
this.gc = GraphicsCardFactory.createGraphicsCard(type);
}
}
//显卡工厂
class GraphicsCardFactory {
public static GraphicsCard createGraphicsCard(String type) {
GraphicsCard gc = null;
if ("1060".equals(type)) {
gc = new GXT1060();
} else if ("1070".equals(type)) {
gc = new GXT1070();
} else if ("3080".equals(type)) {
gc = new GXT3080TI();
}
return gc;
}
}
简单工厂实现方式分析:
1、 工厂类包含必要的逻辑判断,可以决定创建哪一个产品的实例。客户端可以免除创建产品对象的职责,很方便的创建出相应的产品。工厂和产品的职责区分明确。但是新增产品类型,必须要修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂系统扩展困难。
2、客户端无需知道所创建具体产品的类名,只需知道参数即可,在一定程度上解耦。
3、 简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高单一职责原则。
2、 系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂。所以简单工厂模式尽量在类型较少的情况下使用
二、工厂方法模式(对简单工厂的进一步抽象)
//显卡抽象类
abstract class GraphicsCard {}
//1060
class GXT1060 extends GraphicsCard {}
//1070
class GXT1070 extends GraphicsCard {}
//显卡订单
class GraphicsCardOrder {
public GraphicsCard gc;
public GraphicsCardFactory factory;
public GraphicsCardOrder(GraphicsCardFactory factory) {
this.factory = factory;
}
public GraphicsCardOrder(String type) {
this.gc = factory.createGraphicsCard(type);
}
}
//显卡工厂
interface GraphicsCardFactory {
public GraphicsCard createGraphicsCard();
}
//1060工厂
class GraphicsCard1060Factory implements GraphicsCardFactory {
@Override
public GraphicsCard createGraphicsCard() {
return new GXT1060();
}
}
//1070工厂
class GraphicsCard1070Factory implements GraphicsCardFactory {
@Override
public GraphicsCard createGraphicsCard() {
return new GXT1070();
}
}
工厂方法模式分析:
1、 使用者只需要知道具体工厂的名称就可得到所要的产品,无须传入参数指定产品。
2、 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
3、 解耦框架。高层模块不依赖底层模块的实现而是依赖其抽象,无须关心其实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。
4、 类的个数容易过多,增加复杂度。并且一个工厂只能生产一种产品。
三、抽象工厂模式(可生产多种产品)
//显卡抽象类
abstract class GraphicsCard {}
//显示器抽象类
abstract class Display {}
//华硕显卡
class HSGraphicsCard extends GraphicsCard {}
//华硕显示器
class HSDisplay extends Display {}
//影驰显卡
class YCGraphicsCard extends GraphicsCard {}
//影驰显示器
class YCDisplay extends Display {}
//显卡工厂
interface GraphicsCardFactory {
//创建显卡
public GraphicsCard createGraphicsCard();
//创建显示器
public Display createDisplay();
}
//华硕工厂
class HSFactory implements GraphicsCardFactory {
@Override
public GraphicsCard createGraphicsCard() {
return new HSGraphicsCard();
}
@Override
public Display createDisplay() {
return new HSDisplay();
}
}
//影驰工厂
class YCFactory implements GraphicsCardFactory {
@Override
public GraphicsCard createGraphicsCard() {
return new YCGraphicsCard();
}
@Override
public Display createDisplay() {
return new YCDisplay();
}
}
//订单
class Order {
public GraphicsCard gc;
public Display display;
public GraphicsCardFactory factory;
public Order(GraphicsCardFactory factory) {
this.factory = factory;
this.gc = factory.createGraphicsCard();
this.display = factory.createDisplay();
}
}
1、抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象
2、抽象工厂增强了程序的可扩展性,当增加一个新的产品族(例如:七彩虹工厂),不需要修改原代码,满足开闭原则。
四、JDK中的应用