全球访问量最大的10个网站,广西壮锦网站建设策划书,代做毕业设计网站多少钱,建网站在哪里做广告什么是工厂模式
工厂模式#xff08;Factory Pattern#xff09;是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式#xff0c;它提供了一种创建对象的最佳方式。
工厂模式提供了一种将对象的实例化过程封装在工厂类中的方式。通过使用工厂模式#xff…什么是工厂模式
工厂模式Factory Pattern是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式它提供了一种创建对象的最佳方式。
工厂模式提供了一种将对象的实例化过程封装在工厂类中的方式。通过使用工厂模式可以将对象的创建与使用代码分离提供一种统一的接口来创建不同类型的对象。
在工厂模式中我们在创建对象时不会对客户端暴露创建逻辑并且是通过使用一个共同的接口来指向新创建的对象。
工厂模式可以分为三类简单工厂模式静态工厂模式、工厂方法模式 和 抽象工厂模式。
其中简单工厂模式严格上来说不属于23设计模式之一因为它违背了开闭原则更好的是看作为一种编程方式。
本篇中会介绍三种工厂的使用也就是
简单静态工厂模式不属于GOF的23种经典设计模式工厂方法模式抽象工厂模式
使用场景
日志记录器记录可能记录到本地硬盘、系统事件、远程服务器等用户可以选择记录日志到什么地方。
数据库访问当用户不知道最后系统采用哪一类数据库以及数据库可能有变化时。
等等。。。
下面我们模拟手机工厂生产手机。。。
核心角色
抽象产品定义了产品的共同接口或抽象类。它可以是具体产品类的父类或接口规定了产品对象的共同方法。具体产品实现了抽象产品接口定义了具体产品的特定行为和属性。抽象工厂声明了创建产品的抽象方法可以是接口或抽象类。它可以有多个方法用于创建不同类型的产品。具体工厂实现了抽象工厂接口负责实际创建具体产品的对象。
1.简单静态工厂模式
实现了抽象工厂接口负责实际创建具体产品的对象。
结构
简单工厂包含如下角色
抽象产品定义了产品的规范描述了产品的主要特性和功能。具体产品实现或者继承抽象产品的子类具体工厂提供了创建产品的方法调用者通过该方法来获取产品。
示例
模拟手机工厂生产手机。
我们需要定义一个抽象手机产品定义手机产品的品牌和颜色两个方法
/*** 手机产品抽象类** author jiangkd* date 2023/7/28 14:03:15*/
public abstract class AbstractPhone {/*** 手机品牌*/public abstract void brand();/*** 手机颜色*/public abstract void color();}然后有两个具体产品一加和真我哈哈哈
/*** 具体手机产品, 一加手机** author jiangkd* date 2023/7/28 14:06:17*/
Slf4j
public class YijiaPhone extends AbstractPhone {Overridepublic void brand() {log.info(品牌, 一加手机!!!);}Overridepublic void color() {log.info(黑色!!!);}}/*** 具体手机产品, 真我手机** author jiangkd* date 2023/7/28 14:07:27*/
Slf4j
public class ZhenwoPhobe extends AbstractPhone {Overridepublic void brand() {log.info(品牌, 真我手机!!!);}Overridepublic void color() {log.info(白色!!!);}}产品有了现在我们创建一个手机工厂可以根据不同参数创建不同品牌手机
/*** 手机产品的工厂** author jiangkd* date 2023/7/28 14:09:50*/
public class PhoneFactory {/*** 具体如何产生一个产品的对象是由具体的工厂类实现的* p* 注意, 这里是静态方法** param clazz* return AbstractPhone* throws Exception e*/public static AbstractPhone createPhone(Class clazz) throws Exception {// 全限定类名final String name clazz.getName();// 根据反射, 创建具体产品对象return (AbstractPhone) Class.forName(name).newInstance();}/*** 当前方法其实和createPhone方法是一样的作用, 两个方法用哪个都可以* p* 注意, 这里是静态方法** param brand 根据参数区分创建哪个具体产品* return AbstractPhone*/public static AbstractPhone createPhone2(String brand) throws Exception {if (CharSequenceUtil.equals(yijia, brand)) {return new YijiaPhone();} else if (CharSequenceUtil.equals(zhenwo, brand)) {return new ZhenwoPhobe();} else {throw new Exception(参数异常!!!);}}}测试一下
/*** author jiangkd* date 2023/7/28 14:17:25*/
Slf4j
public class DemoTest {public static void main(String[] args) throws Exception {// 创建一加手机AbstractPhone yijiaPhone PhoneFactory.createPhone(YijiaPhone.class);yijiaPhone.brand();yijiaPhone.color();log.info(--------------------------------);yijiaPhone PhoneFactory.createPhone2(yijia);yijiaPhone.brand();yijiaPhone.color();log.info(--------------------------------);// 创建真我手机AbstractPhone zhenwoPhone PhoneFactory.createPhone(ZhenwoPhobe.class);zhenwoPhone.brand();zhenwoPhone.color();log.info(--------------------------------);zhenwoPhone PhoneFactory.createPhone2(zhenwo);zhenwoPhone.brand();zhenwoPhone.color();}}运行结果如下 14:19:59.846 [main] INFO demo.basic.example.design_patterns.gcms.jdgcms.YijiaPhone - 品牌, 一加手机!!! 14:19:59.851 [main] INFO demo.basic.example.design_patterns.gcms.jdgcms.YijiaPhone - 黑色!!! 14:19:59.851 [main] INFO demo.basic.example.design_patterns.gcms.jdgcms.DemoTest - -------------------------------- 14:19:59.882 [main] INFO demo.basic.example.design_patterns.gcms.jdgcms.YijiaPhone - 品牌, 一加手机!!! 14:19:59.882 [main] INFO demo.basic.example.design_patterns.gcms.jdgcms.YijiaPhone - 黑色!!! 14:19:59.882 [main] INFO demo.basic.example.design_patterns.gcms.jdgcms.DemoTest - -------------------------------- 14:19:59.882 [main] INFO demo.basic.example.design_patterns.gcms.jdgcms.ZhenwoPhobe - 品牌, 真我手机!!! 14:19:59.882 [main] INFO demo.basic.example.design_patterns.gcms.jdgcms.ZhenwoPhobe - 白色!!! 14:19:59.882 [main] INFO demo.basic.example.design_patterns.gcms.jdgcms.DemoTest - -------------------------------- 14:19:59.882 [main] INFO demo.basic.example.design_patterns.gcms.jdgcms.ZhenwoPhobe - 品牌, 真我手机!!! 14:19:59.882 [main] INFO demo.basic.example.design_patterns.gcms.jdgcms.ZhenwoPhobe - 白色!!! 其实可以看出来这里我们只有两个具体的手机产品简答静态工厂模式还是很方便的但你有没有发现如果现在我陆陆续续追加其他具体产品 红米努比亚荣耀那么我就要陆陆续续三次修改手机工厂类追加具体产品不算修改是扩展功能的功能这显然不符合java设计模式的六大原则-开闭原则。
那不如我们把工厂拆开每个工厂只生产一种具体的手机产品这样如果我需要增加一个红米就只需要添加一个红米工厂和一个红米产品类就可以了这就是接下来要演示的工厂方法模式
2.工厂方法模式
简单工厂模式确实很方便但是每次新增一个手机产品都需要改动整个工厂的原有代码现在使用工厂方法模式改造一下。
抽象手机产品AbstractPhone 和 两个具体的手机产品一加真我不变依然如上。
工厂类PhoneFactory不要了我们需要重新创建工厂类。
现在我们首先创建一个抽象工厂类用来生产AbstractPhone
/*** 定义产品的抽象工厂类** author jiangkd* date 2023/7/28 14:43:04*/
public abstract class AbstractPhoneFactory {/*** 构建产品, 具体实现交给子类** return AbstractPhone*/abstract AbstractPhone createPhone();}然后分别是一加手机和真我手机的两个具体工厂实现类每个实现类针对一个具体手机品牌的生产
/*** 具体产品一加手机的工厂实现类** author jiangkd* date 2023/7/28 14:44:53*/
public class YijiaPhoneFactory extends AbstractPhoneFactory {OverrideAbstractPhone createPhone() {return new YijiaPhone();}}/*** 具体产品真我手机的工厂实现类** author jiangkd* date 2023/7/28 14:45:35*/
public class ZhenwoPhoneFactory extends AbstractPhoneFactory {OverrideAbstractPhone createPhone() {return new ZhenwoPhobe();}}测试一下
/*** author jiangkd* date 2023/7/28 14:46:16*/
Slf4j
public class DemoTest {public static void main(String[] args) {// 生产一加手机final AbstractPhoneFactory yijiaPhoneFactory new YijiaPhoneFactory();final AbstractPhone yijiaPhone yijiaPhoneFactory.createPhone();yijiaPhone.brand();yijiaPhone.color();log.info(--------------------------------);// 生产真我手机final AbstractPhoneFactory zhenwoPhoneFactory new ZhenwoPhoneFactory();final AbstractPhone zhenwoPhone zhenwoPhoneFactory.createPhone();zhenwoPhone.brand();zhenwoPhone.color();}}运行结果如下 14:48:22.596 [main] INFO demo.basic.example.design_patterns.gcms.YijiaPhone - 品牌, 一加手机!!! 14:48:22.598 [main] INFO demo.basic.example.design_patterns.gcms.YijiaPhone - 黑色!!! 14:48:22.598 [main] INFO demo.basic.example.design_patterns.gcms.gcffms.DemoTest - -------------------------------- 14:48:22.599 [main] INFO demo.basic.example.design_patterns.gcms.ZhenwoPhobe - 品牌, 真我手机!!! 14:48:22.599 [main] INFO demo.basic.example.design_patterns.gcms.ZhenwoPhobe - 白色!!! 现在我们如果想要加一个红米手机只需要创建具体红米产品和对应的工厂类就可以了
/*** 具体手机产品 红米** author jiangkd* date 2023/7/28 14:51:09*/
Slf4j
public class HongmiPhone extends AbstractPhone {Overridepublic void brand() {log.info(品牌, 红米手机!!!);}Overridepublic void color() {log.info(红色!!!);}}/*** 红米手机工厂实现类** author jiangkd* date 2023/7/28 14:52:04*/
public class HongmiPhoneFactory extends AbstractPhoneFactory {OverrideAbstractPhone createPhone() {return new HongmiPhone();}}测试
/*** author jiangkd* date 2023/7/28 14:46:16*/
Slf4j
public class DemoTest {public static void main(String[] args) {// 生产一加手机final AbstractPhoneFactory yijiaPhoneFactory new YijiaPhoneFactory();final AbstractPhone yijiaPhone yijiaPhoneFactory.createPhone();yijiaPhone.brand();yijiaPhone.color();log.info(--------------------------------);// 生产真我手机final AbstractPhoneFactory zhenwoPhoneFactory new ZhenwoPhoneFactory();final AbstractPhone zhenwoPhone zhenwoPhoneFactory.createPhone();zhenwoPhone.brand();zhenwoPhone.color();log.info(--------------------------------);// 生产红米手机final AbstractPhoneFactory hongmiPhoneFactory new HongmiPhoneFactory();final AbstractPhone hongmiPhone hongmiPhoneFactory.createPhone();hongmiPhone.brand();hongmiPhone.color();}}执行结果 14:53:43.272 [main] INFO demo.basic.example.design_patterns.gcms.YijiaPhone - 品牌, 一加手机!!! 14:53:43.274 [main] INFO demo.basic.example.design_patterns.gcms.YijiaPhone - 黑色!!! 14:53:43.274 [main] INFO demo.basic.example.design_patterns.gcms.gcffms.DemoTest - -------------------------------- 14:53:43.276 [main] INFO demo.basic.example.design_patterns.gcms.ZhenwoPhobe - 品牌, 真我手机!!! 14:53:43.276 [main] INFO demo.basic.example.design_patterns.gcms.ZhenwoPhobe - 白色!!! 14:53:43.276 [main] INFO demo.basic.example.design_patterns.gcms.gcffms.DemoTest - -------------------------------- 14:53:43.276 [main] INFO demo.basic.example.design_patterns.gcms.HongmiPhone - 品牌, 红米手机!!! 14:53:43.276 [main] INFO demo.basic.example.design_patterns.gcms.HongmiPhone - 红色!!! 符合开闭原则不修改原来的功能只是添加产品和工厂类就可以了。
细心的小伙伴又会问了虽然不用在原基础功能上修改但是如果还要添加10个品牌手机岂不是要加10个产品类和10个工厂类增加维护难度呀是的这就是工厂方法模式的弊端增加系统的复杂度。
所以你可以看出简单静态工厂和工厂方法模式都是针对一类产品的生产也就是这些工厂只生产同种类产品同种类产品称为同等级产品。工厂方法模式只考虑生产同等级的产品
但实际上呢现实生活中许多工厂是综合型的工厂能生产多等级种类 的产品如电器厂既生产电视机又生产洗衣机或空调大学既有软件专业又有生物专业等。
这就是下面的抽象工厂模式了。。。我们继续延申现在老板发话了生产手机的时候顺便把耳机也生产出来吧
3.抽象工厂模式
由于篇幅问题继续查看java设计模式-工厂模式下