欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > 工厂设计模式

工厂设计模式

2024/10/25 2:54:36 来源:https://blog.csdn.net/ccmjga/article/details/143089178  浏览:    关键词:工厂设计模式

👉 请投票支持这款 全新设计的脚手架 ,让 Java 再次伟大 👈
在这里插入图片描述

什么是工厂设计模式?

工厂设计模式是将拥有共性的产品抽象封装到工厂类中统一进行管理和创建,以达到降低使用者与产品之间的耦合度的目的一种手段。
工厂设计模式是创建者模式之一,且从结构上被划分为三大类。三种不同的结构类型,分别对应处理不同的问题。

  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式

工厂设计模式怎么用?

简单工厂模式

简单工厂模式是最简单,也是最清晰的模式。理解了简单工厂模式,就理解了工厂设计模式的主要思想。

/*** 工厂设计模式-简单工厂模式* 发送接口.**/
public interface Sender {void send();void sendToAll();
}/*** 工厂设计模式-简单工厂模式* 工厂类*/
public class SenderFactory {/*** 单例* 私有化构造器*/private SenderFactory() {//Nope}/*** 嵌套类* 持有外部类对象*/private static class SenderFactoryHolder {private static SenderFactory sf = new SenderFactory();}/*** 获取单例实例** @return*/public static SenderFactory getInstanse() {return SenderFactoryHolder.sf;}/*** 根据参数返回相应发送处理类** @return 邮件/短信发送对象*/public Sender createSender(String senderType) {switch (senderType) {case "sms":return new SMSSender();case "mail":return new MailSender();default:return new SMSSender();}}
}/*** 工厂设计模式-简单工厂模式* 短信发送类**/
public class SMSSender implements Sender {@Overridepublic void send() {System.out.print("发送短信");}@Overridepublic void sendToAll() {System.out.println("群发短信");}
}/*** 工厂设计模式-简单工厂模式* 客户端**/
public class Client {public static void main(String[] args) {SenderFactory factory = SenderFactory.getInstanse();Sender sd = factory.createSender("sms");sd.send();}
}

用户/客户端直接与 SenderFactory 交互,SenderFactory 根据参数决定具体创建的产品,用户最终从 SenderFactory 中得到了想要的产品。
可见,通过简单工厂模式,达到了解耦用户与产品的效果。但是,这样的结构并不是完美的。
在本例中,SenderFactory 掌管了所有的业务逻辑处理。这样的类,我们称为上帝类/全能类。上帝类耦合度非常高,每当需要增加新产品时,就需要更改 SenderFactory 中的代码。比如我们想要增加 FaxSender,则 SenderFactory 中的逻辑必然就会产生改动,这不符合设计模式的开闭原则(对扩展开放,对修改关闭)。
所以,当需要频繁增加新产品时,我们就需要通过工厂方法模式来解决问题。

工厂方法模式

/*** 工厂设计模式-工厂方法模式* 发送接口.*/
public interface Sender {void send();void confrimName();
}/*** 工厂设计模式-工厂方法模式* 短信发送类*/
public class SMSSender implements Sender {@Overridepublic void send() {System.out.println("发送短信");}@Overridepublic void confrimName() {System.out.println("确认短信发送对象姓名");}
}/*** 工厂设计模式-工厂方法模式* 短信发送工厂*/
public class SMSSenderFactory implements ISenderFactory {@Overridepublic Sender createSender() {return new SMSSender();}
}/*** 工厂设计模式-工厂方法模式* 邮件发送类*/
public class MailSender implements Sender {@Overridepublic void send() {System.out.println("发送邮件");}@Overridepublic void confrimName() {System.out.println("确认邮件发送对象姓名");}
}/*** 工厂设计模式-工厂方法模式* 邮件发送类制造工厂**/
public class MailSenderFactory implements ISenderFactory {@Overridepublic Sender createSender() {return new MailSender();}
}/*** 工厂设计模式-工厂方法模式* 传真发送类*/
public class FaxSender implements Sender {@Overridepublic void send() {System.out.println("发送传真");}@Overridepublic void confrimName() {System.out.println("确认传真发送对象姓名");}
}/*** 工厂设计模式-工厂方法模式* 传真发送类制造工厂*/
public class FaxSenderFactory implements ISenderFactory {@Overridepublic Sender createSender() {return new FaxSender();}
}/*** 工厂设计模式-工厂方法模式* 测试客户端*/
public class Client {public static void main(String[] args) {// 需要生产短信发送器,给客户发送短信SMSSenderFactory smsfct = new SMSSenderFactory();smsfct.createSender().send();smsfct.createSender().confrimName();// 需要生产邮件发送器,给客户发送短信MailSenderFactory mailfct = new MailSenderFactory();mailfct.createSender().send();// 需要生产传真发送器,给客户发送短信FaxSenderFactory faxfct = new FaxSenderFactory();faxfct.createSender().send();}
}

有别与简单工厂模式。工厂方法模式中工厂类被抽象成为了接口。而不同的产品对应不同的实现了工厂接口的具体工厂。比如 SMSSenderFactory 实现了工厂接口,并且只负责生产 SMSSender 对象产品。当出现新需求,如增加 FaxSender 产品时,我们不需要改动任何代码,只需要创建相应的 FaxSenderFactory 与 FaxSender 就够了。

细心的读者可能已经发现了,工厂方法模式同样拥有一些“致命”缺点,那就是随着产品的增加,相应的工厂类也会同比增加,造成项目文件十分臃肿巨大。于是,为了减少工厂类的出现数量,抽象工厂模式诞生了。

抽象工厂模式

抽象工厂模式若采用“填鸭式”说明,会让人感觉难以理解。
所以让我们先来尝试靠自己的力量解决一下上一小节中的,工厂方法模式所造成的工厂类大量增多的问题,已达到循序渐进地理解抽象工厂模式的目的。

工厂类疯狂增多的根本原因,是单个商品的生产对应了单个工厂。
要减少他们的数量,最容易想到的解决方案则是想办法让一个工厂创建多个产品。然而有了第一小节简单工厂模式的知识,我们还知道要尽可能解耦工厂类,避免创建出全能类/上帝类,给将来的维护扩展造成负担。
例如,在项目进行中,突然需要增加一个 Receiver 产品,如下:

/*** 工厂设计模式-抽象工厂模式* 接收者对象*/
public interface Receiver {void receive();void confirmName();
}/*** 工厂设计模式-抽象工厂模式* 邮件接受对象*/
public class MailReceiver implements Receiver {@Overridepublic void receive() {System.out.println("接受邮件");}@Overridepublic void confirmName() {System.out.println("确认邮件接受者姓名");}
}/*** 工厂设计模式-抽象工厂设计模式* 传真接收器**/
public class FaxReceiver implements Receiver {@Overridepublic void receive() {System.out.println("接受传真");}@Overridepublic void confirmName() {System.out.println("确认传真发送方姓名");}
}/*** 工厂设计模式-抽象工厂设计模式* 短信接受对象**/
public class SMSReceiver implements Receiver {@Overridepublic void receive() {System.out.println("接受短信");}@Overridepublic void confirmName() {System.out.println("确认短信接受者姓名");}
}

如果按照工厂方法设计模式的思路,上面这 3 个 Receiver 需要在项目中增加 3 个对应的具体工厂类。这显然是不太理想的做法。那么,有没有更加理想的做法呢?

继续分析,本例中 mailSender/mailReceiver,faxSender/faxReceiver,SMSSender/SMSReceiver 刚好能够组合为三对产品组合。如果一个工厂能够生产一对组合产品,是不是只需要三个工厂就能解决我们的需求呢?
在理清了思路后,我们开始动手写代码做一些尝试。
为了方便,我们将 mailSender/mailReceiver 这样一对产品,称为一个产品簇。而 mailSender,faxSender,SMSSender 3 个产品,称为 3 个产品等级。

Sender 类产品:

/*** 工厂设计模式-抽象工厂模式* 信息发送产品统一接口*/
public interface Sender {void send();void confrimName();
}/*** 工厂设计模式-抽象工厂模式* 短信发送对象*/
public class SMSSender implements Sender {@Overridepublic void send() {System.out.println("发送短信");}@Overridepublic void confrimName() {System.out.println("确认短信发送对象姓名");}
}/*** 工厂设计模式-抽象工厂模式* 邮件发送类**/
public class MailSender implements Sender {@Overridepublic void send() {System.out.println("发送邮件");}@Overridepublic void confrimName() {System.out.println("确认邮件发送对象姓名");}
}/*** 工厂设计模式-抽象工厂设计模式* 传真发送器**/
public class FaxSender implements Sender {@Overridepublic void send() {System.out.println("发送传真");}@Overridepublic void confrimName() {System.out.println("确认传真发送姓名");}
}

一个产品簇工厂中,能够生产一个系列的产品。而非单个产品。

/*** 工厂设计模式-抽象工厂模式* 抽象工厂类**/
public interface AbstractMsgHandlerFactory {// 创建发送器方法Sender createSender();// 创建接收器方法Receiver createReceiver();
}/*** 工厂设计模式-抽象工厂设计模式* 传真工厂*/
public class FaxHandlerFactory implements AbstractMsgHandlerFactory {@Overridepublic Sender createSender() {return new FaxSender();}@Overridepublic Receiver createReceiver() {return new FaxReceiver();}
}/*** 工厂设计模式-抽象工厂方法设计模式* 邮件工厂**/
public class MailHandlerFactory implements AbstractMsgHandlerFactory {@Overridepublic Sender createSender() {return new MailSender();}@Overridepublic Receiver createReceiver() {return new MailReceiver();}
}/*** 工厂设计模式-抽象工厂方法设计模式* 短信工厂*/
public class SMSHandlerFactory implements AbstractMsgHandlerFactory {@Overridepublic Sender createSender() {return new SMSSender();}@Overridepublic Receiver createReceiver() {return new SMSReceiver();}
}

/*** 工厂设计模式-抽象工厂方法模式* 客户端**/
public class Client {public static void main(String[] args) {// 需要处理邮件.AbstractMsgHandlerFactory mailFactory = new MailHandlerFactory();mailFactory.createSender().send();mailFactory.createReceiver().receive();// 需要处理短信AbstractMsgHandlerFactory smsFactory = new SMSHandlerFactory();smsFactory.createSender().send();smsFactory.createReceiver().receive();// 需要处理传真AbstractMsgHandlerFactory faxFactory = new FaxHandlerFactory();faxFactory.createSender().send();faxFactory.createReceiver().receive();}
}

通过抽象工厂设计模式,将代码的共性重新进行了抽象,从而使代码结构发生了变化。现在一个工厂不再生产单个产品,而是生产一个产品簇。比如 SMSHandlerFactory 工厂生产与 SMS 有关的产品簇的全系列产品。他们包括 SMSReceiver 与 SMSSender。
将来若需要进行产品等级的扩展,如加入了 Forwarder 类产品,我们不需要增加新的工厂类,仅需要在工厂接口中增加 Forwarder 的生产接口,再更改相应实现代码就可以了。
若将来需要进行产品簇的扩展,如增加了 PhoneSender,PhoneRecevier 系列产品,则仅需要增加一个 phoneFactory 就可以解决问题。而不需要更改原有代码。
也就是说,该设计模式再具备了一定的扩展性的同时,又尽可能的控制了类的大量扩张。

总结

  1. 工厂设计模式分为三类。简单工厂,工厂方法,抽象工厂。
  2. 简单工厂模式适合用于项目需求简单,产品很少并且几乎没有扩展可能性的情况。
  3. 工厂方法模式适合用于产品簇单一,但却经常发生改变的情况。
  4. 抽象工厂适合用于项目拥有多个产品簇,且产品等级经常发生改变,并且还需要尽可能控制项目体积的情况。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com