我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java设计模式之工厂方法和抽象工厂

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java设计模式之工厂方法和抽象工厂

全网最详细的工厂设计模式,本文主要是创建型设计模式中的工厂方法和抽象工厂,先由传统实现方式引出问题,接着对代码改进到简单工厂,后扩展到工厂方法,最后是抽象工厂模式,文中包括概念理解和相关实现代码。

读者可以拉取完整代码本地学习,实现代码均测试通过上传到码云,本地源码下载。

一、引出问题

如果有一个客户老王,需要购买产品,产品分别是A、B、C。

如果用传统方法实现,分别定义A、B、C三个类,再分别创建他们所属的方法。

在客户对象中再分别调用他们的方法。

Product ClientProduct(String orderType) {
    Product product;

    if (orderType.equals("A")) {
        product = new ProductA();
    } else if (orderType.equals("B")) {
        product = new ProductB();
    } else if (orderType.equals("B")) {
        product = new ProductC();
    }
    
    // product制作过程
    product.common();
    
    return product;
}

如果我们需要再增加一个产品D,就需要判断再增加一个分支,然后在分支里面创建产品对象,调用产品D的方法。

这样代码的维护性是极差的,查看我们的软件设计七大原则,很明显,这违反了开闭原则、依赖倒置原则.

如果又有个客户小王,那么小王也必须依赖每个产品类,这样就显得冗杂。

二、简单工厂(静态工厂)

简单工厂(静态工厂)模式就应用而生了。

如果我们将产品A、B、C抽象出来一个父类,再专门创建一个工厂类,在客户购买产品时,只需要传入产品的类型,由工厂去创建产品。

简单工厂模式中包含如下角色:

Factory:工厂角色

​ 工厂角色负责实现创建所有实例的内部逻辑。

Product:抽象产品角色

​ 抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口。

ConcreteProduct:具体产品角色

​ 具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。

看看我们对原始实现方式后的代码。

产品抽象父类:


public class Product {

    public void common(){
        System.out.println("这是产品父类公共方法...");
    }


}

产品A:


public class ProductA extends Product{

    public void common(){
        System.out.println("这是产品A方法...");
    }

}

产品B:


public class ProductB extends Product{

    public void common(){
        System.out.println("这是产品B方法...");
    }
}

工厂类:



public class SimpleFactory {

    public Product createProduct(String orderType) {
        Product product = null;

        if (orderType.equals("A")) {
            product = new ProductA();
        } else if (orderType.equals("B")) {
            product = new ProductB();
        } else if (orderType.equals("C")) {
            product = new ProductC();
        }
        return product;
    }
}

客户老王类:


public class Client {

    SimpleFactory simpleFactory;

    public Client(SimpleFactory simpleFactory) {
        this.simpleFactory = simpleFactory;
    }

    public Product orderProduct(String orderType) {

        Product product;    

        product = simpleFactory.createProduct(orderType);

       //调用每个产出相应的方法
        product.common();
        System.out.println(product.getClass());
        return product;
    }

    public static void main(String[] args) {
        Client client=new Client(new SimpleFactory());
        client.orderProduct("A");
    }

}

这样简单工厂模式就实现了,这样的话老王和具体的产品就很好的解耦了,也不需要老王再依赖具体产品类,依赖倒置问题就很好的解决了。

如果增加一个产品D,需要再重新定义一个D类,实现product接口,而后在工厂类中增加一个分支结构。

显而易见这样实现,缺陷依然存在:

1、工厂类集中了所有产品创建逻辑,职责过重,一旦发生异常,整个系统将受影响。
2、使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
3、系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂。
4、简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

这种方法只是一种编码方式,并不输入设计模式的一种,且局限于产品种类较少。

三、工厂方法

在简单工厂中老王需要具体的产品,就在他自己的类中去创建需要的产品,老王虽然不依赖具体产品,但老王现在需要依赖工厂实现类了。

简单工厂是将产品类抽象化,具体的产品由工厂类去实现。

如果我们将工厂类也抽象化,那就引出了我们今天第一个设计模式——工厂方法。

工厂方法有四个角色:

1、抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 createProduct() 来创建产品。
2、具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
3、抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
4、具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

我们对简单工厂代码进行改造。

抽象产品父类、产品A类、产品B类保持不变。重点看工厂类

抽象工厂类:



public abstract class AbstractFactory {

    public abstract Product createProduct(String orderType);
}

具体实现工厂A类:


public class ConcreteFactoryA extends AbstractFactory{
    @Override
    public Product createProduct(String orderType) {
        System.out.println("参数为:"+orderType);
        return new ProductA();
    }
}

具体实现工厂B类:


public class ConcreteFactoryB extends AbstractFactory{
    @Override
    public Product createProduct(String orderType) {
        return new ProductB();
    }
}

老王类:


public class Client {

    AbstractFactory simpleFactory;

    public Client(AbstractFactory simpleFactory) {
        this.simpleFactory = simpleFactory;
    }

    public Product orderProduct(String orderType) {

        Product product;

        product = simpleFactory.createProduct(orderType);

       //调用每个产出相应的方法
        product.common();
        System.out.println(product.getClass());
        return product;
    }

    public static void main(String[] args) {
        Client client=new Client(new ConcreteFactoryA());
        client.orderProduct("A");
    }

}

这样的好处就在于老王只管他要关注的抽象工厂,具体是哪个工厂实现类生产产品,老王也不需要关注。

典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

缺点也是显而易见的:

  • 类的个数容易过多,增加复杂度。
  • 考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度。
  • 抽象产品只能生产一种产品。

如果对工厂方法依然一知半解的话,接着往下看工厂方法的一个典型实现

在JDK中对工厂方法有大量的运用,其中比较典型的是

new ArrayList<>().iterator();

我们知道集合的一个大分支依赖的是Collection接口,我们以ArrayList作为举例。

Collection接口相当于产品的抽象父类,ArrayList相当于具体产品。

Iterator是一个抽象工厂,在ArrayList中有一个Itr内部类实现了Iterator接口

当我们调用集合的iterator()方法遍历对象时,就会调用各自类的具体实现方法。

四、抽象工厂

有一天,产品A、B、C升级改造了,三种产品分别有红色和蓝色,如果还用工厂方法的话,那简直是个灾难,具体工厂实现类需要六个。

就引出我们今天的第二个设计模式——抽象工厂。

抽象工厂模式(Abstract Factory Pattern):提供一个接口,用于创建创建一系列相关或相互依赖对象的家族,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。

抽象工厂模式与工厂方法模式区别在于,工厂方法模式针对的是一个产品等级结构。

而抽象工厂模式则需要面对多个产品等级结构(各种颜色),一个工厂等级结构可以负责多个不同产品等级结构(不同颜色)中的产品对象的创建 。

抽象工厂依然是四个角色:

  • AbstractFactory:抽象工厂

  • ConcreteFactory:具体工厂

  • AbstractProduct:抽象产品

  • Product:具体产品

    我们开始改造工厂方法代码,既然是要把产品都分成一组,那理应把产品A、B、C都抽象出来,再让工厂类去实现各个产品的不同颜色,也就是概念中的——用于创建创建一系列相关或相互依赖对象的家族。

接口看改造后的代码:

产品抽象类:


public interface Product {

    public void common();

}

产品抽象A家族类:


public abstract class ProductA implements Product {

    public abstract void common();

}

产品抽象B家族类:


public abstract class ProductB implements Product {

    public abstract void common();
}

具体红色产品A类:


public class RedProductA extends ProductA{
    @Override
    public void common() {
        System.out.println("这是红色的产品A");
    }
}

具体蓝色产品A类:


public class BlueProductA extends ProductA {

    @Override
    public void common() {
        System.out.println("这是蓝色的产品A");
    }
}

抽象A家族工厂类:



public interface AbstractProductFactory {

    public ProductA createProduct(String orderType);
}

实现A家族工厂类:


public class ConcreateProductAFactory implements AbstractProductFactory{

    @Override
    public ProductA createProduct(String orderType) {
        return new BlueProductA();
    }
}

老王类:


public class Client {

    ConcreateProductAFactory simpleFactory;

    public Client(ConcreateProductAFactory simpleFactory) {
        this.simpleFactory = simpleFactory;
    }

    public ProductA orderProduct(String orderType) {

        ProductA product;

        product = simpleFactory.createProduct(orderType);

       //调用每个产出相应的方法
        product.common();
        System.out.println(product.getClass());
        return product;
    }

    public static void main(String[] args) {
        Client client=new Client(new ConcreateProductAFactory());
        client.orderProduct("A");
    }

}

这样的话,每天工厂类可以把A的产品家族类(红、蓝)都实现,抽象工厂模式隔离了具体类的生成,使得老王并不需要知道什么产品被创建,从具体的产品解耦出来。

  • 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。

如果要增加新产品、和新工厂很容易,如果再增加一个等级(颜色)代码修改起来就很痛苦了。

抽象工厂模式在Spring中有大量的运用。

比较典型的是,BeanFactory 是用于管理 Bean 的一个工厂,所有工厂都是 BeanFactory 的子类。这样我们可以通过 IOC 容器来管理访问 Bean,根据不同的策略调用 getBean() 方法,从而获得具体对象。

BeanFactory 的子类主要有

ClassPathXmlApplicationContext、

XmlWebApplicationContext、

StaticWebApplicationContext、

StaticApplicationContext。

在 Spring 中,DefaultListableBeanFactory 实现了所有工厂的公共逻辑。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对编程网的支持。如果你想了解更多相关内容请查看下面相关链接

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java设计模式之工厂方法和抽象工厂

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

设计模式之简单工厂模式、工厂模式、抽象工厂模式的对比

设计模式已经经历了很长一段时间的发展,它们提供了软件开发过程中面临的一般问题的最佳解决方案。学习这些模式有助于经验不足的开发人员通过一种简单快捷的方式来学习软件设计。

Python设计模式之抽象工厂模式

python面向对象编程入门,我们需要不断学习进步 """抽象工厂模式的实现"""import randomclass PetShop:"""宠物商店"""def __init__(self, animal_factory=None):""
2022-06-04

Java简单工厂,工厂方法,抽象工厂模式怎么实现

这篇文章主要讲解了“Java简单工厂,工厂方法,抽象工厂模式怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java简单工厂,工厂方法,抽象工厂模式怎么实现”吧!1、简单工厂模式1.定
2023-06-29

简单工厂模式和抽象工厂模式

简单工厂模式,顾名思义,就是比较简单的一个模式,并且使用在业务比较简单的情况下,且具体产品不需要扩张它由三种角色组成工厂类,是这个模式的核心,含有一定的逻辑和判断,根据逻辑不同,产生具体的工厂产品抽象产品:具体产品的父类具体产品:工具抽象产
2023-06-02

java中抽象工厂模式与工厂方法模式的区别

一、简单工厂模式特点:1、它是一个具体的类,非接口 抽象类。有一个重要的create()方法,利用if或者 switch创建产品并返回。2、create()方法通常是静态的,所以也称之为静态工厂。缺点:1、扩展性差(我想增加一种面条,除了新增一个面条产品类,还
java中抽象工厂模式与工厂方法模式的区别
2015-05-09

简单工厂,工厂方法和抽象工厂

抽象工厂http://www.cnblogs.com/java-my-life/archive/2012/03/28/2418836.html工厂方法http://www.cnblogs.com/java-my-life/archive/2
2023-06-03

设计模式系列-抽象工厂模式

抽象工厂提供了一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。简单来说是为需要创建多个相关联产品的场景提供了解决思路。

java设计模式之抽像工厂详解

一、概念  提供一个创建一系列相关或相互依赖对像的接口,而无需指定它们具体的类。二、模式动机  这一系列对像之间是相互依赖的,相当于一个产品族 三、模式的结构通过上图我们可以清楚的看到抽像工厂模式包括以下4个角色:  1.抽像工厂角色(A
2023-05-31

设计模式系列—抽象工厂模式

本篇和大家一起来学习抽象工厂模式相关内容。

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录