设计模式之抽象工厂模式

抽象工厂模式

对比:
工厂方法模式:是一种由工厂接口提供一个创建产品接口的方法的设计模式。
抽象工厂模式:是一种由工厂接口提供一系列产品接口创建方法的设计模式。

**定义:**为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
定义中说了,我们是要创建一个接口,而这个接口的作用是什么呢?是用于创建一组相关或相互依赖的对象,而且这些对象不是具体的类,即是说创建的是接口或者是抽象类。
具体类图:
在这里插入图片描述
根据上面类图写下的程序代码如下:
产品接品及其相应实现类

package net;

interface ProductA {

    void methodA();
}

interface ProductB {
    
    void methodB();
}

class ProductA1 implements ProductA{

    public void methodA() {
        System.out.println("产品A系列中1型号产品的方法");
    }
    
}

class ProductA2 implements ProductA{

    public void methodA() {
        System.out.println("产品A系列中2型号产品的方法");
    }
    
}

class ProductB1 implements ProductB{

    public void methodB() {
        System.out.println("产品B系列中1型号产品的方法");
    }
    
}

class ProductB2 implements ProductB{

    public void methodB() {
        System.out.println("产品B系列中2型号产品的方法");
    }
    
}
工厂接口代码:
package net;

public interface Creator {

    ProductA createProductA();
    
    ProductB createProductB();
    
}

工厂实现类代码:

package net;

public class ConcreteCreator1 implements Creator{

    public ProductA createProductA() {
        return new ProductA1();
    }

    public ProductB createProductB() {
        return new ProductB1();
    }

}
package net;

public class ConcreteCreator2 implements Creator{

    public ProductA createProductA() {
        return new ProductA2();
    }

    public ProductB createProductB() {
        return new ProductB2();
    }

}

测试代码:

package net;


public class Client {

    public static void main(String[] args) throws Exception {
        Creator creator = new ConcreteCreator1();
        ProductA productA = creator.createProductA();
        ProductB productB = creator.createProductB();
        productA.methodA();
        productB.methodB();
        
        creator = new ConcreteCreator2();
        productA = creator.createProductA();
        productB = creator.createProductB();
        productA.methodA();
        productB.methodB();
    }
}

抽象工厂模式是为了解决抽象产品不再一个的问题。
关于List原码的分析:

package java.util;

public interface List<E> extends Collection<E> {
    
    Iterator<E> iterator();//一种产品

    Object[] toArray();

    <T> T[] toArray(T[] a);

    ListIterator<E> listIterator();//另外一种产品

    ListIterator<E> listIterator(int index);

}

从原码中可以看到List使用的就是抽象工厂模式来设计的,其中iterator及listIterator是对应的两种产品接口。
下面的是对应的类图(UML图):
在这里插入图片描述
类图分析:
1.List,是抽象工厂的角色,它有两个制造产品的方法,iterator和listIterator,相当于Creator。
2.ListIterator和Iterator都是抽象产品,相当于ProductA和ProductB。其中ListIterator有两个实现类,分别是AbstractList.ListItr和LinkedList.ListItr,相当于ProductA1和ProductA2。Iterator的实现类为AbstractList.Itr,相当于ProductB1,但是没有B2。
3.LinkedList是其中一个具体的工厂类,相当于ConcreteCreator1,实现抽象工厂List,它制造的两个具体产品分别是LinkedList.ListItr和AbstractList.Itr。
4.同样的,ArrayList也是一个具体的工厂类,相当于ConcreteCreator2,实现抽象工厂List,它制造的两个具体产品分别是AbstractList.ListItr和AbstractList.Itr。
结合上一章工厂方法模式,我们来分析一下工厂方法模式和抽象工厂模式二者的关系。
Iterable接口是List的父接口,所以它只负责一个产品Iterator的制造,所以是工厂方法模式,而List接口扩展了Iterable接口,又添加了一个制造产品的方法,即又添加了一个系列的产品,所以就成为了抽象工厂模式。

下面是由简单工厂到工厂方法再到抽象工厂三大模式的进化过程:
一、简单工厂:

interface Product{}

//具体产品
class ProductA implements Product{}
class ProductB implements Product{}

//产品工厂(下一步就是它的进化,就变成了工厂方法模式)
// 这里其实也使用的是单例设计模式
public class ProductFactory {

    private ProductFactory(){}
    
    public static Product getProduct(String productName){
        if (productName.equals("A")) {
            return new ProductA();
        }else if (productName.equals("B")) {
            return new ProductB();
        }else {
            return null;
        }
    }
}

二、工厂方法模式

interface Product{}

//具体产品
class ProductA implements Product{}
class ProductB implements Product{}

//将简单工厂中的工厂给抽象成接口
interface Factory{
    Product getProduct();
}
//具体的工厂A,创造产品A
class FactoryA implements Factory{

    public Product getProduct() {
        return new ProductA();
    }
    
}
//具体的工厂B,创造产品B
class FactoryB implements Factory{

