java设计模式之工厂方法模式
创始人
2024-01-25 03:05:39
0

一:工厂方法模式介绍

1.什么是工厂方法模式?
工厂方法模式是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。

2.工厂方法模式适合应用场景
1.当你在编写代码的过程中, 如果无法预知对象确切类别及其依赖关系时, 可使用工厂方法。
2.工厂方法将创建产品的代码与实际使用产品的代码分离, 从而能在不影响其他代码的情况下扩展产品创建部分代码。
3.例如, 如果需要向应用中添加一种新产品, 你只需要开发新的创建者子类, 然后重写其工厂方法即可。
3.实现方式
1.让所有产品都遵循同一接口。 该接口必须声明对所有产品都有意义的方法。
2.在创建类中添加一个空的工厂方法。 该方法的返回类型必须遵循通用的产品接口。
3.在创建者代码中找到对于产品构造函数的所有引用。 将它们依次替换为对于工厂方法的调用, 同时将创建产品的代码移入工厂方法。你可能需要在工厂方法中添加临时参数来控制返回的产品类型。
4.工厂方法的代码看上去可能非常糟糕。 其中可能会有复杂的 switch分支运算符, 用于选择各种需要实例化的产品类。 但是不要担心, 我们很快就会修复这个问题。
5.现在, 为工厂方法中的每种产品编写一个创建者子类, 然后在子类中重写工厂方法, 并将基本方法中的相关创建代码移动到工厂方法中。

如果应用中的产品类型太多, 那么为每个产品创建子类并无太大必要, 这时你也可以在子类中复用基类中的控制参数。
例如, 设想你有以下一些层次结构的类。 基类 邮件及其子类 航空邮件和 陆路邮件 ; ​ 运输及其子类 飞机, 卡车和 火车 。 ​ 航空邮件仅使用 飞机对象, 而 陆路邮件则会同时使用 卡车和 火车对象。 你可以编写一个新的子类 (例如 火车邮件 ) 来处理这两种情况, 但是还有其他可选的方案。 客户端代码可以给 陆路邮件类传递一个参数, 用于控制其希望获得的产品。

6.如果代码经过上述移动后, 基础工厂方法中已经没有任何代码, 你可以将其转变为抽象类。 如果基础工厂方法中还有其他语句, 你可以将其设置为该方法的默认行为。

4. 工厂方法模式优缺点
优点:
1你可以避免创建者和具体产品之间的紧密耦合。
2.单一职责原则。 你可以将产品创建代码放在程序的单一位置, 从而使得代码更容易维护。
3.开闭原则。 无需更改现有客户端代码, 你就可以在程序中引入新的产品类型。
缺点:
1.应用工厂方法模式需要引入许多新的子类, 代码可能会因此变得更复杂。 最好的情况是将该模式引入创建者类的现有层次结构中。

二:工厂方法模式代码实现

需求:设计一个咖啡店点餐系统。
设计一个咖啡类(Coffee),并定义其两个子类(美式咖啡和拿铁咖啡);再设计一个咖啡店类(CoffeeStore),咖啡店具有点咖啡的功能。

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

抽象工厂

//咖啡类工厂生产各种咖啡
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();
}
}
/*** @Author cgz* @Date 2022/11/16 12:27*///咖啡店
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.addsuagr();return  coffee;}//模拟controller层public static void main(String[] args) {//源码不用动,如果新增加新需求就增加新的子类,去继承工厂,实现创建工厂的方法,再去新增加具体的产品,//定义产品的逻辑,在其抽象方法上CoffeeStore coffeeStore =new CoffeeStore();coffeeStore.orderCoffee("咖啡类型");}
}
//将Coffee类做成抽象
public abstract class Coffee{protected String name; //名字//这个方法就是实现各个产品各自的特点public abstract void prepare();//加牛奶public void addMilk() {System.out.println(name + " addMilk;");}//加糖public void addsuagr() {System.out.println(name + " addsuagr;");}public void setName(String name) {this.name = name;}
//拿铁咖啡
public class LatteCoffee extends Coffee{//比如需求新增加产品//继承父类,并重写其方法,这样就是工厂模式每次只需要增加子类而不用改源代码的原因@Overridepublic void prepare() {setName("拿铁咖啡");System.out.println(" 拿铁咖啡");}//美式咖啡
public class AmericanCoffee extends Coffee{//比如需求新增加产品//继承父类,并重写其方法,这样就是工厂模式每次只需要增加子类而不用改源代码的原因@Overridepublic void prepare() {setName("美式咖啡");System.out.println(" 美式咖啡");}

三:总结

工厂模式的好处就是新增加产品时候不需要改源代码,我听过一个大佬说过一句话,如果一层不能解决问题,那就再套一层,不断套层。
总的来说:我发现工厂方法模式,需要具体的产品(比如拿铁,美式咖啡),还有一个抽象的产品(coffee)给具体的产品继承(定义抽象方法),抽象工厂(定义方法),具体工厂实现抽象工厂的方法,咖啡店(定义一个方法调用工厂方法,返回一个抽象产品)

这样看起来工厂方法模式的实现步骤:
1.定义抽象工厂(定义一个方法**)
2.定义各个具体实现类实现抽象方法(增加产品时候就新增一个实现类)-
3.定义一个类获取抽象方法实例,再生成一个公有构造器,定义一个方法(给其他模块调用,比如Service层)
4.定义抽象的产品(抽象的产品定义一个方法)
5.定义具体的产品继承抽象的产品

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...