工厂模式[Factory Design Pattern]:一般情况下分为三种更加细分的类型:简单工厂、工厂方法和抽象工厂方法。但在 GoF 《设计模式》一书中,将简单工厂模式看作是工厂模式的一种特例。
简单工厂方法
定义
有一个工厂对象决定创建出哪一种产品类的实例(实现对象的创建),又叫静态工厂方法模式,顾名思义,使用 static 修饰。
实现
public interface IProduct {
public void method();
}
public class ProductA implements IProduct{
public void method() {
System.out.println("产品A方法");
}
}
public class ProductB implements IProduct{
public void method() {
System.out.println("产品B方法");
}
}
public class Creator {
private Creator(){}
public static IProduct createProduct(String productName){
if (productName == null) {
return null;
}
if (productName.equals("A")) {
return new ProductA();
}else if (productName.equals("B")) {
return new ProductB();
}else {
return null;
}
}
}
public class Client {
public static void main(String[] args) {
// new ProductA(); 原始创建对象
//工厂方法:创建对象,使得类的职责更加单一,代码更加清晰
IProduct product1 = Creator.createProduct("A");
product1.method();
IProduct product2 = Creator.createProduct("B");
product2.method();
}
}
缺点
上面我们虽然只写了两个 if 循环,但是如果有很多的时候,违背了开闭原则。
工厂方法
定义
定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。进一步抽象化核心工厂类们可以使系统在不修改具体工厂角色的情况下引进新的产品。
实现
public interface Product {
public void method();
}
public class ProductA implements Product{
public void method() {
System.out.println("AAA");
}
}
public class ProductB implements Product{
public void method() {
System.out.println("BBB");
}
}
public interface ProductFactory {
Product create();
}
public class ProductFactoryA implements ProductFactory {
@Override
public Product create() {
return new ProductA();
}
}
public class ProductFactoryB implements ProductFactory {
@Override
public Product create() {
return new ProductB();
}
}
//测试
public class Test {
public static void main(String[] args) {
ProductFactory productFactory=new ProductFactoryA();
Product producta=productFactory.create();
producta.method();
//B同理
}
}
现在我们增加产品时,只需要增加响应的产品和工厂,而完全不需要修改原有的代码。相比与简单工厂方法,更加符合开闭原则。
缺点
如果有30个产品,那且不是对应有30个工厂类。总共就60个类了,继续膨胀系统类过多,就会造成难以维护。
简单工厂VS工厂方法
像上面的案例,就可以直接使用简单工厂方法。当对象的创建逻辑比较复杂,不只是简单的 new 一下就可以,而是要组合其他类对象,做各种初始化操作的时候,推荐使用工厂方式,将复杂的创建逻辑拆分到多个工厂中,让每个工厂类不至于太过复杂。
下图就是我理解的简单工厂(左)和工厂方法(右)的UML类图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wi233nr0-1621521771151)(D:\myself\Java-Learn\自己总结的方向\Java 进阶\设计模式\工厂方法1.jpg)]
抽象工厂
定义
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
实现
//产品类
public interface ProductA {
void methodA();
}
public interface ProductB {
void methodB();
}
public class ProductA1 implements ProductA {
@Override
public void methodA() {
System.out.println("A1");
}
}
public class ProductA2 implements ProductA {
@Override
public void methodA() {
System.out.println("A2");
}
}
public class ProductB1 implements ProductB {
@Override
public void methodB() {
System.out.println("B1");
}
}
public class ProductB2 implements ProductB {
@Override
public void methodB() {
System.out.println("B2");
}
}
//工厂类
public interface ProductFactory {
ProductA createA();
ProductB createB();
}
public class ProductFactoryA implements ProductFactory {
@Override
public ProductA createA() {
return new ProductA1();
}
@Override
public ProductB createB() {
return new ProductB1();
}
}
public class ProductFactoryB implements ProductFactory {
@Override
public ProductA createA() {
return new ProductA2();
}
@Override
public ProductB createB() {
return new ProductB2();
}
}
//测试
public class Test {
public static void main(String[] args) {
ProductFactory productFactory=new ProductFactoryA();
ProductA producta=productFactory.createA();
ProductB productb=productFactory.createB();
producta.methodA();
productb.methodB();
}
}
就是一个工厂不止创建一个对象,这里一个工厂是创建了两个对象。一定程度上解决了工厂方法的类过于膨胀的问题。
参考: