设计模式之工厂模式-程序员宅基地

技术标签: 设计模式  工厂模式  

什么是工厂模式?

我们在创建对象时不会对客户端直接暴露创建逻辑,而是 **通过使用一个共同的接口根据不同的条件来指向具体想要创建的对象。**简单来说,我需要某个类的对象,我只需要告诉工厂我需要这个类,工厂就给我返回这个类对象,而创建对象的具体实现由工厂来实现,调用者直接用结果就可以。

工厂模式的优点?

  • 使用工厂模式的优点在于一个调用者想创建一个对象,只要知道其名称(创建该对象的条件)就可以在工厂获取具体的对象

  • 扩展性强,如果想增加一个产品(也就是具体的对象),只要扩展工厂类就可以(也就是增加不同的标签,增加不同标签所对应的对象)。

  • 屏蔽产品的具体实现,调用者只关心能否获得想要的结果,无需关心内部实现

三种工厂模式详解


  • 简单工厂模式

    用工厂模式实现加减法运算器

    //运算器
    public class Operation {
          
       
        public String getName(){
          
            return "";
        }
    }
    
    
    //加法运算器
    public class Add extends Operation {
          
        @Override
        public String getName(){
          
            return "加法";
        }
    }
    
    
    //减法运算器
    public class Sub extends Operation{
          
        @Override
        public String getName(){
          
            return "减法";
        }
    }
    
    
    public class Factory {
          
    
        public static Operation createOperation(String operate){
          
    
    		//运算器
            Operation oper = null;
    
            switch(operate){
          
                case "+":
                    oper = new Add();
                    break;
                case "-":
                    oper = new Sub();
                    break;
            }
            return oper;
        }
    }
    
    //测试
    public class Test {
          
        public static void main(String[] args) {
          
            //创建运算器
            Operation operation;
            //通过入参条件告诉工厂我应该创建的是减法运算器
            operation = Factory.createOperation("-");
            System.out.println(operation.getName());
        }
    }
    
    
    特点
    • 只有一个工厂factory

    • factory类是一个具体的类,非接口/抽象类。有一个重要的create()方法,利用if或者 switch创建产品并返回。

  • create()方法通常是静态的,所以也称之为静态工厂。

缺点
  • 扩展性差(我想增加乘法,除了新增一个乘法类,还需要修改工厂类方法,在switch添加乘法条件)

    • 不同的类需要不同额外参数的时候 不支持。

  • 工厂方法模式

    还是上面那个例子,如果我需要添加乘法和除法功能,势必要添加新的运算类,并且还有修改factory类的create方法。这样是违法开闭原则的。

    我们先定义加减运算为简单运算,乘除运算为复杂运算。

    //定义抽象工厂,所有工厂必须实现该接口
    public interface Factory {
          
        public Operation createOperation(String operate);
    }
    
    
    //复杂运算工厂
    public class ComplexFactory implements Factory {
          
    
        public Operation createOperation(String operate){
          
            Operation oper = null;
            switch(operate){
          
                case "*":
                    oper = new Mul();
                    break;
                case "/":
                    oper = new Div();
                    break;
            }
            return oper;
        }
    }
    
    //简单运算工厂
    public class EasyFactory implements Factory {
          
        public  Operation createOperation(String operate){
          
            Operation oper = null;
            switch(operate){
          
                case "+":
                    oper = new Add();
                    break;
                case "-":
                    oper = new Sub();
                    break;
            }
            return oper;
        }
    }
    
    //定义抽象运算器,所有运算器必须实现该接口
    public interface Operation {
          
        public String getName();
    }
    
    //复杂运算器
    public class ComplexOperation implements Operation {
          
    
        public String getName(){
          
            return "";
        }
    }
    
    //简单运算器
    public class EasyOperation implements Operation {
          
        @Override
        public String getName() {
          
            return "";
        }
    }
    
    //加法运算器
    public class Add extends EasyOperation {
          
        @Override
        public String getName() {
          
            return "加法";
        }
    }
    
    //减法运算器
    public class Sub extends EasyOperation{
          
        @Override
        public String getName() {
          
            return "减法";
        }
    }
    
    //乘法运算器
    public class Mul extends ComplexOperation {
          
    
        @Override
        public String getName() {
          
            return "乘法";
        }
    }
    
    //除法运算器
    public class Div extends ComplexOperation {
          
        @Override
        public String getName() {
          
            return "除法";
        }
    }
    
    
    //测试
    public class Test {
          
        public static void main(String[] args) {
          
    
            //运算器
            Operation operation = null;
    
            //复杂运算工厂
            Factory complexfactory = new ComplexFactory();
    		//简单运算工厂
            Factory easyfactory = new EasyFactory();
    		//通过不同工厂可创建不同的对象实例
            operation = complexfactory.createOperation("*");
            System.out.println(operation.getName());
            
            operation = easyfactory.createOperation("+");
            System.out.println(operation.getName());
    
        }
    }
    
    特点
    • 有多个工厂factory(实现同一工厂接口),有多种产品operation(实现同一产品接口),产品与工厂相对应
    • 扩展性强,添加新的产品需要添加对应的工厂,无需改动原来代码,直接实现产品接口和工厂接口即可

  • 抽象工厂模式

    在工厂方法模式中,产品种类是单一的,比如上面的例子,运算只是基本的四则运算,如果涉及到对象与对象之间的运算呢?这就不是简单的四则运算了,抽象方法模式就针对多种产品。
    在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_45638407/article/details/100864018

