设计模式之---工厂模式

设计模式–工厂模式

一 什么是工厂模式

使用工厂模式是为了将创建对象的具体过程屏蔽隔离起来 快速的将对象实例化 从而提高了代码的灵活性和改善了简洁性,工厂模式具体分为以下三类:

1 简单工厂模式(Simple Factory)

2 工厂方法模式(Factory Method)

3 抽象工厂模式(Abstract Factory)

三种模式从上到下逐渐变得抽象,但主要可以分为工厂方法模式和抽象工厂模式,而简单工厂模式则可以看为工厂方法模式中一个特别的案例,两者归为一类,我们先举一个例子对工厂模式做一个初步的了解

1 从前世上并没有工厂,如果客户想要一辆大众车,则需要为客户制造一辆大众车

2 简单工厂模式: 后来出现了工厂,用户不需要再去制造大众车,由工厂进行制造,想要什么车直接发给工厂制造就可以了,比如要制造帕萨特系列的车,工厂就制造这个系列的车

3 工厂方法模式:为了满足客户的需求,大众车的系列越来越多,如帕萨特,高尔夫等系列,一个工厂只能制造一个系列,所以又分为多个制造不同系列的工厂,每个具体工厂制造一个系列的车,但是大众工厂只是一个抽象的,你还需要实现具体的工厂才可以制造对应系列的车辆

4 抽象工厂模式:随着客户的要求越来越高,大众车必须配置显示屏,于是这个工厂开始生产对应系列的显示屏的车,最终客户只需要说:我想要配备小米显示屏的大众车,工厂就直接生产相应的车辆了。

下面针对几种不同的工厂模式进行详细的说明:

二 简单工厂模式

简单工厂模式的核心是定义一个创建对象的接口,将对象的创建和本身的业务逻辑分离,降低系统的耦合度,使得两个修改起来相对容易些,当以后实现改变时,只需要修改工厂类即可。

代码实现:

动物类:

public class Animal {
    public Animal(){}
}

class Cat extends Animal{
    public Cat(){
        System.out.println("您领养了一只猫");
    }
}

class Dog extends Animal{
    public Dog(){
        System.out.println("您领养了一只狗");
    }
}

class Tiger extends Animal{
    public Tiger(){
        System.out.println("您领养了一只老虎");
    }
}


一只老虎");
    }
}

工厂类:

public class AnimalFactory {
    public Animal createAnimal(String animal){
        switch (animal){
            case "dog":
                return new Dog();
            case "cat":
                return new Cat();
            case "tiger":
                return new Tiger();
                default:
                    break;
        }
        return null;
    }
//用户端
    public static void main(String[] args) {
        AnimalFactory af = new AnimalFactory();
        Animal dog = af.createAnimal("dog");
        Animal cat = af.createAnimal("cat");
        Animal tiger = af.createAnimal("tiger");
    }
}


三 工厂方法模式

工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。
但缺点在于,每增加一个产品都需要增加一个具体产品类和实现工厂类,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

代码实现:

动物类:

public class Animal {
    public Animal(){}
}

class Cat extends Animal{
    public Cat(){
        System.out.println("您领养了一只猫");
    }
}

class Dog extends Animal{
    public Dog(){
        System.out.println("您领养了一只狗");
    }
}

class Tiger extends Animal{
    public Tiger(){
        System.out.println("您领养了一只老虎");
    }
}



工厂类:

public interface AnimalFactory {
    Animal createAnimal();
}

class CatFactory implements AnimalFactory{
    @Override
    public Animal createAnimal() {
        return new Cat();
    }
}

class DogFactory implements AnimalFactory{
    @Override
    public Animal createAnimal() {
        return new Dog();
    }
}

class TigerFactory implements AnimalFactory{
    @Override
    public Animal createAnimal() {
        return new Tiger();
    }
}

客户类:

public class Customer {
    public static void main(String[] args) {
        CatFactory catFactory = new CatFactory();
        catFactory.createAnimal();
        DogFactory dogFactory = new DogFactory();
        dogFactory.createAnimal();
    }
}

四 抽象工厂模式

在工厂方法模式中,我们使用一个工厂创建一个产品,一个具体工厂对应一个具体产品,但有时候我们需要一个工厂能够提供多个产品对象,而不是单一的对象,这个时候我们就需要使用抽象工厂模式。
在介绍抽象工厂模式前,我们先厘清两个概念:

产品等级结构:产品等级结构指的是产品的继承结构,比如一个狗粮抽象类,它有A品牌狗粮、B品牌狗粮等一系列的子类,那么这个狗粮抽象类和他的子类就构成了一个产品等级结构。
产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。比如,狗咖生产狗粮和狗绳,那么狗狗粮则位于狗粮产品族中。

什么是抽象工厂模式?

抽象工厂模式主要用于创建相关对象的家族。当一个产品族中需要被设计在一起工作时,通过抽象工厂模式,能够保证客户端始终只使用同一个产品族中的对象;并且通过隔离具体类的生成,使得客户端不需要明确指定具体生成类;所有的具体工厂都实现了抽象工厂中定义的公共接口,因此只需要改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
但该模式的缺点在于添加新的行为时比较麻烦,如果需要添加一个新产品族对象时,需要更改接口及其下所有子类,这必然会带来很大的麻烦。

代码实现:

产品类:

public interface Food {
}

class DogFood implements Food{
    public DogFood(){
        System.out.println("生产狗粮");
    }
}

class CatFood implements Food{
    public CatFood(){
        System.out.println("生产猫粮");
    }
}
interface Tool{

}

class DogTool implements Tool{
    public DogTool(){
        System.out.println("生产养狗工具");
    }
}

class CatTool implements Tool{
    public CatTool(){
        System.out.println("生产养猫工具");
    }
}

工厂类:

public interface AnimalFactory {
    public Food createFood();
    public Tool createTool();
}

class CatFactory implements AnimalFactory{
    @Override
    public Food createFood() {
        return new CatFood();
    }

    @Override
    public Tool createTool() {
        return new CatTool();
    }
}

class DogFactory implements AnimalFactory{
    @Override
    public Food createFood() {
        return new DogFood();
    }

    @Override
    public Tool createTool() {
        return new DogTool();
    }
}

用户类:

public class Customer {
    public static void main(String[] args) {
        CatFactory catFactory = new CatFactory();
        catFactory.createFood();
        catFactory.createTool();
        DogFactory dogFactory = new DogFactory();
        dogFactory.createFood();
        dogFactory.createTool();
    }
}

五 工厂模式小结

工厂方法模式与抽象方法模式的区别在于:

  • 工厂方法模式只有一个抽象产品类和抽象工厂类,但可以派生出许多具体的产品类和工厂类,每个具体的产品类和工厂类只能创建一个具体的实例

  • 抽象工厂模式具有多个抽象产品类和一个抽象工厂类,每个抽象产品类可以派生出来多个具体的产品类,抽象工厂类也可以派生出许多个具体的工厂类,同时每个具体的工厂类也可以创建出多个产品类的实例

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

打破常规,BD仓储物流的效能提升!

当前,随着国家战略的推进,JS与民用领域的融合不断加深,物流业也步入了军民融合的新时代。在智能仓储物流方面,JS物流的智能化进展受到了BD系统的高度关注和重视。 一、建设JS仓储物流RFID基础设施 JS物流领域引入RFID技术的基础工…

MySQL表的基本查询上

1,创建表 前面基础的文章已经讲了很多啦,直接上操作: 非常简单!下一个! 2,插入数据 1,全列插入 前面也说很多了,直接上操作: 以上插入和全列插入类似,全列…

概率 期望与方差

一、期望 1、定义 对随机变量可能取值的加权平均,其中权重是每个可能取值的概率。用E表示,如x是随机变量,则该期望为EX 2、离散型随机变量的期望 对于离散随机变量 X ,其可能的取值为 x1,x2,…,xn,对应的概率为 E(X)…

MOS管的电路应用

MOS管的电路应用 MOS管的选型参考 1、MOS管类型 一般选择增强型NMOS管,同等工艺条件下,导通电阻Ron更小,发热更低,允许通过的电流更大,型号也更多。 2、Vgs电压 需要考虑开启电压,驱动电压,极…

基于WebSocket实现简易即时通讯功能

代码实现 pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifa…

SQL 干货 | 使用 Having 子句筛选聚合字段

如果你编写 SQL 查询已有一段时间&#xff0c;那么你可能对 WHERE 子句非常熟悉。虽然它对聚合字段没有影响&#xff0c;但有一种方法可以根据聚合值过滤记录&#xff0c;那就是使用 HAVING 子句。本博客将介绍它的工作原理&#xff0c;并提供几个在 SELECT 查询中使用它的示例…

Redis-缓存一致性

缓存双写一致性 更新策略探讨 面试题 缓存设计要求 缓存分类&#xff1a; 只读缓存&#xff1a;&#xff08;脚本批量写入&#xff0c;canal 等&#xff09;读写缓存 同步直写&#xff1a;vip数据等即时数据异步缓写&#xff1a;允许延时&#xff08;仓库&#xff0c;物流&a…

C语言练习

