【设计模式】工厂模式

news/2024/10/23 9:39:32/

目录

        • 一、说明
        • 二、简单工厂模式
          • 2.1 说明
          • 2.2 简单工厂代码示例
          • 2.3 静态工厂代码示例
        • 三、工厂方法模式
          • 3.1 说明
          • 3.2 工厂方法代码示例
        • 四、抽象工厂模式
          • 4.1 说明
          • 4.2 抽象工厂代码示例
        • 五、通过配置获取

一、说明

  • 1.如果使用对象的时候直接new该对象,就会对该对象耦合严重
  • 2.如果要更换对象,所有new对象的地方都需要修改,违背了软件设计原则的开闭原则
  • 3.使用工厂生产对象,只需要与工厂打交道
  • 4.能与对象解耦,如果要更换对象,直接在工厂里更换该对象
  • 5.最大的优点即解耦

二、简单工厂模式

2.1 说明
  • 1.简单工厂不是一种设计模式,是一种编程习惯
  • 2.简单工厂包括抽象产品、具体产品、具体工厂
  • 3.抽象产品:定义了产品的规范,描述了产品的主要特性和功能
  • 4.具体产品:实现或者继承抽象产品的子类
  • 5.具体工厂:提供了创建产品的方法,调用者通过该方法来创建产品
  • 6.后续要加新的产品,得要修改简单工厂的代码,违反了开闭原则
  • 7.优点:封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,避免修改客户端代码,如果要实现新产品可以直接修改工厂类,而不需要在原代码中修改,降低了客户端代码修改的可能性,更容易扩展
  • 8.缺点:增加新产品还是会修改工厂类的代码,违背了“开闭原则”
2.2 简单工厂代码示例
package com.learning.simple_factory;public class AProduct extends Product {@Overridepublic void sell() {System.out.println("A产品卖出");}
}
package com.learning.simple_factory;public class BProduct extends Product {@Overridepublic void sell() {System.out.println("B产品卖出");}
}
package com.learning.simple_factory;public abstract class Product {public abstract void sell();
}
package com.learning.simple_factory;/*** @Author wangyouhui* @Description 简单工厂**/
public class SimpleFactory {public Product getProduct(String type){if("A".equals(type)){return new AProduct();}else if("B".equals(type)){return new BProduct();}else{throw new RuntimeException("未找到对应的产品");}}
}
package com.learning.simple_factory;public class Store {public static void main(String[] args) {SimpleFactory simpleFactory = new SimpleFactory();Product a = simpleFactory.getProduct("A");a.sell();Product b = simpleFactory.getProduct("B");b.sell();}
}
2.3 静态工厂代码示例
package com.learning.static_factory;
/*** @Author wangyouhui* @Description 静态工厂**/
public class StaticFactory {public static Product getProduct(String type){if("A".equals(type)){return new AProduct();}else if("B".equals(type)){return new BProduct();}else{throw new RuntimeException("未找到对应的产品");}}
}
package com.learning.static_factory;public class Store {public static void main(String[] args) {Product a = StaticFactory.getProduct("A");a.sell();Product b = StaticFactory.getProduct("B");b.sell();}
}

三、工厂方法模式

3.1 说明
  • 1.使用工厂方法模式完全遵循开闭原则
  • 2.定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象
  • 3.工厂方法使一个产品类的实例化延迟到对应工厂的子类
  • 4.工厂方法模式的角色:抽象工厂、具体工厂、抽象产品、具体产品
  • 5.抽象工厂:提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品
  • 6.具体工厂:实现抽象工厂中的抽象方法,完成具体产品的创建
  • 7.抽象产品:定义了产品的规范,描述了产品的主要特性和功能
  • 8.具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应
  • 9.优点:用户只需要知道具体工厂的名称便可以得到所要的产品,无须知道产品的具体创建过程;在新增新的产品时只需要添加具体产品类和对应的具体工厂类,不需要对原工厂进行修改,满足开闭原则
  • 10.缺点:每增加一个产品就要增加一个具体产品类和一个具体工厂类,增加了系统的复杂度
