创建者模式—工厂模式

news2024/12/26 11:26:03

目录

1.工厂模式

1.1概述

1.2简单工厂模式

1.2.1结构

1.2.2实现

1.2.3优缺点

1.2.4静态工厂

1.3工厂方法模式

1.3.1概念

1.3.2结构

1.3.3实现

1.3.4优缺点

1.4抽象工厂模式

1.4.1概念

1.4.2结构

1.4.3实现

1.4.4优缺点


1.工厂模式

1.1概述

需求:设计一个咖啡店点餐系统。

设计一个咖啡类(Coffee),并定义其两个子类(美式咖啡【AmericanCoffee】和拿铁咖啡【LatteCoffee】);再设计一个咖啡店类(CoffeeStore),咖啡店具有点咖啡的功能。

package zyy02;

public abstract class Coffee {
    public abstract String getName();
    public void addSugar(){
        System.out.println("加糖");
    }
    public void addMilk(){
        System.out.println("加奶");
    }

}
package zyy02;

public class AmericanCoffee extends Coffee{
    @Override
    public String getName() {
        return "美式咖啡";
    }
}
package zyy02;

public class LatteCoffee extends Coffee{
    @Override
    public String getName() {
        return "拿铁咖啡";
    }
}
package zyy02;

public class CoffeeStore {
    public Coffee orderCoffee(String type){
        //声明coffee类型的变量,根据不同类型创建咖啡子类对象
        Coffee coffee=null;
        if("american".equals(type)){
            coffee=new AmericanCoffee();
        }else if("latte".equals(type)){
            coffee=new LatteCoffee();
        }else{
            throw new RuntimeException("对不起,你所点的咖啡没有");
        }
        //加配料
        coffee.addMilk();
        coffee.addSugar();

        return coffee;
    }
}
package zyy02;

public class Demo {
    public static void main(String[] args) {
        //创建咖啡点类
        CoffeeStore store=new CoffeeStore();
        //点咖啡
        Coffee coffee=store.orderCoffee("latte");
        System.out.println(coffee.getName());
    }
}

在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则。如果我们使用工厂来生产对象,我们就只和工厂打交道就可以了,彻底和对象解耦,如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦。

三种工厂的使用

  • 简单工厂模式(不属于GOF的23种经典设计模式)
  • 工厂方法模式
  • 抽象工厂模式

1.2简单工厂模式

简单工厂不是一种设计模式,反而比较像是一种编程习惯

1.2.1结构

简单工厂包含如下角色:

  • 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品 :实现或者继承抽象产品的子类
  • 具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品。

1.2.2实现

 现在使用简单工厂对上面案例进行改进

  

package zyy02;

public abstract class Coffee {
    public abstract String getName();
    public void addSugar(){
        System.out.println("加糖");
    }
    public void addMilk(){
        System.out.println("加奶");
    }

}
package zyy02;

public class AmericanCoffee extends Coffee{
    @Override
    public String getName() {
        return "美式咖啡";
    }
}
package zyy02;

public class LatteCoffee extends Coffee{
    @Override
    public String getName() {
        return "拿铁咖啡";
    }
}
package zyy02;

public class SimpleFactory {
    public Coffee createCoffee(String type){
        //声明coffee类型的变量,根据不同类型创建咖啡子类对象
        Coffee coffee=null;
        if("american".equals(type)){
            coffee=new AmericanCoffee();
        }else if("latte".equals(type)){
            coffee=new LatteCoffee();
        }else{
            throw new RuntimeException("对不起,你所点的咖啡没有");
        }
        return coffee;
    }
}
package zyy02;

public class CoffeeStore {
    public Coffee orderCoffee(String type){
        SimpleFactory factory=new SimpleFactory();
        //调用方法生产咖啡
        Coffee coffee=factory.createCoffee(type);
        //加配料
        coffee.addMilk();
        coffee.addSugar();

        return coffee;
    }
}
package zyy02;

public class Demo {
    public static void main(String[] args) {
        //创建咖啡点类
        CoffeeStore store=new CoffeeStore();
        //点咖啡
        Coffee coffee=store.orderCoffee("latte");
        System.out.println(coffee.getName());
    }
}

工厂(factory)处理创建对象的细节,一旦有了SimpleCoffeeFactory,CoffeeStore类中的orderCoffee()就变成此对象的客户,后期如果需要Coffee对象直接从工厂中获取即可。这样也就解除了和Coffee实现类的耦合,同时又产生了新的耦合,CoffeeStore对象和SimpleCoffeeFactory工厂对象的耦合,工厂对象和商品对象的耦合。

后期如果再加新品种的咖啡,我们势必要需求修改SimpleCoffeeFactory的代码,违反了开闭原则。工厂类的客户端可能有很多,比如创建美团外卖等,这样只需要修改工厂类的代码,省去其他的修改操作。

1.2.3优缺点

优点:

封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户代码修改的可能性,更加容易扩展。

缺点:

增加新产品时还是需要修改工厂类的代码,违背了"开闭原则"。

1.2.4静态工厂

在开发中也有一部分人将工厂类中的创建对象的功能定义为静态的,这个就是静态工厂模式,它也不是23种设计模式中的,与上面的区别就是调用工厂类的时候可以直接用类名调用:

public class SimpleCoffeeFactory {

    public static Coffee createCoffee(String type) {
        Coffee coffee = null;
        if("americano".equals(type)) {
            coffee = new AmericanoCoffee();
        } else if("latte".equals(type)) {
            coffee = new LatteCoffee();
        }
        return coffe;
    }
}
package zyy02;

public class CoffeeStore {
    public Coffee orderCoffee(String type){
        //调用方法生产咖啡
        Coffee coffee=SimpleFactory.createCoffee(type);
        //加配料
        coffee.addMilk();
        coffee.addSugar();

        return coffee;
    }
}

1.3工厂方法模式

针对上例中的缺点,使用工厂方法模式就可以完美的解决,完全遵循开闭原则。

1.3.1概念

定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。

1.3.2结构

工厂方法模式的主要角色:

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
  • 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

1.3.3实现

使用工厂方法模式对上例进行改进

 

public interface CoffeeFactory {

    Coffee createCoffee();
}
public class LatteCoffeeFactory implements CoffeeFactory {

    public Coffee createCoffee() {
        return new LatteCoffee();
    }
}

public class AmericanCoffeeFactory implements CoffeeFactory {

    public Coffee createCoffee() {
        return new AmericanCoffee();
    }
}
public class CoffeeStore {

    private CoffeeFactory factory;

    public CoffeeStore(CoffeeFactory factory) {
        this.factory = factory;
    }

    public Coffee orderCoffee(String type) {
        Coffee coffee = factory.createCoffee();
        coffee.addMilk();
        coffee.addsugar();
        return coffee;
    }
}

从以上的编写的代码可以看到,要增加产品类时也要相应地增加工厂类,不需要修改工厂类的代码了,这样就解决了简单工厂模式的缺点。工厂方法模式是简单工厂模式的进一步抽象。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。

1.3.4优缺点

优点: 

  • 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
  • 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;

缺点:

  • 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。

1.4抽象工厂模式

1.4.1概念

工厂方法模式中考虑的是一类产品的生产,同种类产品称为同等级产品,也就是说:工厂方法模式只考虑生产同等级的产品

本节要介绍的抽象工厂模式将考虑多等级产品的生产,将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族,也就是同一品牌的产品,同一品牌的产品产自同一个工厂。

1.4.2结构

抽象工厂模式的主要角色如下:

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
  • 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。

1.4.3实现

现咖啡店业务发生改变,不仅要生产咖啡还要生产甜点,如提拉米苏、抹茶慕斯等,要是按照工厂方法模式,需要定义提拉米苏类、抹茶慕斯类、提拉米苏工厂、抹茶慕斯工厂、甜点工厂类,很容易发生类爆炸情况。其中拿铁咖啡、美式咖啡是一个产品等级,都是咖啡;提拉米苏、抹茶慕斯也是一个产品等级;拿铁咖啡和提拉米苏是同一产品族(也就是都属于意大利风味),美式咖啡和抹茶慕斯是同一产品族(也就是都属于美式风味)。所以这个案例可以使用抽象工厂模式实现。

 

