设计模式之工厂模式(Factory)

news2024/11/26 0:48:13

任何可以产生对象的方法或类,都可以称为工厂。

下面的代码定义了Car这种交通工具:

public class Car {
    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}

然后在main函数里面想要调用调用Car的go方法,就需要new一个car对象,然后调用

public class Main {
    public static void main(String[] args) {
        Car m = new Car();
        m.go();
    }
}

如果又来了一个飞机,你想开飞机,又得在main函数里面,new一个Plane

public class Plane {
    public void go() {
        System.out.println("plane flying shushua....");
    }
}
public class Main {
    public static void main(String[] args) {
        // Car m = new Car();
        Plane m = new Plane();
        m.go();
    }
}

main函数的逻辑会改来改去

可以引入接口,简单多态的应用,car和plane都去实现Moveable这个接口

public interface Moveable {
    void go();
}
public class Car implements  Moveable {
    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}
public class Plane implements Moveable {
    public void go() {
        System.out.println("plane flying shushua....");
    }
}
public class Main {
    public static void main(String[] args) {
        Moveable m = new Car(); // 简单多态应用
        m.go();
    }
}

通过实现Moveable接口,做到了可以任意定制各种交通工具,只需要实现Moveable接口就行

1.简单工厂 工厂方法(Factory Method) --> 每种产品都对应一个工厂
创建一个工厂类,里面生产Car,Plane和Broom,可扩展性不好,有新的交通工具都得加,要定制的话,
所有的代码都写到了一个类里面

/**
 * 简单工厂的可扩展性不好
 */
public class SimpleVehicleFactory {
    public Car createCar() {
        //before processing 可以加一些前置操作
        return new Car();
    }

    public Broom createBroom() {
        return new Broom();
    }

    // Plane...
}

可以给Car,Plane分别创建工厂,每个工厂里面可以做任意的定制,代码隔离开了 --> 通过xxxFactory做到了任意定制生产过程

public class CarFactory {
    public Moveable create() {
        System.out.println("a car created!");
        return new Car();
    }
}
public static void main(String[] args) {
    Moveable m = new CarFactory().create();
    m.go();
}

2.静态工厂
单例也是一种工厂,也被人称为静态工厂。

4.抽象工厂
如何任意扩展产品族?

public class Car{

    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}
public class AK47 {
    public void shoot() {
        System.out.println("tututututu....");
    }
}
public class Bread {
    public void printName() {
        System.out.println("wdm");
    }
}

有个人开着Car,拿着AK47,tututu,还吃着面包,客户端代码(使用这些类的代码),可能会像下面这样写,但是
如果来了一个人是魔法世界的人,骑得是扫帚,武器是魔法棒,吃的是蘑菇,你的客户端代码就又得重新写
Car,AK47,面包,是一个产品族
扫帚,魔法棒,蘑菇又是一个产品族
有没有一种方法,可以任意选择产品族,客户端代码不用改? --> 抽象工厂

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.go();
        AK47 ak47 = new AK47();
        ak47.shoot();
        Bread bread = new Bread();
        bread.printName();
    }
}

定义一个抽象工厂类: AbastractFactory可以生产一些列的产品,Food Vehicle Weapon

public abstract class AbastractFactory {
    abstract Food createFood();
    abstract Vehicle createVehicle();
    abstract Weapon createWeapon();
}

定义三个抽象类:

//交通工具
public abstract class Vehicle { //interface
    abstract void go();
}
//武器
public abstract class Weapon {
    abstract void shoot();
}
//食物
public abstract class Food {
   abstract void printName();
}

Car,AK47,Bread分别实现上面的抽象类

public class Car extends Vehicle{

    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}
public class AK47 extends Weapon{
    public void shoot() {
        System.out.println("tututututu....");
    }
}
public class Bread extends Food{
    public void printName() {
        System.out.println("wdm");
    }
}

Broom,MagicStick,MushRoom分别实现上面的抽象类

public class Broom extends Vehicle{
    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}
public class MagicStick extends Weapon{
    public void shoot() {
        System.out.println("diandian....");
    }
}
public class MushRoom extends Food{
    public void printName() {
        System.out.println("dmg");
    }
}

定义具体的ModernFactory:

public class ModernFactory extends AbastractFactory {
    @Override
    Food createFood() {
        return new Bread();
    }

    @Override
    Vehicle createVehicle() {
        return new Car();
    }

    @Override
    Weapon createWeapon() {
        return new AK47();
    }
}

定义具体的MagicFactory:

public class MagicFactory extends AbastractFactory {
    @Override
    Food createFood() {
        return new MushRoom();
    }

    @Override
    Vehicle createVehicle() {
        return new Broom();
    }

