百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

「设计模式」简单工厂、工厂方法、抽象工厂模式一篇文章就能学会

liebian365 2024-10-21 08:46 24 浏览 0 评论

一、什么是工厂模式

1.概念

工厂模式的设计思想是提供一个工厂,这个工厂会将我们想要的对象实例做出一定的规范化,也省去了创建这个类的麻烦。

2.跟构建者模式的区别

构建者模式是针对「一个类」,而工厂模式则针对「多个类」(实现同一个接口的) 构建者模式是「向类的构造方法传入一个对象进行创建」的,工厂模式是直接「创建一个对象」,当然工厂模式内部也可以套用构建者模式来简化对象的创建。

3.工厂模式的使用场景

  1. 「有很多类似的类,但我们只需要其中的一个」。像MyBatis中的日志工厂,日志类有很多,但是我们之需要一个,MyBatis的日志工厂就会根据我们的需求来创建日志类实例,或者创建默认日志类实例。
  2. 「创建过程比较麻烦」

4.优点

  1. 「扩展性高」。像创建新的类,直接创建新的工厂即可。
  2. 「使创建过程透明化」。在使用工厂时,不需要考虑它的创建过程,直接使用即可。

5.缺点

  1. 「工厂的创建步骤麻烦」
  2. 「增加系统的复杂度」。创建个对象绕来绕去,头都晕了。
  3. 「依赖性过高」。每个工厂和对应的类之间依赖性太高了,修改一个类,也要修改工厂。创建一个类,也要创建一个工厂。

6.原则

“+”代表遵守,“-”代表不遵守或者不相关

原则 开放封闭 单一职责 迪米特 里氏替换 依赖倒置 接口隔离 合成复用 + + + - + + -

二、工厂模式的分类

1.简单工厂

「概念」

简单工厂就比较简单了,它并没有一个类对应一个工厂,而是都「由一个工厂来控制类的创建」

「代码」

package factory;

/**
 * @author xxj
 * 简单工厂
 */
public class SimpleFactory {
    public Car create(String car){
        if (car=="BENZ"){
            return new BENZCar();
        }else if (car=="BMW"){
            return new BMWCar();
        }else {
            return null;
        }
    }
    public class BENZCar implements Car{
        @Override
        public void draw() {
            System.out.println("BENZ在跑");
        }
    }
    public class BMWCar implements Car{

        @Override
        public void draw() {
            System.out.println("BMW在跑");
        }
    }
    /**
     * 车接口
     */
    public interface Car{
        void draw();
    }
}

「特点」

首先,需要「创建」一个所有实现类都要实现的「接口类」,然后让所有实现类「实现这个接口类」,最后,「创建一个工厂类」,这个工厂类「提供一个创建方法」,根据传入的参数进行「创建实现类」

可以看出,简单工厂的业务逻辑都集中在create方法中,这就「不利于扩展」,而且会使「业务逻辑」越来越「复杂」

2.工厂方法

「概念」

工厂方法是一个类对应一个工厂,不再是通过一个工厂类来控制类的实例化。

「代码」

package factory;

/**
 * @author xxj
 * 工厂方法
 */
public class MethodFactory {
    public interface Car{
        void draw();
    }
    public interface fatory{
       Car create();
    }
    
    public class BMWCar implements Car{
        @Override
        public void draw() {
            System.out.println("BMW在跑");
        }
    }
    public class BENZCar implements Car{
        @Override
        public void draw() {
            System.out.println("BENZ在跑");
        }
    }
    public class BMWFactory implements fatory{
        @Override
        public Car create() {
            return new BMWCar();
        }
    }
    public class BENZFactory implements fatory{
        @Override
        public Car create() {
            return new BENZCar();
        }
    }
}

「特点」

「首先」,需要「创建两个接口」,一个是「目标类的接口」,一个是「工厂类的接口」「然后」「实现这两个接口」「工厂类」需要有「一个」完成创建并「返回一个目标类实例方法」。 如果是只有一个目标类的话,可以不使用接口,直接创建目标类和接口类即可。

可以看出,这个是「一个工厂对应一个目标类」「创建」的步骤「比较繁琐」,每添加一个目标类,就要手动的去创建一个工厂,但是它「降低了系统的复杂度」,不需要将判断创建那个工厂的逻辑全部放在一个工厂里,「提高了扩展性」,可以通过不断地实现目标类和工厂类的接口实现扩展。

和简单工厂的区别是:工厂方法是通过不同的方法来创建对象的,而简单工厂则是通过不同的参数在一个方法来创建对象

3.抽象工厂

「概念」

一般情况下,在需要「一个工厂创建特别多的目标类」时,就可以使用抽象工厂了。 和工厂方法的区别是:「工厂方法」「一个工厂类对应一个目标类」「抽象工厂」「一个工厂类对应多个目标类」

「代码」

package factory;

/**
 * @author xxj
 * 抽象工厂
 */
public class AbstractFactory {
    public interface Pants{
        int size=0;
        
    }
    public interface Clothes{
        int size=0;
    }
    public interface fatory{
        Pants createPants();
        Clothes createClothes();
    }
    public class XPants implements Pants{
    }
    public class XClothes implements Clothes{
    }
    public class XFactory implements fatory{
        @Override
        public Pants createPants() {
            return new XPants();
        }
        @Override
        public Clothes createClothes() {
            return new XClothes();
        }
    }
}

「特点」

首先,需要「创建一个工厂接口和多个目标类接口」,然后分别实现这些接口,「工厂类」则需要「有多个目标类的创建方法」

这里的工厂接口严格一点的应该是「工厂抽象类」,又涉及到接口和抽象类的区别了,我也不是很懂,有空再学习一下。

抽象工厂的「扩展性」比工厂方法的「更高」了,但是「步骤」也是「更加繁琐」了,如果不是有特别多目标类,就不需要考虑抽象工厂了,这也比较适合规模比较大的架构来使用。

三、总结

目标类和工厂类可以组成一个x(目标类)y(工厂类)轴,这里的一个工厂类可以看成一个派系的类都需要在这个工厂类创建。 当x=1,y=1时,就不要考虑工厂模式了。 当「1<x,y=1」时,就优先考虑「简单工厂」。 当「x=1,1<y」时,就优先考虑「工厂方法」。 当「1<x,1<y」时,就优先考虑「抽象工厂」

相关推荐

4万多吨豪华游轮遇险 竟是因为这个原因……

(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...

“菜鸟黑客”必用兵器之“渗透测试篇二”

"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...

科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白

作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...

麦子陪你做作业(二):KEGG通路数据库的正确打开姿势

作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...

知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势

智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...

每日新闻播报(September 14)_每日新闻播报英文

AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...

香港新巴城巴开放实时到站数据 供科技界研发使用

中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...

5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper

本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...

Qt动画效果展示_qt显示图片

今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...

如何从0到1设计实现一门自己的脚本语言

作者:dong...

三年级语文上册 仿写句子 需要的直接下载打印吧

描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...

C++|那些一看就很简洁、优雅、经典的小代码段

目录0等概率随机洗牌:1大小写转换2字符串复制...

二年级上册语文必考句子仿写,家长打印,孩子照着练

二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...

一年级语文上 句子专项练习(可打印)

...

亲自上阵!C++ 大佬深度“剧透”:C++26 将如何在代码生成上对抗 Rust?

...

取消回复欢迎 发表评论: