热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于java:JAVA设计模式系列工厂模式

软件设计模式(SoftwareDesignPattern),又称设计模式,是一套被重复应用、少数人通晓的、通过分类编目标、代码设计教训的总结。它形容了在软件设计过程中的一些一直反复

软件设计模式(Software Design Pattern),又称设计模式,是一套被重复应用、少数人通晓的、通过分类编目标、代码设计教训的总结。它形容了在软件设计过程中的一些一直反复产生的问题,以及该问题的解决方案。

也就是说,它是解决特定问题的一系列套路,是前辈们的代码设计教训的总结,具备肯定的普遍性,能够重复应用。

其目标是为了进步代码的可重用性、代码的可读性和代码的可靠性。

那么咱们明天来看看设计模式中的第二种工厂模式中的工厂办法模式

在现实生活中社会分工越来越细,越来越专业化,各种产品有专门的工厂生产,彻底辞别了自力更生的小农经济时代,这大大缩短了产品的生产周期,进步了生产效率。那么咱们可能会思考在软件开发中是否做到软件对象的生产和应用相拆散呢?而这便须要咱们的设计模式中的工厂模式

首先咱们来回忆一下,社会由最开始的自力更生原始社会,到农耕小作坊时代,到工业革命流水线,再到古代产业链代工厂,咱们会发现生产的效率越来越高,其实整个社会的提高就是工厂模式倒退的缩影。最开始自力更生是没有工厂;到小作坊简略实现商品的生产,为简略工厂模式;到工业革命流水线,商品实现自产自销,为工厂办法模式;到现阶段产业链代工厂,如当初的富士康等企业,为其余企业提供工厂流水线,为形象工厂模式

什么是工厂模式呢?

定义一个创立产品对象的工厂接口,将产品对象的理论创立工作推延到具体子工厂类当中。这满足创立型模式中所要求的“创立与应用相拆散”的特点。所有咱们在理论开发中,但凡须要生成简单对象的中央,都能够尝试思考应用工厂模式来代替。而按理论业务场景划分,工厂模式有 3 种不同的实现形式,别离是简略工厂模式、工厂办法模式和形象工厂模式。

所以紧接着咱们来顺次依据不同的场景看看这几种工厂模式。

简略工厂模式

咱们把被创立的对象称为“产品”,把创立产品的对象称为“工厂”。如果要创立的产品不多,只有一个工厂类就能够实现,这种模式叫“简略工厂模式”

在简略工厂模式中创立实例的办法通常为动态(static)办法

因而简略工厂模式(Simple Factory Pattern)又叫作动态工厂办法模式(Static Factory Method Pattern)。

首先咱们来看看简略工厂模式的组成:

  • 简略工厂(SimpleFactory):是简略工厂模式的外围,负责实现创立所有实例的外部逻辑。工厂类的创立产品类的办法能够被外界间接调用,创立所需的产品对象。
  • 形象产品(Product):是简略工厂创立的所有对象的父类,负来源gao@dai!ma.com搞$代^码网责形容所有实例共有的公共接口。
  • 具体产品(ConcreteProduct):是简略工厂模式的创立指标。

绘制结构图如下:

​ 图-1 简略工厂模式结构图

如果咱们用java代码示意是怎么的呢?

/**
 * @author hz
 * @version 1.0
 */
public class Client {
    //形象产品
    public interface Product {
        void show();
    }
    //具体产品:ProductA
    static class ConcreteProduct1 implements Product {
        public void show() {
            System.out.println("具体产品1显示...");
        }
    }
    //具体产品:ProductB
    static class ConcreteProduct2 implements Product {
        public void show() {
            System.out.println("具体产品2显示...");
        }
    }
    final class Const {
        static final int PRODUCT_A = 0;
        static final int PRODUCT_B = 1;
        static final int PRODUCT_C = 2;
    }
    static class SimpleFactory {
        public static Product makeProduct(int kind) {
            switch (kind) {
                case Const.PRODUCT_A:
                    return new ConcreteProduct1();
                case Const.PRODUCT_B:
                    return new ConcreteProduct2();
            }
            return null;
        }
    }
}

该模式的优缺点有哪些呢?

长处:
  1. 工厂类蕴含必要的逻辑判断,能够决定在什么时候创立哪一个产品的实例。客户端能够罢黜间接创立产品对象的职责,很不便的创立出相应的产品。工厂和产品的职责辨别明确。
  2. 客户端无需晓得所创立具体产品的类名,只需晓得参数即可。
  3. 也能够引入配置文件,在不批改客户端代码的状况下更换和增加新的具体产品类。
毛病:
  1. 简略工厂模式的工厂类繁多,负责所有产品的创立,职责过重,一旦异样,整个零碎将受影响。且工厂类代码会十分臃肿,违反高聚合准则。
  2. 应用简略工厂模式会减少零碎中类的个数(引入新的工厂类),减少零碎的复杂度和了解难度
  3. 零碎扩大艰难,一旦减少新产品不得不批改工厂逻辑,在产品类型较多时,可能造成逻辑过于简单
  4. 简略工厂模式应用了 static 工厂办法,造成工厂角色无奈造成基于继承的等级构造。

然而简略工厂模式每减少一个产品就要减少一个具体产品类和一个对应的具体工厂类,这减少了零碎的复杂度,违反了“开闭准则”,因而咱们进行进一步对简略工厂进行形象,这个也是咱们前面马上将给大家说的工厂模式的第二个实现场景,工厂办法模式。

