工厂设计模式很常用,分为简单工厂,工厂方法和抽象工厂。
核心本质
- 实例化对象不使用new,用工厂方法代替
- 将选择实现类,创建对象统一管理和控制。从而将调用者跟我们实现类解耦
OOP七大原则
- 开闭原则:一个软件的实体应当对扩展开放,对修改关闭
- 依赖倒转原则:要针对接口编程,不要针对实现编程
- 迪米特法则:只与你直接的朋友通信,而避免与陌生人通信
应用场景
- JDK中Calendar的getInstance方法
- JDBC中的Connection对象的获取
- Spring中IOC容器创建管理bean对象
- 反射中Class对象的newInstance方法
三种模式
简单工厂(Simple Factory)
用来生产同一等级结构
中的任意产品(对于增加新的产品,需要扩展已有代码)
如下图需要扩展一类新车–Ford,需要扩展车工厂里面的代码
Car接口
1 2 3 4 5 6 7 8 9 10 11 12
| package com.marlowe.factory.simple;
public interface Car { public void name(); }
|
以下两个实体类实现Car接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.marlowe.factory.simple;
public class Bmw implements Car { @Override public void name() { System.out.println("我是宝马!"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.marlowe.factory.simple;
public class Tesla implements Car{ @Override public void name() { System.out.println("我是特斯拉!"); } }
|
CarFactory工厂类
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 35 36 37 38 39 40 41
| package com.marlowe.factory.simple;
public class CarFactory {
public static Car getCar(String car) { if ("宝马".equals(car)) { return new Bmw(); } else if ("特斯拉".equals(car)) { return new Tesla(); } else { return null; } }
public static Car getBmw() { return new Bmw(); }
public static Car getTesla() { return new Tesla(); } }
|
主类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.marlowe.factory.simple;
public class Comsumer { public static void main(String[] args) { System.out.println("通过方式1获取:"); Car car1 = CarFactory.getCar("宝马"); Car car2 = CarFactory.getCar("特斯拉"); car1.name(); car2.name(); System.out.println("通过方式2获取:"); Car bmw = CarFactory.getBmw(); Car tesla = CarFactory.getTesla(); bmw.name(); tesla.name(); } }
|
1 2 3 4 5 6 7
| 结果: 通过方式1获取: 我是宝马! 我是特斯拉! 通过方式2获取: 我是宝马! 我是特斯拉!
|
工厂方法(Factory Method)
用来生产同一等级结构
中的固定产品(支持增加任意产品)
如下图需要扩展一类新车–Ford,横向扩展即可
Car接口
1 2 3 4 5 6 7 8 9 10 11 12
| package com.marlowe.factory.method;
public interface Car { public void name(); }
|
以下两个实体类实现Car接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.marlowe.factory.method;
public class Bmw implements Car { @Override public void name() { System.out.println("我是宝马!"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.marlowe.factory.method;
public class Tesla implements Car { @Override public void name() { System.out.println("我是特斯拉!"); } }
|
CarFactory接口
1 2 3 4 5 6 7 8 9 10 11 12
| package com.marlowe.factory.method;
public interface CarFactory { Car getCar(); }
|
以下两个类实现CarFactory接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.marlowe.factory.method;
public class BmwFactory implements CarFactory { @Override public Car getCar() { return new Bmw(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.marlowe.factory.method;
public class TeslaFactory implements CarFactory { @Override public Car getCar() { return new Tesla(); } }
|
主类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.marlowe.factory.method;
import com.marlowe.factory.simple.CarFactory;
public class Comsumer { public static void main(String[] args) { Car car1 = new TeslaFactory().getCar(); Car car2 = new BmwFactory().getCar(); Car car3 = new FordFactory().getCar(); car1.name(); car2.name(); car3.name(); } }
|
抽象工厂(Abstract Factory)
围绕一个超级工厂创建其他工厂,该工厂又称为其他工厂的工厂
抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定它们具体的类
抽象产品工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.marlowe.factory.abstract1;
public interface IProductFactory {
IPhoneProduct iPhoneProduct();
IRouterProduct iRouterProduct(); }
|
小米工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.marlowe.factory.abstract1;
public class XiaomiFactory implements IProductFactory { @Override public IPhoneProduct iPhoneProduct() { return new XiaomiPhone(); }
@Override public IRouterProduct iRouterProduct() { return new XiaomiRouter(); } }
|
华为工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.marlowe.factory.abstract1;
public class HuaweiFactory implements IProductFactory { @Override public IPhoneProduct iPhoneProduct() { return new HuaweiPhone(); }
@Override public IRouterProduct iRouterProduct() { return new HuaweiRouter(); } }
|
手机产品接口
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
| package com.marlowe.factory.abstract1;
public interface IPhoneProduct {
void start();
void shutdown();
void call();
void sendMessage(); }
|
以下小米手机和华为手机分别实现手机产品接口
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
| package com.marlowe.factory.abstract1;
public class XiaomiPhone implements IPhoneProduct { @Override public void start() { System.out.println("打开小米手机"); }
@Override public void shutdown() { System.out.println("关闭小米手机"); }
@Override public void call() { System.out.println("小米手机打电话");
}
@Override public void sendMessage() { System.out.println("小米手机发信息");
} }
|
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
| package com.marlowe.factory.abstract1;
public class HuaweiPhone implements IPhoneProduct { @Override public void start() { System.out.println("打开华为手机"); }
@Override public void shutdown() { System.out.println("关闭华为手机"); }
@Override public void call() { System.out.println("华为手机打电话"); }
@Override public void sendMessage() { System.out.println("华为手机发信息"); } }
|
路由器产品接口
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
| package com.marlowe.factory.abstract1;
public interface IRouterProduct {
void start();
void shutdown();
void openWifi();
void setting(); }
|
以下小米路由器和华为路由器分别实现路由器产品接口
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
| package com.marlowe.factory.abstract1;
public class XiaomiRouter implements IRouterProduct { @Override public void start() { System.out.println("打开小米路由器");
}
@Override public void shutdown() { System.out.println("关闭小米路由器"); }
@Override public void openWifi() { System.out.println("打开小米路由器wifi"); }
@Override public void setting() { System.out.println("设置小米路由器"); } }
|
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
| package com.marlowe.factory.abstract1;
public class HuaweiRouter implements IRouterProduct { @Override public void start() { System.out.println("打开华为路由器");
}
@Override public void shutdown() { System.out.println("关闭华为路由器"); }
@Override public void openWifi() { System.out.println("打开华为路由器wifi"); }
@Override public void setting() { System.out.println("设置华为路由器"); } }
|
主类
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
| package com.marlowe.factory.abstract1;
public class Client { public static void main(String[] args) { System.out.println("===============小米系列产品================="); XiaomiFactory xiaomiFactory = new XiaomiFactory(); IPhoneProduct iPhoneProduct = xiaomiFactory.iPhoneProduct(); iPhoneProduct.call(); iPhoneProduct.sendMessage();
IRouterProduct iRouterProduct = xiaomiFactory.iRouterProduct(); iRouterProduct.openWifi(); System.out.println();
System.out.println("===============华为系列产品================="); HuaweiFactory huaweiFactory = new HuaweiFactory(); iPhoneProduct = huaweiFactory.iPhoneProduct(); iPhoneProduct.call(); iPhoneProduct.sendMessage();
IRouterProduct iRouterProduct1 = huaweiFactory.iRouterProduct(); iRouterProduct1.openWifi(); } }
|
1 2 3 4 5 6 7 8 9 10
| 结果: ===============小米系列产品================= 小米手机打电话 小米手机发信息 打开小米路由器wifi
===============华为系列产品================= 华为手机打电话 华为手机发信息 打开华为路由器wifi
|
适用场景:
- 客户端(应用层)不依赖与产品类实例如何被创建、实现等细节
- 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复代码
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现
优点
- 具体产品在应用层的代码隔离,无需关心创建的细节
- 将一个系列的产品统一到一起管理
缺点
- 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难
- 增加了系统的抽象性和理解难度
小结
- 简单工厂模式(静态工厂模式)
虽然某种程度上不符合设计原则,但实际使用最多!
- 工厂方法模式
不修改已有类的前提下,通过新增新的工厂类实现扩展。
- 抽象工厂模式
不可以增加产品,可以增加产品族!