题目&#xff1a; 1.编写一段C语言&#xff0c;向下边这样输入2个整数&#xff0c;如果他们的差值小于等于10&#xff0c;则显示“它们的差值小于等于10”&#xff0c;否则显示“它们的差大于等于11”. 请输入两个整数&#xff1a; 整数A&#xff1a;12 整数B&#xff1a;7…

SQL分类中的DDL

DDL&#xff08;Data Definition Language):数据定义语言&#xff0c;用来定义数据库对象&#xff08;数据库&#xff0c;表&#xff0c;字段&#xff09;。 一、DDL语句操作数据库 1、查询所有数据库&#xff1a;show databases&#xff1b;&#xff08;一般用大写&#xff…

spring |Spring Security安全框架 —— 认证流程实现

文章目录 开头简介环境搭建入门使用1、认证1、实体类2、Controller层3、Service层3.1、接口3.2、实现类3.3、实现类&#xff1a;UserDetailsServiceImpl 4、Mapper层3、自定义token认证filter 注意事项小结 开头 Spring Security 官方网址&#xff1a;Spring Security官网 开…

React路由 基本使用 嵌套路由 动态路由 获取路由参数 异步路由 根据配置文件来生成路由

文章目录 React-router的三个版本react-router使用嵌套路由动态路由 获取路由参数Params参数Query参数Location信息 控制跳转地址异步路由根据配置文件生成路由 React-router的三个版本 React-router 服务端渲染使用React-router-dom 浏览器端渲染使用React-router-native Rea…

API项目3:API签名认证

问题引入 我们为开发者提供了接口&#xff0c;却对调用者一无所知 假设我们的服务器只能允许 100 个人同时调用接口。如果有攻击者疯狂地请求这个接口&#xff0c;那是很危险的。一方面这可能会损害安全性&#xff0c;另一方面耗尽服务器性能&#xff0c;影响正常用户的使用。…

若依前后端分离版本el-select下拉框字典如何设置默认值。

在若依前后端分离框架中&#xff0c;如何给下拉框设置默认值&#xff0c;刚入门的小伙伴&#xff0c;可能会不知道如何去做。 本章教程&#xff0c;主要以用户管理模块中的添加用户举例说明如何设置用户性别默认值为男。 解决思路 首先&#xff0c;我们需要找到打开新增页面的方…

【工具】前端js数字金额转中文大写金额

【工具】前端js数字金额转中文大写金额 代码 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>金额转…

多功能点击器(文末附Gitee源码)——光遇自动弹奏

之前提到的多功能点击器&#xff0c;使用场景比较多&#xff0c;之前玩光遇喜欢在里面弹琴&#xff0c;想到用这个点击器也能自动弹琴&#xff0c;跟别的自动弹琴脚本不一样&#xff0c;这个比较简单容易操作。 借这个光遇自动弹琴使用教程再讲解一下这个多功能点击头的使用方法…

ModelMapper的常见用法 ,号称是beanUtils.copyProp....的升级版??,代码复制粘贴即可复现效果,so convenient

官网案例 以下将官网案例做一个解释 1&#xff09;快速入门 递归遍历源对象的属性拷贝给目标对象 拷贝对象下对象的属性值 Data class Order {private Customer customer;private Address billingAddress; }Data class Customer {private Name name; }Data class Name {pr…

在三维可视化项目中,B/S和C/S架构该如何选择?

一、什么是B/S和C/S 在3D数据可视化中&#xff0c;有两种常见的架构模式&#xff1a;BS&#xff08;Browser/Server&#xff09;和CS&#xff08;Client/Server&#xff09; B/S模式 B/S模式是指将3D数据可视化的逻辑和处理放在服务器端&#xff0c;而在客户端使用浏览器进行…

智能汽车智能网联

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗你的人和事&#xff0c;多看一眼都是你的不…

rom定制系列------小米6x_MIUI14_安卓13刷机包修改写入以及功能定制 界面预览

在接待一些定制化系统中。有很多工作室或者一些特殊行业的友友需要在已有固件基础上简略修改其中的功能。方便使用。例如usb调试默认开启。usb安装设置以及usb安装与内置删减一些app的定制服务。今天给友友预览其中小米6X此款机型定制相关的一些界面与功能演示。 定制机型以及…

公司新来的00后测试开发,让我对“跨界”二字有了全新认识

最近&#xff0c;我们部门迎来了一位新面孔——一个00后的年轻人&#xff0c;阿沅。初见他时&#xff0c;我以为他只是众多新入职员工中的普通一员&#xff0c;毕竟他的专业背景与我们的IT行业似乎相去甚远——广告学。然而&#xff0c;他的到来&#xff0c;却如同一阵清风&…