    @Override
    Weapon createWeapon() {
        return new MagicStick();
    }
}

AbastractFactory可以生产一些列的产品,Food Vehicle Weapon
定义一个ModernFactory,继承自AbastractFactory,现代的工厂可以生产Car,AK47,Bread(分别继承自Vehicle Weapon Food)
定义一个MagicFactory,也继承自AbastractFactory,魔法工厂可以生产Broom,MagicStick,MushRoom(分别继承自Vehicle Weapon Food)

一共有:抽象的工厂,具体的工厂,抽象的产品,具体的产品
在这里插入图片描述
在Main方法里面就只需要创建具体的工厂,然后调用方法就行,不用像之前,创建各种不同的对象之后再调用对应的方法:

public class Main {
    public static void main(String[] args) {
        AbastractFactory f = new ModernFactory(); // 如果是魔法世界的人,只需要该这一行代码就行,new MagicFactory(),非常方便

        Vehicle c = f.createVehicle();
        c.go();
        Weapon w = f.createWeapon();
        w.shoot();
        Food b = f.createFood();
        b.printName();
    }
}

探讨: 这里Vehicle类,用的是抽象类,只有一个抽象方法,是不是用接口也行?就像前面的Moveable一样? --> 形容词用接口,名词用抽象类

工厂方法和抽象工厂比较:
工厂方法方便在产品上进行扩展,有新的产品来了,只需要加新的xxxFactory就行,如果想要加新的族,就比较麻烦
如果是产品一族上进行扩展,抽象工厂就比较方便,只需要加具体的工厂就行(例如加火星工厂),但是要加的产品就比较麻烦,抽象工厂得加方法,具体工厂也得加方法
例如要加衣服这个产品,就需要在抽象工厂里面加creat衣服的方法,后面的具体工厂也得加

工厂方法: 添加产品维度方便
抽象工厂: 产品一族扩展方便

有没有一种方法,加新的产品和扩展一族产品比较方便呢? --> Spring bean 工厂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1177894.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Netty入门指南之传统通信的问题

作者简介:☕️大家好,我是Aomsir,一个爱折腾的开发者! 个人主页:Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客 当前专栏:Netty应用专栏_Aomsir的博客-CSDN博客 文章目录 参考文献前言多线程…

管理类联考——写作——技巧篇——书写标点符号使用要求规范文档

写作答题卡书写标点符号使用要求规范文档 常用标点符号有逗号、句号、叹号、问号等 11 种,下面一一列举其用法和书写规范。 一、句号 用法:用于陈述句的末尾。 占格情况:占一格,写在格子左下方。 举例: 我看见妈妈走…

web3案例中解决交易所中 ETH与token都是0问题 并帮助确认展示是否成功

可能写了这么久 很多人会发现一个问 我们前面的案例 个人在交易所中的 自定义token 和 ETH 一直是放了个0 大家也不太敢确认是否真的有效 那么 很简单 我们操作 存入一些进交易所 不就ok了 我们 来看之前交易所写的代码 我们写了 depositEther 存入 ETH 和 depositToken 存入…

03 贝尔曼公式

贝尔曼公式 前言1、Motivating examples2、state value3、Bellman equation:Derivation4、Bellman equation:Matrix-vector form4、Bellman equation:Solve the state value5、Action value 前言 本文来自西湖大学赵世钰老师的B站视频。本节课主要介绍贝尔曼公式。 本节课概要…

海外问卷项目是怎么赚钱的?

大家好,我是橙河老师,今天聊一聊海外问卷项目是怎么赚钱的? 在海外国家,问卷调查这种商业模式一直都很流行,很多商业公司为了收集消费者的意见,会对外发有偿的调查问卷,从最开始的纸质调查&…

MySQL第五讲·关于外键和连接, 如何做到关联查询?

你好,我是安然无虞。 文章目录 外键和连接:如何做关联查询?如何创建外键?连接关联查询中的误区 外键和连接:如何做关联查询? 在实际的数据库应用开发过程中,我们经常需要把2个或2个以上的表进…

C语言函数初使用

目录 1知识点: 2一个小代码,后续知识点讲解: 3知识点: 定义函数 实例 函数声明 调用函数 函数参数 4总结: 1知识点: 函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,…

网站源码备份 [极客大挑战 2019]PHP1

打开题目 题目提示我们备份网站 我们输入/www.zip 下载zip文件&#xff0c;打开发现 打开index.php <?phpinclude class.php;$select $_GET[select];$resunserialize($select);?> 文件包含class.php&#xff0c;get传参一个select函数&#xff0c;反序列化select参…

HMM与LTP词性标注之命名实体识别与HMM

