Java三种工厂模式

前言


很多框架中都设计到设计模式,其中工厂模式最常用,为了日后能更好研究框架源码,或者对于小白的我来说至少能读懂框架源码。掌握基本的设计模式是必须的。所以在这里做一个粗浅的认识总结,其中可能会有很多的瑕疵,希望大家多多包涵,此外其中的UML都是自己画的,自我感觉不太很正规。


概念

以工厂方法模式(Factory Method Model)UML说明相关概念
Java三种工厂模式_第1张图片
角色说明:

  • 抽象工厂角色AbstractFactory:工厂方法模式的核心,它与应用程序无关,其中主要规定返回的抽象产品,是具体工厂角色必须实现的接口或者必须继承的父类,由子类实现返回的具体产品。
  • 具体工厂角色ConcreteFactoryA/B:实现或继承自抽象工厂角色,含有和具体业务逻辑有关的代码。创建对应的具体产品的对象。
  • 抽象产品角色Product:是所有具体产品角色的父类,它负责描述所有产品实例所共有的公共接口。
  • 具体产品角色ConcreteProductA/B:继承或者实现自抽象产品角色,一般为多个。工厂类返回的都是该角色的某一具体产品。

应用实例:

  • Hibernate换数据库只需要换方言和驱动就可以,不需要关心是怎么生成相关的类。
  • 我们去饭店点餐,只需要按照菜单选择好吃好看的报上名字就可以,而不需要关心后台厨师(工厂)是怎么炒菜的。
  • 比如某位女生的衣柜里存在商务女装、时尚女装、休闲女装、男朋友买的套装(谁叫女生的衣服多呢,我就拿这个比喻了,哈哈)这些也都是成套存在的,即可以理解为一系列具体产品。某一天她要去约会,那么她选择的是男朋友买的套装出门,那么这个套装有上衣(某个具体产品),裤子(某个具体产品)。直接拿出来就可以穿上出门,女生就不需要太关心这个套装是如何搭配的(很有审美观男朋友已经帮忙搭配好了,女生也比较满意),是不是方便了许多了呢?

1、简单工厂模式(Simple Factory

  • 工厂是一个简单的类,不是抽象类或者是接口,其中生成返回具体产品通常使用if-else或者swith-case
  • 返回产品的方法一般都是static,所有也称之为静态工厂方法模式(Static FactoryMethod Pattern)。
  • 也可以认为:简单工厂模式看为工厂方法模式的一种特例,所以优缺点等介绍将不做,具体请看工厂方法模式。

2、工厂方法模式(Factory Method

特点

(1)生成返回具体产品是通过实现抽象工厂类或者工厂接口方式。
(2) 一组产品依赖实现一个抽象类或接口。
(3)一个工厂工具(工厂实现类)返回产品组中一个具体产品类。


UML图

Java三种工厂模式_第2张图片

  • ConcreteProductA只依赖ConcreteFactroyAConcreteFactroyA只返回ConcreteProductA
  • 一组产品ConcreteProductAConcreteProductB只实现Product产品接口;
  • 一个工厂接口AbstracFactory也只依赖一个产品接口Product

代码实现:

Java三种工厂模式_第3张图片
AbstractFactory.java:

/**
 * 抽象工厂类:返回具体产品
 * @author Lijian
 *
 */
interface AbstractFactory {
    Product createProduct();
}

Product.java:

/**
 * 抽象产品类:定义产品
 * @author Lijian
 *
 */
interface Product {
    void method1();
    void method2();
}

ConcreteProductA.java:

/**
 * 产品类
 * @author Lijian
 *
 */
public class ConcreteProductA implements Product{

    @Override
    public void method1() {
        System.out.println("ConcreteProductA implement method1()");
    }

    @Override
    public void method2() {
        System.out.println("ConcreteProductA implement method2()");
    }
}

ConcreteProductB.java

/**
 * 产品类
 * @author Lijian
 *
 */
public class ConcreteProductB implements Product{

    @Override
    public void method1() {
        System.out.println("ConcreteProductB implement method1()");
    }

    @Override
    public void method2() {
        System.out.println("ConcreteProductB implement method2()");
    }
}

ConcreteFactoryA.java

/**
 * 工厂工具类A
 * @author Lijian
 *
 */
public class ConcreteFactoryA implements AbstractFactory{
    //构造器,可以外部调用对外创建实例
    public ConcreteFactoryA() {}
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

ConcreteFactoryB.java:

/**
 * 工厂工具类B
 * @author Lijian
 *
 */
public class ConcreteFactoryB implements AbstractFactory{
    //构造器,可以外部调用对外创建实例
    public ConcreteFactoryB() {}
    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

Consumer.java

/**
 * 客户端消费者类
 * @author Lijian
 *
 */
public class Consumer {
    public static void serviceFactory(AbstractFactory factory) {
        Product product = factory.createProduct();//upcast向上转型
        System.out.println(factory.getClass().getSimpleName()+" create "+product.getClass().getSimpleName()+":");
        product.method1();
        product.method2();
    }
    public static void main(String[] args) {
        //传入工厂工具类ConcreteFactoryA/B
        serviceFactory(new ConcreteFactoryA());
        serviceFactory(new ConcreteFactoryB());
    }
}

结果如下:

ConcreteFactoryA create ConcreteProductA:
ConcreteProductA implement method1()
ConcreteProductA implement method2()
ConcreteFactoryB create ConcreteProductB:
ConcreteProductB implement method1()
ConcreteProductB implement method2()


3、抽象工厂模式(Abstract Factory

首先应该先知道产品族与等级结构指的是什么:

等级结构:工厂模式提供的一系列产品,即全部依赖实现于同一个接口或者抽象类产品。
产品族:指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族。

特点

(1)提供创建一组相关相互依赖对象的接口,而无需指定他们具体的类。
(2)工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。
(3)抽象工厂实现类提供的产品可以为多个,这多个产品可以实现依赖于不同的产品接口或抽象类产品。


UML图

Java三种工厂模式_第4张图片

  • ConcreteProductA只依赖ConcreteFactroyAConcreteFactroyA只返回ConcreteProductA
  • 一组产品ConcreteProductAConcreteProductB只实现Product产品接口;
  • 一个工厂接口AbstracFactory也只依赖一个产品接口Product

代码实现

这里只举例实现关键部门,没有完整代码实现:
产品相关类:

//多个抽象接口
interface AbstractProductA {  
    public void show();  
}  
interface AbstractProductB {  
    public void show();  
}  

class ProductA implements AbstractProductA {  
    public void show() {  
        System.out.println("ProductA implement AbstractProductA");  
    }  
}  
class ProductB implements AbstractProductB {  
    public void show() {  
        System.out.println("ProductB implement AbstractProductB");  
    }  
} 

工厂相关类:

//一个工厂接口返回多个产品
interface AbstractFactory{  
    public AbstractProductA createProductA();  
    public AbstractProductB createProductB();  
}  
//这些产品之间互相有关联,一个工厂工具返回多个产品
class ConcreteFactory implements AbstractFactory{  
    public AbstractProductA createProductA() {  
        return new ProductA();  
    }  
    public AbstractProductB createProductB() {  
        return new ProductB();  
    }  
}

4、工厂方法与抽象工厂比较

(1)工厂方法模式:

  • 定义一个用于创建对象的接口,让子类(ConcreteFactoryA/B)决定实例化哪一个类,遵循了开放—封闭原则。
  • 相对比之下,工厂方法模式的扩展性比较好,比如我们需要增加一个产品,则需要增加两个工厂相关类与一个产品实现类,但是不需要关心与其他产品之间的复杂关系。
  • 产品只依赖产品接口,与消费者无关,实现了一定的解耦。
  • 抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,不能做到产品的相互交流。

(2)抽象工厂:
抽象工厂模式是工厂方法模式的升级版,除了具备工厂方法模式的优点之外,还具备以下几点:

  • 由于是针对产品族的,所以每个产品的相互约束,相互关联都可以在内部实现,而不需要对外重新创建管理产品的相关类(具体情况根据业务情况而定)
  • 面对复杂的产品生产环境,抽象工厂模式可以应对。
  • 扩展性差,面对增加需求变动时,需要在已经确定了产品集合中增加产品扩展工厂接口,之后还需要确定产品之间的关联依赖。

你可能感兴趣的:(设计模式)