public interface DessertFactory {

    Coffee createCoffee();

    Dessert createDessert();
}
//美式甜点工厂
public class AmericanDessertFactory implements DessertFactory {

    public Coffee createCoffee() {
        return new AmericanCoffee();
    }

    public Dessert createDessert() {
        return new MatchaMousse();
    }
}
//意大利风味甜点工厂
public class ItalyDessertFactory implements DessertFactory {

    public Coffee createCoffee() {
        return new LatteCoffee();
    }

    public Dessert createDessert() {
        return new Tiramisu();
    }
}

如果要加同一个产品族的话,只需要再加一个对应的工厂类即可,不需要修改其他的类

1.4.4优缺点

优点:

当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:

当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

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

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

相关文章

易基因|细菌全基因组甲基化纳米孔测序(ONT):技术推介

大家好,这是专注表观组学十余年,领跑多组学科研服务的易基因。今天跟大家介绍一下易基因的新产品:细菌全基因组甲基化纳米孔测序(ONT)。表观修饰不需要改变DNA序列便能实现对性状的改变,表观修饰的改变与基…

什么是事务?什么是索引?什么是视图?

目录 一、事务 二、视图 1 、视图概念 2、为什么要使用视图 3 、性能问题 4 、定义视图 5、查看视图 6、删除视图 三、索引 1、引入索引的问题 2、索引是什么 3、索引为什么选择b树 一、事务 事务是什么? 事务是一个操作序列,这些操作要么都…

Python+Selenium+Unittest 之selenium2--元素定位1-简介

这篇先说下webdriver的几种元素定位方式,让大家有个大概的了解,UI自动化说白了就是使用代码代替人工去进行操作,在页面上,执行人员可以直接对看到的任何地方进行点击、拖动等操作,而代码的话需要识别到到底要点那个按钮…

生产制造业ERP管理系统对于制造企业的好处有哪些?

任何一家企业在管理当中都存在或多或少的问题,这些问题对企业的发展都形成了一定的阻碍。在生产制造业当中,由于每日的繁重的生产计划和大量的生产作业,使得企业管理存在一些问题,这些问题不利于生产的有序进行,从而阻…

图表控件LightningChart.NET 系列教程(八):用代码创建图表