文章目录 知识图谱介绍NLP应用场景知识图谱&#xff08;Neo4j演示&#xff09;命名实体识别模型架构讲解HMM与CRFHMM五大要素&#xff08;两大状态与三大概率&#xff09;HMM案例分享HMM实体识别应用场景代码实现 知识图谱介绍 NLP应用场景 图谱的本质&#xff0c;就是把自然…

JS逆向爬虫---请求参数加密②【某麦数据analysis参数加密】

主页链接: https://www.qimai.cn/rank analysis逆向 完整参数生成代码如下&#xff1a; const {JSDOM} require(jsdom) const dom new JSDOM(<!DOCTYPE html><p>hello</p>) window dom.windowfunction customDecrypt(n, t) {t t || generateKey(); //…

ZZULIOJ 1108: 打印数字图形(函数专题) (C/C++)

1108: 打印数字图形&#xff08;函数专题&#xff09; 题目描述 从键盘输入一个整数n(1≤n≤9),打印出指定的数字图形。要求在程序中定义并调用如下函数&#xff1a;PrintSpace(m)用来输出m个空格&#xff1b;PrintDigit(m)来输出一行中的数字串"12…m…21"&#xff…

element树形结构下拉组件组装对应格式数据

element树形结构下拉组件组装对应格式数据 <el-row><el-col :span"24"><el-form-item label"购买渠道" prop"treeData" class"grid-content bg-purple"><el-cascaderv-model"testForm.treeData":optio…

鳄鱼指标的3颜色线都代表什么?澳福官网一段话明白了

投资者一直在使用鳄鱼指标进行交易&#xff0c;但是对指标上面的3种颜色的K线都代表什么不明白&#xff1f;直到看到澳福官网一段话才明白&#xff0c;原来这么简单&#xff01; 鳄鱼指标&#xff0c;这一工具是由三条移动平均线组合而成。具体来说&#xff0c;蓝线&#xff0…

8-3、T型加减速单片机程序【51单片机控制步进电机-TB6600系列】

摘要&#xff1a;根据前两节内容&#xff0c;已完成所有计算工作&#xff0c;本节内容介绍具体单片机程序流程及代码 一、程序流程图 根据前两节文章内容可知&#xff0c;T型加减速的关键内容是运动类型的判断以及定时器初值的计算&#xff0c;在输出运动参数后即可判断出运动…

前端代码优化小技巧

导读 今天分享一下开测前端代码的一些优化&#xff0c;及使用的一些小技巧&#xff0c;来优化我们的网站&#xff0c;前端开发中最常见的问题就是很少使用ES6方法导致代码冗余&#xff0c;不够清晰&#xff0c;定时器和闭包导致内存溢出及泄露,网站中css导致排版错乱&#xff…

C++基础——对于C语言缺点的补充(2)

上篇文章中说到&#xff0c;为了解决C语言会出现人为定义的函数和库函数出现重定义的错误&#xff0c;C引入了一个新的概念&#xff0c;即命名空间&#xff0c;通过认为定义命名空间&#xff0c;来解决上述问题。 在本篇文章中&#xff0c;将继续介绍C相对于C语言不足来进行的补…

linux之信号

Linux之信号 什么是信号信号的产生方式signalsignactionkill信号集信号屏蔽 什么是信号 信号机制是一种使用信号来进行进程之间传递消息的方法&#xff0c;信号的全称为软中断信号&#xff0c;简称软中断。 信号的本质是软件层次上对中断的一种模拟&#xff08;软中断&#xff…

Hello Qt!

目录 1. 什么是Qt 2. Qt中的模块 3. 下载安装 4. QtCreator 4. Hello Qt 解释 .pro 解释 main.cpp 解释 mainwindow.ui 解释 mainwindow.h 解释 mainwindow.cpp 5. Qt 中的窗口类 5.1 基础窗口类 5.2 窗口的显示 6. Qt 的坐标体系 7. 内存回收 1. 什么是Qt 是一…

✔ ★【备战实习(面经+项目+算法)】 11.6 学习

✔ ★【备战实习&#xff08;面经项目算法&#xff09;】 坚持完成每天必做如何找到好工作1. 科学的学习方法&#xff08;专注&#xff01;效率&#xff01;记忆&#xff01;心流&#xff01;&#xff09;2. 每天认真完成必做项&#xff0c;踏实学习技术 认真完成每天必做&…

【斗破年番】萧炎给彩鳞承诺遭删,熏儿限时返场,古河沦为打工人

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析国漫资讯。 深度爆料&#xff0c;在斗破年番69话的最新剧情中&#xff0c;一场感人至深的情感戏份被删减了。在原著中&#xff0c;萧炎曾向美杜莎承诺&#xff0c;他会集齐材料&#xff0c;为她炼制出天雁九行翼。然而&a…