工厂办法模式

后面咱们说了简略工厂模式违反了开闭准则,而“工厂办法模式”是对简略工厂模式的进一步抽象化,其益处是能够使零碎在不批改原来代码的状况下引进新的产品,即满足开闭准则。

工厂办法模式的次要角色蕴含:

  • 形象工厂(Abstract Factory):提供了创立产品的接口,调用者通过它拜访具体工厂的工厂办法 newProduct() 来创立产品。
  • 具体工厂(ConcreteFactory):次要是实现形象工厂中的形象办法,实现具体产品的创立。
  • 形象产品(Product):定义了产品的标准,形容了产品的次要个性和性能。
  • 具体产品(ConcreteProduct):实现了形象产品角色所定义的接口,由具体工厂来创立,它同具体工厂之间一一对应。

绘制结构图如下:

​ 图-2 工厂办法模式

比照简略工厂模式,工厂办法模式在之间简略的工厂的根底之上将工厂进行拆分成形象工厂和具体工厂两局部内容,这样灵活性失去大量晋升。

而这种模式咱们能够在那些场合应用呢?

  • 用户只须要晓得具体工厂的名称就可失去所要的产品,毋庸晓得产品的具体创立过程。
  • 灵活性加强,对于新产品的创立,只需多写一个相应的工厂类。
  • 典型的解耦框架。高层模块只须要晓得产品的抽象类,毋庸关怀其余实现类,满足迪米特法令、依赖倒置准则和里氏替换准则。

如果咱们用java代码示意是怎么的呢?

/**
 * @author hz
 * @version 1.0
 */
public class AbstractFactoryTest {
    public static void main(String[] args) {
        try {
            Product a;
            AbstractFactory af;
            af = (AbstractFactory) ReadXML.getObject();
            //形象工厂内容放入到内部配置文件xml/properties等文件中,通过I/O流加载从而创立出形象工厂
            a = af.newProduct();
            a.show();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
//形象产品:提供了产品的接口
interface Product {
    public void show();
}
//具体产品1:实现形象产品中的形象办法
class ConcreteProduct1 implements Product {
    public void show() {
        System.out.println("具体产品1显示...");
    }
}
//具体产品2:实现形象产品中的形象办法
class ConcreteProduct2 implements Product {
    public void show() {
        System.out.println("具体产品2显示...");
    }
}
//形象工厂:提供了厂品的生成办法
interface AbstractFactory {
    public Product newProduct();
}
//具体工厂1:实现了厂品的生成办法
class ConcreteFactory1 implements AbstractFactory {
    public Product newProduct() {
        System.out.println("具体工厂1生成-->具体产品1...");
        return new ConcreteProduct1();
    }
}
//具体工厂2:实现了厂品的生成办法
class ConcreteFactory2 implements AbstractFactory {
    public Product newProduct() {
        System.out.println("具体工厂2生成-->具体产品2...");
        return new ConcreteProduct2();
    }
}
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
/**
 * @author hz
 * @version 1.0
 */
public class ReadXML {
    //该办法用于从XML配置文件中提取具体类类名,并返回一个实例对象
    public static Object getObject() {
        try {
            //创立文档对象
            DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dFactory.newDocumentBuilder();
            Document doc;
            doc = builder.parse(new File("src/FactoryMethod/config1.xml"));
            //获取蕴含类名的文本节点
            NodeList nl = doc.getElementsByTagName("className");
            Node classNode = nl.item(0).getFirstChild();
            String cName = "FactoryMethod." + classNode.getNodeValue();
            //System.out.println("新类名:"+cName);
            //通过类名生成实例对象并将其返回
            Class c = Class.forName(cName);
            Object obj = c.newInstance();
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}

那么该模式有哪些优缺点呢?

长处:
  • 用户只须要晓得具体工厂的名称就可失去所要的产品,毋庸晓得产品的具体创立过程。
  • 灵活性加强,对于新产品的创立,只需多写一个相应的工厂类。
  • 典型的解耦框架。高层模块只须要晓得产品的抽象类,毋庸关怀其余实现类,满足迪米特法令、依赖倒置准则和里氏替换准则。
毛病:
  • 类的个数容易过多,减少复杂度
  • 减少了零碎的抽象性和了解难度
  • 形象产品只能生产一种产品,此弊病可应用形象工厂模式解决。

总结:

对于产品种类绝对较少的状况,思考应用简略工厂模式。应用简略工厂模式的客户端只须要传入工厂类的参数,不须要关怀如何创建对象的逻辑,能够很不便地创立所需产品。

对于某个产品,调用者分明地晓得应该应用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来,那么咱们能够采纳工厂办法模式,如JAVA中的Colletion中的iterator() 办法;

或者咱们只是须要一种产品,而不想晓得也不须要晓得到底是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们依据以后零碎的状况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是通明的,咱们也能够选用工厂办法模式。

然而留神当须要生成的产品不多且不会减少,一个具体工厂类就能够实现工作时,可删除形象工厂类。这时工厂办法模式将进化到简略工厂模式。

不论是简略工厂模式还是咱们的工厂办法模式思考的都是一系列雷同类型的产品,如果生产的产品类型不是一个类型,那咱们怎么解决呢,这就须要咱们的工厂模式的另一种模式-形象工厂模式。



推荐阅读
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
author-avatar
额外的房间
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有