设计模式--工厂方法模式
/** * 抽象实例角色 */ public interface Bank { /** * 打印余额具体业务 */ void getBalance(); }
/** * @description: 农业银行-充当具体实例角色 * @author: jack * @time: 2022/5/12 16:56 */ public class AbcBank implements Bank{ @Override public void getBalance() { System.out.println("您的农业银行余额为1000元."); } }
/** * @description: 建设银行-充当具体实例角色 * @author: jack * @time: 2022/5/12 16:57 */ public class CcbBank implements Bank{ @Override public void getBalance() { System.out.println("您的建设银行余额为2000元."); } }
/** * @description: 充当抽象工厂角色 * @author: jack * @time: 2022/5/12 17:00 */ public interface BankFactory { // 抽象工厂方法 Bank createBank(); }
/** * @description: 农业银行工厂-充当具体工厂角色 * @author: jack * @time: 2022/5/12 17:01 */ public class AbcBankFactory implements BankFactory{ @Override public Bank createBank() { // 实例化农业银行 Bank bank = new AbcBank(); return bank; } }
/** * @description: 建设银行工厂-充当具体工厂角色 * @author: jack * @time: 2022/5/12 17:03 */ public class CcbBankFactory implements BankFactory{ @Override public Bank createBank() { // 实例化建设银行 Bank bank = new CcbBank(); return bank; } }
/** * @description: 工厂方法模式 * @author: jack * @time: 2022/5/12 16:41 */ public class factoryMethodPatternDemo { public static void main(String[] args) { // 抽象工厂 BankFactory factory; // 抽象实例 Bank bank; // 创建具体实例工厂 factory = new CcbBankFactory(); // 创建具体实例,具体实例交给实例工厂去创建 bank = factory.createBank(); // 执行业务逻辑 bank.getBalance(); } }
客户端打印如下:您的建设银行余额为2000元.
如果切换成农业银行就把创建工厂改成:
factory = new AbcBankFactory();
工厂方法模式UML结构图:
工厂方法模式优/缺点与适用环境
工厂方法模式是简单工厂模式的延伸,它继承了简单工厂模式的优点,同时还弥补了简单工厂模式的不足。工厂方法模式是使用频率最高的设计模式之一,是很多开源框架和API类库的核心模式。
优点:
工厂方法模式的优点主要如下∶
(1)在工厂方法模式中,工厂方法用来创建客户所需要的实例,同时还向客户隐藏了哪种具体实例类将被实例化这一细节,用户只需要关心所需实例对应的工厂,无须关心创建细节,甚至无须知道具体实例类的类名。
(2)基于工厂角色和实例角色的多态性设计是工厂方法模式的关键。它能够让工厂自主确定创建何种实例对象,而如何创建这个对象的细节完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,正是因为所有的具体工厂类都具有同一抽象父类。
(3)使用工厂方法模式的另一个优点是在系统中加入新实例时无须修改抽象工厂和抽象实例提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体实例,而只要添加一个具体工厂和具体实例即可,这样系统的可扩展性也就变得非常好,完全符合开
闭原则
缺点:
工厂方法模式的缺点主要如下∶
(1)在添加新产品时需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
(2)由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度。
工厂方法模式适用环境:
在以下情况下可以考虑使用工厂方法模式∶
(1)客户端不知道它所需要的对象的类。在工厂方法模式中,客户端不需要知道具体实例类的类名,只需要知道所对应的工厂即可,具体产品对象由具体工厂类创建,可将具体工厂类的类名存储在配置文件或数据库中。
(2)抽象工厂类通过其子类来指定创建哪个对象。在工厂方法模式中,对于抽象工厂类只需要提供一个创建实例的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时子类对象将覆盖父类对象,从而使得系统更容易
扩展。