智能推荐

jax-ws和jax-rs_使用JAX-RS和Spring构建HATEOAS API-程序员宅基地

文章浏览阅读119次。jax-ws和jax-rs 在我以前的博客文章中,我展示了如何使用Spring Boot配置Jersey多么容易。 我对Spring Boot和Jersey的探索并未结束,我研究了在Spring Boot应用程序中将Spring HATEOAS与Jersey一起使用的可能性。 Spring HATEOS允许创建遵循HATEOAS原理的REST表示形式,并且(截至撰写本文时)具有使用链接的基本J..._jax.ws.rs demo

Ubuntu新手入门全攻略_ub社区怎么进-程序员宅基地

文章浏览阅读10w+次,点赞48次,收藏523次。Ubuntu可以说是Linux系统的一面旗帜,相比于大多数发行版,美观易用,具有强大的社区支持,因而也成为了新手入门Linux系统的一个不错选择(再深入点的CentOS之类的就另说了)。笔者在尝试Ubuntu系统的时候遇到了若干问题花了一些时间才解决,本文主要讲解这些Ubuntu入门可能会遇到的问题,有深有浅,欢迎批评指正。_ub社区怎么进

智慧美业系统v6.4.0 营销 O2O 美容_智慧美业系统源码-程序员宅基地

文章浏览阅读214次。【优化】小程序端商品显示。【优化】收银端数据显示。_智慧美业系统源码

定义一个数组,输出数组中的最大值_创建一维数组arr[],将数组中最大的元素输出-程序员宅基地

文章浏览阅读1.1k次。输出数组最大值_创建一维数组arr[],将数组中最大的元素输出

通俗解释 方差,标准差,协方差以及相关系数_方差大白话解释-程序员宅基地

文章浏览阅读1.1w次,点赞16次,收藏29次。本文转载自:http://blog.csdn.net/yangdashi888/article/details/52397990 https://www.zhihu.com/question/208520041、方差,标准差定义 很显然,均值描述的是样本集合的中间点,它告诉我们的信息是很有限的,而标准差给我们描述的则是样本集合的各个样本点到均值的距离之平均。以这两个集_方差大白话解释

Java集合之aHshset_javahdt-程序员宅基地

文章浏览阅读187次。【代码】上周讲课的总结。_javahdt

随便推点

