简单工厂、工厂方法、抽象工厂三种设计模式总结

概述

  工厂模式是创建型设计模式的代表,其设计的思想就是将类的创建和使用隔离开来,用一个专门的工厂类来创建对象,这样就将使用的类和创建的类进行了解耦。引入了工厂类以后,程序的目标就是如何在新增了被创建对象的时候,在最小的改动中完成新的扩展功能,这种扩展主要体现在以下两个方面:

  • 客户端创建和使用工厂类的扩展,也就是扩展中尽量做到客户端不修改
  • 工厂类创建类的时候的扩展,也就是扩展中工厂类不修改

  为了解决以上两个问题,不同的解决思路演化成了不同的工厂模式,用来解决不同的问题。

简单工厂模式(Simple Factory)

定义

  简单工厂设计模式就是单纯的将创建类的功能进行解耦出来,将创建对象的功能放到工厂类中去,客户端直接调用工厂类便可以得到要使用的对象。简单工厂的本质就是选择创建。在这个过程中,如果需要在多个被创建类中选择一个去创建,客户端就要指定到底要创建哪一个。

代码示例

  我们以创建一类产品对象的不同产品为例,类简单模拟简单工厂模式的使用。

  1. 先创建一个Product的接口类
public interface Product {
    void operate();
}
  1. 实现两个产品ProductA和ProductB
public class ProductA implements Product {
    @Override
    public void operate() {
        System.out.println("productA");
    }
}
public class ProductB implements Product {
    @Override
    public void operate() {
        System.out.println("productB");
    }
}
  1. 创建简单工厂类,我们以传入一个string标记和传入Class对象的两种方式来举例,当然也可以用配置文件的方式或者其他的方法。
public class SimpleFactory {

    /**
     * 创建对象的方式一:
     * 客户端传入一个标记,工厂类根据标记来创建对象
     * @param productFlag : 创建标记
     * @return : 被创建的对象
     */
    public static Product createProduct(String productFlag) {
        if (productFlag == null || "".equals(productFlag.trim())) {
            return null;
        }
        productFlag = productFlag.trim();
        if ("productA".equals(productFlag)) {
            return new ProductA();
        }
        if ("productB".equals(productFlag)) {
            return new ProductB();
        }
        return null;
    }