LightningChart.NET SDK 是一款高性能数据可视化插件工具,由数据可视化软件组件和工具类组成,可支持基于 Windows 的用户界面框架(Windows Presentation Foundation)、Windows 通用应用平台(Universal Windows Platfor…

【微服务】分布式事务Seata

分布式事务Seata1.分布式事务问题1.1.本地事务1.2.分布式事务2.理论基础2.1.CAP定理2.1.1.一致性2.1.2.可用性2.1.3.分区容错2.1.4.矛盾2.2.BASE理论2.3.解决分布式事务的思路3.初识Seata3.1.Seata的架构3.2.部署TC服务3.3.微服务集成Seata3.3.1.引入依赖3.3.2.配置TC地址3.3.3…

商用清洁机器人:科沃斯“破圈”、高仙机器人“纵深”

配图来自Canva可画 正所谓科技改变生活,机器人在人们日常生活中出现的频率正在逐步提高。同时,随着智能技术的不断迭代升级、用户需求的增多,机器人的应用场景逐步拓宽、功能形态也愈发多样化,比如配送机器人、医疗机器人、教育机…

Android 12.0 启动app时设置密码锁

1.前言 1.1概述 在12.0的系统产品开发中,对于限制某些app的启动的功能中,在项目中的需求是在点击app启动的时候,根据包名设置密码锁,当输入正确的密码的时候来启动这个app,否则 就不能启动这个app,达到限制使用app的目的,这就需要在app启动的时候,检测app的包名,然后在…

分布式架构的必问理论

基础理论: CAP理论: CAP理论是分布式系统设计中最基础、也是最为关键的理论,它指出,分布式数据存储不可能同时满足以下三个条件。 一致性(Consistency):每次读取要么获得最近写入的数据&…

OAuth2 (二)

目录 创建项目结构 父工程 客户 认证服务器 资源拥有者 资源服务器 创建项目结构 演示代码下载: https://gitee.com/lisenaq/oauth2-example.git 演示客户发请求: http://localhost:8080/client/getCode 父工程 父工程有:子模块需要重新导入该…

CVE-2022-34916 Apache Flume 远程代码执行漏洞分析

项目介绍 Apache Flume 是一个分布式的,可靠的,并且可用于高效地收集,汇总和移动大量日志数据的软件。它具有基于流数据流的简单而灵活的体系结构。它具有可调的可靠性机制以及许多故障转移和恢复机制,并且具有健壮性和容错性。它…

Spring/SpringBoot/SpringCloud面试题

SpringBoot和SpringMVC的区别 形式上:SpringBoot是一个自动化配置的工具;SpringMVC是一个web框架在搭建项目时:SpringMVC需要手动配置xml文件,同时需要配置Tomcat服务器。而SpringBoot采用约定大于配置的方式,进行自动…

【Linux系统】第五篇:Linux中编译器gcc/g++的使用

文章目录一、编译工具gcc/g二、程序编译的过程🎄预处理🎄编译🎄汇编🎄链接三、动态链接和静态链接🌻动态链接🌻静态链接🌻 程序动、静态链接的区分一、编译工具gcc/g gcc/g 分别是 C/C 的编译器…

【wp】hgame2023 week3 RePwn

【wp】hgame2023 week3 Re&&Pwn Re cpp那个chacha20加密不会。 kunmusic 用dnspy逆dll,在Program的Main方法中找到了初始化的数据 下断点执行,拷贝出data 写一份脚本进行data与104的异或 def step_one():with open("./data", enc…

发明专利申请流程资料

​发明专利申请流程 依据专利法,发明专利申请的审批程序分为: 1、受理阶段 2、初步审查阶段 3、公布阶段 4、实质审查阶段 5、授权阶段 发明专利申请所需资料 1、发明专利请求书。 2、说明书。 3、权利要求书。 4、说明书摘要。 5、有附图的可同时提交说…

Actionchains在selenium中的使用方法

今天分享一下selenium最常用的ActionChains的使用,以及碰到的一些问题的解决。 1.selenium解决鼠标悬停的问题 今天抓取某个平台的数据时发现有的数据需要鼠标悬停在上面才能加载出来,于是就想到了使用ActionChains解决悬停的问题,下面是思…

计算机组成原理 | 第九章:控制单元的功能 | 微操作命令 | 时钟周期

文章目录📚微操作命令的分析🐇取指周期🐇间址周期🐇执行周期🥕非访存指令🥕访存指令⭐️🥕转移指令🐇中断周期📚控制单元的功能🐇控制单元的外特性&#x1f9…

分享微信报名小程序怎么做_瑜伽健身房培训报名小程序开发介绍

活动报名收费签到小程序,支持个人免费组织报名收款和现场签到。随时随地管理活动、发布活动、查看收入明细提现资金更效率。 活动报名收费签到小程序主要功能有: 在线报名:通过二维码或链接分享活动入口,亦可轻松放进入公众号。 …

客户端通过SSH连接Linux服务器超时问题解决方法汇总

🐚作者简介:花神庙码农(专注于Linux、WLAN、TCP/IP、Python等技术方向)🐳博客主页:花神庙码农 ,地址:https://blog.csdn.net/qxhgd🌐系列专栏:善假于物&#…

Windows无法进入睡眠模式怎么办?

睡眠模式是电脑的一种低功耗模式,能减少耗电。当你要离开电脑一阵,但又不想关闭文档和程序,就可以选择让电脑暂时休眠。 如果你的电脑无法进入睡眠模式,可以尝试下面几种方法: 更换电源选项检查电源命令使用电源疑难…