Ubuntu16.04安装CodeChecker及CodeChecker服务器的配置_ubuntu codechecker-程序员宅基地

文章浏览阅读1.3k次。Ubuntu安装CodeChecker首先环境使用的是Ubuntu16.04发行版其自带的python版本为3.5,gcc版本为5CodeChecker需要python版本>=3.6经过实验,发现Ubuntu版本过低时,如果不能按照如下方法使用apt直接安装python,那么需要使用gcc对python源码进行进行编译安装。此时gcc版本应至少>=5。否则无法对python进行编译安装(至少gcc4.8.1不行)因此如果需要gcc降级,那么务必在安装CodeChecker安装结束后再_ubuntu codechecker

3.Mapper.xml 详解-程序员宅基地

文章浏览阅读1.6w次,点赞12次,收藏108次。文章目录Mapper.xml 详解1. parameterType2. resultType3. 级联查询3.1 一对多3.2 多对多Mapper.xml 详解MyBatis 主要有两个的配置文件:config.xml 和 Mapper.xml,这两个配置文件可以自定义文件名。config.xml 是全局配置文件,主要配置 MyBatis 的数据源(DataSource),事务管理(TransactionManager)以及打印 SQL 语句,开启二级缓存,注册 Mapper.xml 等。Map_mapper.xml

ensp提示抓包工具wireshark配置路径不正确_ensp抓包工具wireshark配置路径不正确-程序员宅基地

文章浏览阅读2.4w次,点赞30次,收藏61次。太久没有使用模拟器,今天突然打不开抓包工具了,莫慌,马上上解决方法。出现这个问题的原因可能是因为各位老铁们在升级软件的时候位置变了,或者是先安装了ensp后面才安装的wireshark。解决方法:单击 eNSP的菜单 - 工具 - 选项 - 工具设置,在引用工具里面 设置你安装的 wireshark 路径。有的老铁可能已经忘记了安装路径,这边告知大家如何找到安装路径,先找到电脑里面的wireshark请注意看一下是不是真实的安装路径如果不是请同理选中快捷方式右键选中打开文件所在位置下_ensp抓包工具wireshark配置路径不正确

全网疯传,阿里 P8 技术官的架构笔记外泄:微服务分布式架构实践手册_阿里p8分布式架构笔记-程序员宅基地

文章浏览阅读132次。阿里 P8 大佬的架构笔记:微服务分布式架构实践手册从企业的真实需求出发,理论结合实际,深入讲解 Spring Cloud 微服务和分布式系统的知识。_阿里p8分布式架构笔记

宏基台式计算机编号,ACER如何查询型号名称序列号SNID?-程序员宅基地

文章浏览阅读5.5k次。本帖最后由 fs_2010 于 2012-10-6 21:58 编辑Ps:一年一度的国庆,如今的国庆长假都过了一大半,也相信友友们买到了算了心中的一台本本了,一刚刚开始购买的时候,有许多的方方面面的东西都没有注意到多少,当时在估计也就是为这一个价格而下手的,哪一台本本到手了之后,怎么才能让自己安下心来使用呢?怎么查看出厂日期的?还有保修方面的等等原因……所以提供一点点的信息,让猿们参考参考、、、注..._查看snid

Matlab导出图片模糊的解决办法_matlab画出的三维图,在保存到latex的时候,将渲染器改为painters后为什么图中的虚-程序员宅基地

文章浏览阅读4.3w次,点赞34次,收藏48次。问题描述之前发现,Matlab画图如果figure内的线条过多,或者散点过多,导出的图片会模糊,且图片并非矢量图。试过eps和pdf格式,均是非常模糊,而且用编辑器直接打开eps文本可见大段乱码。解决方案解决方法就在于figure的导出设置中。在设置的渲染选项中,渲染器有两个,分别为painters和OpenGL,分别为矢量格式输出和位图输出。默认情况下,Matlab会..._matlab画出的三维图,在保存到latex的时候,将渲染器改为painters后为什么图中的虚