工厂模式
1 基本概念
1、本质
- 实例化对象不使用new,用工厂方法代替。
- 将选择实现类、创建对象统一管理和控制,从而将调用者与实现类解耦。
2、作用
- 实现创建者和调用者的分离。
3、分类
- 简单工厂模式:用来生产同一等级结构中的任意产品(对于增加新的产品,需要覆盖已有代码)。
- 工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)。
- 抽象工厂模式:围绕一个超级工厂创建其他工厂。该工厂又称为其他工厂的工厂。
4、OOP七大原则
- 开闭原则:一个软件的实体应当对扩展开放,对修改关闭。
- 依赖倒转原则:要针对接口编程,不要针对实现编程。
- 迪米特法则:只与直接的朋友通信,而避免和陌生人通信。
2 分类
1、简单工厂模式(静态工厂模式)
Car
package factory.simple; public interface Car { void name(); }
WuLing
package factory.simple; public class WuLing implements Car { @Override public void name() { System.out.println("WuLing"); } }
Tesla
package factory.simple; public class Tesla implements Car { @Override public void name() { System.out.println("Tesla"); } }
CarFactory
package factory.simple; public class CarFactory { public static Car getCar(String car) { if ("WuLing".equals(car)) { return new WuLing(); } if ("Tesla".equals(car)) { return new Tesla(); } return null; } }
Consumer
package factory.simple; import org.junit.Test; public class Consumer { @Test public void test() { // 1、使用new创建(需要知道接口,所有的实现类) Car car01 = new WuLing(); Car car02 = new Tesla(); car01.name(); car02.name(); // 2、使用工厂创建 Car wuLing = CarFactory.getCar("WuLing"); wuLing.name(); } }
Dazhong(新增Car,需要同时修改CarFactory源码)
package factory.simple; public class Dazhong implements Car { @Override public void name() { System.out.println("Dazhong"); } }
2、工厂方法模式
Car
package factory.simple; public interface Car { void name(); }
WuLing
package factory.simple; public class WuLing implements Car { @Override public void name() { System.out.println("WuLing"); } }
Tesla
package factory.simple; public class Tesla implements Car { @Override public void name() { System.out.println("Tesla"); } }
CarFactory
package factory.method; public interface CarFactory { Car getCar(); }
WuLingFactory
package factory.method; public class WuLingFactory implements CarFactory { @Override public Car getCar() { return new WuLing(); } }
TeslaFactory
package factory.method; public class TeslaFactory implements CarFactory { @Override public Car getCar() { return new Tesla(); } }
MoBai(新增Car)
package factory.method; public class MoBai implements Car { @Override public void name() { System.out.println("MoBai"); } }
MoBaiFactory(提供相应的工厂)
package factory.method; public class MoBaiFactory implements CarFactory { @Override public Car getCar() { return new MoBai(); } }
Consumer
package factory.method; import org.junit.Test; public class Consumer { @Test public void test() { Car car01 = new WuLingFactory().getCar(); Car car02 = new TeslaFactory().getCar(); car01.name(); car02.name(); Car car03 = new MoBaiFactory().getCar(); car03.name(); } }
3、抽象工厂模式
1、定义
- 抽象工厂模式提供了创建一系列相关或者相互依赖对象的接口,无须指定它们具体的类。
2、适用场景
- 客户端(应用层)不依赖于产品实例如何被创建、实现等细节。
- 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现。
3、优点
- 具体产品在应用层的代码隔离,无须关心创建的细节。
- 将一个系列的产品统一到一起创建。
4、缺点
- 规定了所有可能被创建的产品集合,产品簇中扩展新的产品困难。
- 增加了系统的抽象性和理解难度。
5、代码
IProductFactory
package factory.abstract1; /** * 抽象产品工厂 */ public interface IProductFactory { // 生产手机 IphoneProduct iphoneProduct(); // 生产路由器 IRouterProduct routerProduct(); }
IphoneProduct
package factory.abstract1; /** * 手机产品接口 */ public interface IphoneProduct { void start(); void shutdown(); void callup(); void sendMS(); }
IRouterProduct
package factory.abstract1; /** * 路由器产品接口 */ public interface IRouterProduct { void start(); void shutdown(); void openWifi(); void setting(); }
XiaomiPhone
package factory.abstract1; /** * 小米手机 */ public class XiaomiPhone implements IphoneProduct { @Override public void start() { System.out.println("开启小米手机"); } @Override public void shutdown() { System.out.println("关闭小米手机"); } @Override public void callup() { System.out.println("小米打电话"); } @Override public void sendMS() { System.out.println("小米发短信"); } }
XiaomiRouter
package factory.abstract1; /** * 小米路由器 */ public class XiaomiRouter implements IRouterProduct { @Override public void start() { System.out.println("启动小米路由器"); } @Override public void shutdown() { System.out.println("关闭小米路由器"); } @Override public void openWifi() { System.out.println("打开小米Wifi"); } @Override public void setting() { System.out.println("小米路由器设置"); } }
HuaweiPhone
package factory.abstract1; /** * 华为手机 */ public class HuaweiPhone implements IphoneProduct { @Override public void start() { System.out.println("开启华为手机"); } @Override public void shutdown() { System.out.println("关闭华为手机"); } @Override public void callup() { System.out.println("华为打电话"); } @Override public void sendMS() { System.out.println("华为发短信"); } }
HuaweiRouter
package factory.abstract1; /** * 华为路由器 */ public class HuaweiRouter implements IRouterProduct { @Override public void start() { System.out.println("启动华为路由器"); } @Override public void shutdown() { System.out.println("关闭华为路由器"); } @Override public void openWifi() { System.out.println("打开华为Wifi"); } @Override public void setting() { System.out.println("华为路由器设置"); } }
XiaomiFactory
package factory.abstract1; public class XiaomiFactory implements IProductFactory { @Override public IphoneProduct iphoneProduct() { return new XiaomiPhone(); } @Override public IRouterProduct routerProduct() { return new XiaomiRouter(); } }
HuaweiFactory
package factory.abstract1; public class HuaweiFactory implements IProductFactory { @Override public IphoneProduct iphoneProduct() { return new HuaweiPhone(); } @Override public IRouterProduct routerProduct() { return new HuaweiRouter(); } }
Client
package factory.abstract1; import org.junit.Test; public class Client { @Test public void test() { System.out.println("=====小米系列产品====="); // 小米工厂 XiaomiFactory xiaomiFactory = new XiaomiFactory(); IphoneProduct iphoneProduct = xiaomiFactory.iphoneProduct(); iphoneProduct.callup(); iphoneProduct.sendMS(); IRouterProduct iRouterProduct = xiaomiFactory.routerProduct(); iRouterProduct.openWifi(); System.out.println("=====华为系列产品====="); // 华为工厂 HuaweiFactory huaweiFactory = new HuaweiFactory(); IphoneProduct iphoneProduct1 = huaweiFactory.iphoneProduct(); iphoneProduct1.callup(); IRouterProduct iRouterProduct1 = huaweiFactory.routerProduct(); iRouterProduct1.openWifi(); } }
3 小结
3.1 对比
1、简单工厂模式(静态工厂模式)
- 虽然某种程度上不符合设计原则,但实际使用最多。
2、工厂方法模式
- 不修改已有类的前提下,通过增加新的工厂类实现扩展。
3、抽象工厂模式
- 不可以增加产品,可以增加产品族。
3.2 应用场景
- JDK中的Calendar、Connection。
- Spring中IOC容器创建管理Bean对象。
- 反射中Class对象的newInstance方法。