    /**
     * 创建对象的方式二:
     * 客户端传入被创建对象的class类,工厂类根据反射去创建对象
     * @param clazz : 被创建对象的class类
     * @return : 被创建的对象
     */
    public static Product createProduct(Class<? extends Product> clazz) {
        if (null == clazz) {
            return null;
        }
        try {
            return clazz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
  1. 客户端使用
public class Client {

    @Test
    public void test1() {
        Product product = SimpleFactory.createProduct("productA");
        product.operate();
    }

    @Test
    public void test2() {
        Product product = SimpleFactory.createProduct(ProductB.class);
        product.operate();
    }
}

UML类图

简单工厂模式类图

总结

  简单工厂模式对客户端和创建对象的逻辑进行了简单的隔离,并没有做到完全的解耦,从示例中我们可以看到,客户端在使用的过程中,还是要感知对象的存在,同时工厂类在创建对象的时候,也要感知对象的存在,因此,创建解耦的两边都没有做到完全的解耦。但是简单工厂模式只需要增加一个工厂类,而且如果被创建的对象比较简单的话,完全可以用静态方法来写,这样对于客户端使用和代码的可读性方面都是非常清晰的。

工厂方法模式(Factory Method)

定义

  工厂方法模式在简单工厂的基础上,着重解决了工厂类和创建的对象之间的扩展问题。具体实现思路是:讲工厂对象作为一个接口或者抽象类,让工厂的子类去实现具体要创建哪个对象。工厂方法的本质就是将具体的创建逻辑让子类去实现,这样在新增了对象的时候,同步新增对应的工厂类即可,客户端就不需要感知具体的对象了。

代码示例

  我们在简单工厂中Product接口和ProductA、ProductB两个实现类的基础上,进行代码示例编写

  1. 新增一个工厂方法的接口
public interface ProductFactoryMethod {
    Product createProduct();
}
  1. 创建两个ProductFactoryMethod的实现类ProductAFactory和ProductBFactory,用来对应创建ProductA和ProductB对象
public class ProductAFactory implements ProductFactoryMethod {
    @Override
    public Product createProduct() {
        return new ProductA();
    }
}
public class ProductBFactory implements ProductFactoryMethod {
    @Override
    public Product createProduct() {
        return new ProductB();
    }
}
  1. 客户端代码如下
public class Client {
    @Test
    public void test() {
        ProductFactoryMethod factoryMethod = new ProductAFactory();
        factoryMethod.createProduct().operate();
    }
}

UML类图

工厂方法模式类图

总结

  工厂方法模式在简单工厂的基础上,讲具体对象的创建交到工厂创建类的子类中去实现,对客户端和产品对象进行了解耦,使的客户端在不感知产品的对象的前提下,对程序进行了扩展。虽然客户端不用感知产品,但是需要感知具体的工厂类,但是这种感知可以在新增了产品对象需要扩展时,用配置文件或者数据库的方式,进行扩展,使的客户端和产品对象不再耦合成为了可能。

抽象工厂模式(Abstract Factory)

定义

  抽象工厂模式的主要目的是为了创建有相互依赖的产品族的。在现实生活中,有的对象是要组合起来使用的,两个类型的产品有着相互的依赖关系,比如intel的CPU就必须装在支持intel的主板上,同理AMD的CPU也要装在支持AMD的主板上才能工作,虽然对于产品来说,有CPU和主板两类,但是其具体的实现有特定的依赖关系。解决这种问题,我们可以用到抽象工厂模式,先定义一个抽象的工厂类,里面可以创建相互关联的产品类型,在具体实现的工厂子类中可以实现相互依赖的产品。比如上面cpu和主板的例子中,我们可以先定义一个工厂接口,其中有两个方法,一个是创建CPU的方法,一个是创建主板的方法,在intel的产品工厂实现类中可以穿件intel的CPU和主板,在AMD的工厂实现类中可以创建AMD的CPU和主板,这样不同工厂的实现类创建出来的产品就是相互关联好的,不会出现不一致的情况。

代码示例

  1. 新建ProductA和ProductB两类产品的接口
public interface ProductA {
    void operateA();
}
public interface ProductB {
    void operateB();
}
  1. 给ProductA实现两个产品ProductA1和ProductA2,同理给ProductB实现两个产品ProductB1和ProductB2,其中ProductA1和ProductB1有依赖关系,ProductA2和ProductB2有依赖关系。
public class ProductA1 implements ProductA {
    @Override
    public void operateA() {
        System.out.println("operateA1");
    }
}
public class ProductA2 implements ProductA {
    @Override
    public void operateA() {
        System.out.println("operateA2");
    }
}
public class ProductB1 implements ProductB {
    @Override
    public void operateB() {
        System.out.println("operateB1");
    }
}
public class ProductB2 implements ProductB {
    @Override
    public void operateB() {
        System.out.println("operateB2");
    }
}
  1. 创建一个抽象工厂的接口,可以创建ProductA和ProductB两类产品
public interface AbstractFactory {
    ProductA createProductA();

    ProductB createProductB();
}
  1. 创建两个AbstractFactory工厂的实现类Product1Factory和Product2Factory,用来具体创建产品对象
public class Product1Factory implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ProductA1();
    }

    @Override
    public ProductB createProductB() {
        return new ProductB1();
    }
}
public class Product2Factory implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ProductA2();
    }

    @Override
    public ProductB createProductB() {
        return new ProductB2();
    }
}
  1. 客户端使用
public class Client {

    @Test
    public void testProductFactory1() {
        AbstractFactory factory = new Product1Factory();
        userProduct(factory);
    }

    @Test
    public void testProductFactory2() {
        AbstractFactory factory = new Product2Factory();
        userProduct(factory);
    }

    private void userProduct(AbstractFactory factory) {
        ProductA productA = factory.createProductA();
        productA.operateA();
        ProductB productB = factory.createProductB();
        productB.operateB();
    }
}

UML类图

抽象工厂模式类图

总结

  抽象工厂模式是为了解决有相互依赖产品族的问题,如果把相互依赖的产品看成是一类产品对象的话,抽象工厂就成了工厂方法模式。


后记
  个人总结,欢迎转载、评论、批评指正

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值