    public Product getProduct() {
        return new ProductB();
    }
    
}

抽象工厂模式:

interface Product1{}

//具体产品
class Product1A implements Product1{}
class Product1B implements Product1{}

//多了一个抽象产品1
interface Product2{}

//具体产品1
class Product2A implements Product2{}
class Product2B implements Product2{}

//原有的工厂方法模式的工厂里添加一个方法
interface Factory{
    Product getProduct1();
    //添加另外一个产品族的创造方法
    Product1 getProduct2();
}
//具体的工厂A,创造产品A
class FactoryA implements Factory{

    public Product1 getProduct() {
        return new Product1A();
    }
    //添加相应的实现
    public Product2 getProduct1() {
        return new Product2A();
    }
    
}
//具体的工厂B,创造产品B
class FactoryB implements Factory{

    public Product1 getProduct1() {
        return new Product1B();
    }
    //添加相应的实现
    public Product2 getProduct2() {
        return new Product2B();
    }
    
}

进化过程:

首先,工厂模式都需要一个产品接口。

简单工厂模式是通过单例模式设计了一个工厂类去生产不同的实现了相同产品接口的产品。

工厂方法模式是在简单工厂的基础上把工厂类抽象成工厂接口,该工厂接口也不再生产具体的产品,而是生成产品接口。而是把生产产品实现的具体细节交给了实现了该工厂接口的实现类去做。这样做可以解决了简单工厂模式的对修改开放的弊端,实现了六大开发指导原则中大姐大(开闭原则)。

抽象工厂模式即在工厂方法的基础上进行了扩展,从工厂方法只能生产一种产品接口扩展成生产多种相关或相互依赖的产品接口。这样做解决了工厂方法不适合多种产品设计的弊端。

下面介绍两套关于工厂模式设计扩展第三方包的方法:
一、工厂方法模式:

//抽象产品
interface Product{}

//具体产品
class ProductA implements Product{}
class ProductB implements Product{}

//工厂接口
interface Factory{
    Product getProduct();
}

//具体的工厂A,创造产品A
class FactoryA implements Factory{

    public Product getProduct() {
        return new ProductA();
    }
    
}
//具体的工厂B,创造产品B
class FactoryB implements Factory{

    public Product getProduct() {
        return new ProductB();
    }
    
}

/*   假设以上是一个第三方jar包中的工厂方法模式,我们无法改动源码   */

//我们自己特有的产品
interface MyProduct{}

//我们自己特有的产品实现
class MyProductA implements MyProduct{}
class MyProductB implements MyProduct{}

//扩展原有的工厂接口
interface MyFactory extends Factory{
    MyProduct getMyProduct();
}

//我们自己特有的工厂A,扩展自原有的工厂A,并且实现获得我们自己特有产品的接口方法
class MyFactoryA extends FactoryA implements MyFactory{

    public MyProduct getMyProduct() {
        return new MyProductA();
    }
    
}
//同A
class MyFactoryB extends FactoryB implements MyFactory{

    public MyProduct getMyProduct() {
        return new MyProductB();
    }
    
}

二、使用组合的方式:

//抽象产品
interface Product{}

//具体产品
class ProductA implements Product{}
class ProductB implements Product{}

//工厂接口
interface Factory{
    Product getProduct();
}

//具体的工厂A,创造产品A
class FactoryA implements Factory{

    public Product getProduct() {
        return new ProductA();
    }
    
}
//具体的工厂B,创造产品B
class FactoryB implements Factory{

    public Product getProduct() {
        return new ProductB();
    }
    
}

/*   假设以上是一个第三方jar包中的工厂方法模式,我们无法改动源码   */

//我们自己特有的产品
interface MyProduct{}

//我们自己特有的产品实现
class MyProductA implements MyProduct{}
class MyProductB implements MyProduct{}

//我们自己的工厂接口
interface MyFactory{
    MyProduct getMyProduct();
}

//我们自己特有的工厂A,产生产品A
class MyFactoryA implements MyFactory{
    
    public MyProduct getMyProduct() {
        return new MyProductA();
    }
    
}

//我们自己特有的工厂B,产生产品B
class MyFactoryB implements MyFactory{
    
    public MyProduct getMyProduct() {
        return new MyProductB();
    }
    
}

/*  到这里是我们自己的一套工厂方法模式,去创造我们自己的产品,以下我们将以上二者组合   */

//我们使用组合的方式将我们的产品系列和jar包中的产品组合起来
class AssortedFactory implements MyFactory,Factory{
    
    MyFactory myFactory;
    Factory factory;
    
    public AssortedFactory(MyFactory myFactory, Factory factory) {
        super();
        this.myFactory = myFactory;
        this.factory = factory;
    }

    public Product getProduct() {
        return factory.getProduct();
    }

    public MyProduct getMyProduct() {
        return myFactory.getMyProduct();
    }
    
}

抽象工厂模式学习结束

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值