3.2 工厂方法代码示例
package com.learning.factory.factory_method;/*** @Author wangyouhui* @Description**/
public abstract class Product {public abstract void sell();
}
package com.learning.factory.factory_method;/*** @Author wangyouhui* @Description A产品**/
public class AProduct extends Product{@Overridepublic void sell() {System.out.println("A产品卖出");}
}
package com.learning.factory.factory_method;/*** @Author wangyouhui* @Description B产品**/
public class BProduct extends Product{@Overridepublic void sell() {System.out.println("B产品卖出");}
}
package com.learning.factory.factory_method;public interface FactoryMethodFactory {Product getProduct();
}
package com.learning.factory.factory_method;/*** @Author wangyouhui* @Description A产品工厂**/
public class AProductFactory implements FactoryMethodFactory{@Overridepublic Product getProduct() {return new AProduct();}
}
package com.learning.factory.factory_method;/*** @Author wangyouhui* @Description B产品工厂**/
public class BProductFactory implements FactoryMethodFactory{@Overridepublic Product getProduct() {return new BProduct();}
}
package com.learning.factory.factory_method;/*** @Author wangyouhui* @Description 商店**/
public class Store {private FactoryMethodFactory factoryMethodFactory;public void setFactoryMethodFactory(FactoryMethodFactory factoryMethodFactory) {this.factoryMethodFactory = factoryMethodFactory;}public void sell(){this.factoryMethodFactory.getProduct().sell();}public static void main(String[] args) {AProductFactory aProductFactory = new AProductFactory();BProductFactory bProductFactory = new BProductFactory();Store store = new Store();store.setFactoryMethodFactory(aProductFactory);store.setFactoryMethodFactory(bProductFactory);store.sell();}
}

四、抽象工厂模式

4.1 说明
  • 1.抽象工厂模式考虑多等级产品的生产
  • 2.将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族
  • 3.台式机、笔记本、pad都是电脑,是同一个产品等级
  • 4.苹果制造的笔记本和手机,是同一个产品族
  • 5.抽象工厂模式是工厂方法模式的升级版,工厂方法模式只生产一个等级的产品,抽象工厂模式可生产多个等级的产品
  • 6.抽象工厂的角色:抽象工厂、具体工厂、抽象产品、具体产品
  • 7.抽象工厂:提供创建产品的接口,包含多个创建产品的方法,可以创建多个不同等级的产品
  • 8.具体工厂:实现抽象工厂中所有抽象方法,完成具体产品的创建
  • 9.抽象产品:定义产品规范,描述产品主要特征和功能,抽象工厂模式有多个抽象产品
  • 10.具体产品:实现抽象产品角色定义的接口,由具体工厂来创建,同具体工厂之间是多对一关系
  • 11.优点:当一个产品族中的多个对象被设计成一起工作时,能保证客户端始终只使用同一个产品族中的对象
  • 12.缺点:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改
4.2 抽象工厂代码示例
package com.learning.factory.abstract_factory;interface ChineseFactory {// 获取货物Goods getGoods();// 获取产品Product getProduct();
}
package com.learning.factory.abstract_factory;/*** @Author wangyouhui* @Description A工厂**/
public class AFactory implements ChineseFactory{@Overridepublic Goods getGoods() {return new AGoods();}@Overridepublic Product getProduct() {return new AProduct();}
}
package com.learning.factory.abstract_factory;/*** @Author wangyouhui* @Description B工厂**/
public class BFactory implements ChineseFactory{@Overridepublic Goods getGoods() {return new BGoods();}@Overridepublic Product getProduct() {return new BProduct();}
}
package com.learning.factory.abstract_factory;/*** @Author wangyouhui* @Description**/
public abstract class Product {public abstract void sell();
}
package com.learning.factory.abstract_factory;/*** @Author wangyouhui* @Description 货物**/
public abstract class Goods {public abstract void sell();
}
package com.learning.factory.abstract_factory;/*** @Author wangyouhui* @Description A货物**/
public class AGoods extends Goods{@Overridepublic void sell() {System.out.println("A货物卖出");}
}
package com.learning.factory.abstract_factory;/*** @Author wangyouhui* @Description B货物**/
public class BGoods extends Goods{@Overridepublic void sell() {System.out.println("B货物卖出");}
}
package com.learning.factory.abstract_factory;/*** @Author wangyouhui* @Descriptionc 产品**/
public abstract class Product {public abstract void sell();
}
package com.learning.factory.abstract_factory;/*** @Author wangyouhui* @Description A产品**/
public class AProduct extends Product {@Overridepublic void sell() {System.out.println("A产品卖出");}
}
package com.learning.factory.abstract_factory;/*** @Author wangyouhui* @Description B产品**/
public class BProduct extends Product {@Overridepublic void sell() {System.out.println("B产品卖出");}
}
package com.learning.factory.abstract_factory;/*** @Author wangyouhui* @Description 示例**/
public class Store {public static void main(String[] args) {AFactory aFactory = new AFactory();Goods goods1 = aFactory.getGoods();Product product1 = aFactory.getProduct();goods1.sell();product1.sell();BFactory bFactory = new BFactory();Goods goods2 = bFactory.getGoods();Product product2 = bFactory.getProduct();goods2.sell();product2.sell();}
}

五、通过配置获取

package com.learning.factory.config_factory;/*** @Author wangyouhui* @Description**/
public abstract class Product {public abstract void sell();
}
package com.learning.factory.config_factory;/*** @Author wangyouhui* @Description A产品**/
public class AProduct extends Product {@Overridepublic void sell() {System.out.println("A产品卖出");}
}
package com.learning.factory.config_factory;/*** @Author wangyouhui* @Description B产品**/
public class BProduct extends Product {@Overridepublic void sell() {System.out.println("B产品卖出");}
}

在这里插入图片描述

aProduct=com.learning.factory.config_factory.AProduct
bProduct=com.learning.factory.config_factory.BProduct
package com.learning.factory.config_factory;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Properties;
import java.util.Set;
public class ProductFactory {//加载配置文件,获取配置文件中配置的全类名,并创建该类的对象进行存储//1.定义容器对象存储对象private static HashMap<String, Product> map = new HashMap<>();//2.加载配置文件,只需要加载一次static{//3.创建Properties对象Properties properties = new Properties();//4.调用load方法进行配置文件的加载InputStream is = ProductFactory.class.getClassLoader().getResourceAsStream("bean.properties");try {properties.load(is);//5.从properties集合中获取全类名并创建对象Set<Object> set = properties.keySet();for(Object key: set){String className = properties.getProperty((String) key);//通过反射技术创建对象Class clazz = Class.forName(className);Product product = (Product) clazz.newInstance();//将名称和对象存储在容器中map.put((String)key, product);}} catch (Exception e) {e.printStackTrace();}}public static Product createProduct(String name){return map.get(name);}public static void main(String[] args) {Product aProduct = ProductFactory.createProduct("aProduct");Product bProduct = ProductFactory.createProduct("bProduct");aProduct.sell();bProduct.sell();}
}

http://www.ppmy.cn/news/52635.html

相关文章

数字化转型中的石头和沙子问题

作者介绍 朱金衡&#xff0c;西门子Mendix 高级技术咨询顾问及架构师&#xff0c;Mendix Certified 中级培训讲师以及TOGAF Certified 企业架构师。作为专家服务架构师提供咨询服务&#xff0c;如方案设计、开发辅导、故障排除、应用程序审查等&#xff0c;同时创造了许多专门…

Git使用总结

初始化本地Git仓库 git init 执行效果&#xff1a;项目根目录下会多了 .git 隐藏文件夹&#xff0c;存放的是本地库的相关目录和配置文件&#xff0c;不能删除也不能胡乱修改 设置本地签名 形式&#xff1a; 用户名&#xff1a;ysp Email: sdnuysp163.com 作用&#xff1a;区分…

操作系统基本知识点

进程&#xff1a;进程是一个程序的执行过程。执行前需要将该程序放到内存中才能被CPU处理 系统调用 系统调用命令 广义指令 操作系统提供的接口&#xff1a; 1.命令接口&#xff1a;允许用户直接使用 2.程序接口&#xff1a;允许用户通过程序间接使用 3.GUI&#xff1a;现代…

初始新能源汽车

文章目录 电动汽车的三级模块体系VCU&#xff08;整车控制器&#xff09;MCU&#xff08;电机控制器&#xff09;电池包和BMS&#xff08;电池管理系统&#xff09;电动汽车的大三电电动汽车的小三电电动汽车的模块组成 电动汽车的三级模块体系 总体上讲&#xff0c;整个新能源…

接口测试工具

一、Apifox和Postman各自的定义 1、Postman是一款支持http协议的接口调试与测试工具&#xff0c;其主要特点就是功能强大&#xff0c;使用简单且易用性好 。无论是开发人员进行接口调试&#xff0c;还是测试人员做接口测试&#xff0c;postman都是我们的首选工具之一 。 2、A…

人脸识别 Face Recognition 入门

人脸识别 Face Recognition 入门概述 总述传统特征方法深度学习方法损失函数改进基于欧几里德和距离的损失基于角度/余弦边距的损失SoftMax 损失及其变体 一级标题二级标题二级标题二级标题 找论文搭配 Sci-Hub 食用更佳 &#x1f4aa; Sci-Hub 实时更新 : https://tool.yovisu…

企企通受邀出席嘉兴产业数字化峰会,助力嘉兴“智”造业发展

近日&#xff0c;2023年嘉兴产业数字化峰会在浙江嘉兴圆满举办&#xff0c;企企通作为采购供应链厂商受邀出席&#xff0c;并与众多信息化领域的专家一起分享心得、总结得失、展望未来&#xff0c;为嘉兴市企业的产业数字化发展探索合适的路径与方向。 01、数字蓄能&#xff0c…

02 【Sass语法介绍-变量】

sass有两种语法格式Sass(早期的缩进格式&#xff1a;Indented Sass)和SCSS(Sassy CSS) 目前最常用的是SCSS&#xff0c;任何css文件将后缀改为scss&#xff0c;都可以直接使用Sassy CSS语法编写。 所有有效的 CSS 也同样都是有效的 SCSS。 Sass语法介绍-变量 1.前言 Sass …