工厂模式有三种模式:
- 简单工厂模式
能够扩展同一级别的任意产品。 - 工厂方法模式
不修改已有类的前提下,通过增加新的工厂类来实现扩展。 - 抽象工厂模式
不可以增加产品,可以增加产品族。
简单工厂 (静态工厂模式)
比方说:我们现在有个需求,实现几种口味的蛋糕并且实现对这些蛋糕的订购功能。
目前我们的蛋糕有三种,代码也已经实现完了。这时突然要增加一种口味的蛋糕,除了要添加一个类外,三个订单功能类也要修改。也就是在订单类中增加多一个if-else。而在现实生活中,我们的订单远远超出三个。这样一处改,处处都得改,降低开发效率,违反了设计模式的ocp原则,即对扩展开放,对修改关闭。
而静态工厂模式就是由一个工厂对象统一创建所有口味的蛋糕实例。就是将蛋糕选择的判断生成交由工厂去实现。但我们新增一种口味蛋糕时,只需要在工厂类中添加即可,然后在需要用到的订单功能类调用工厂类来获取就好了。
//同一等级蛋糕结构,可以进行扩展 public interface Cake { void make(); void cut(); } //具体的蛋糕实例 public class GreekCake implements Cake{ @Override public void make() { System.out.println("GreekCake制作完成"); } @Override public void cut() { System.out.println("GreekCake已切块"); } } //统一创建蛋糕实例的工厂 public class CakeFactory { //方法一 public static Cake getCake(String cake){ if ( cake.equals("GreekCake")) { return new GreekCake(); }else if ( cake.equals("SweetCake")){ return new SweetCake(); }else{ return null; } } //方法二 public static Cake getGreekCake(){ return new GreekCake(); } public static Cake getSweetCake(){ return new SweetCake(); } } //用户订单,多个 public class Order1 { public static void main(String[] args) { Cake greekCake = CakeFactory.getGreekCake(); Cake sweetCake = CakeFactory.getSweetCake(); greekCake.make(); greekCake.cut(); } }
工厂方法模式
定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
比如我们想要不同地方不同口味的蛋糕,我们需要在不同地方设立工厂,一个工厂能够创建出不同口味的蛋糕实例。当某个工厂要新增口味时,对其他工厂不影响。
代码实现:(蛋糕接口和蛋糕类省略)
//工厂接口 public interface Factory { Cake getGreekCake(); Cake getSweetCake(); } //不同的工厂 public class BeijingFactory implements Factory{ @Override public Cake getGreekCake() { return new GreekCake(); } @Override public Cake getSweetCake() { return new SweetCake(); } } public class XianFactory implements Factory{ @Override public Cake getGreekCake() { return new GreekCake(); } @Override public Cake getSweetCake() { return new SweetCake(); } //可以新增任意一种口味的蛋糕 }
抽象工厂模式
抽象工厂模式可以为我们的工厂增加产品族。
比方说,有家电子公司,它负责生产两个牌子的手机和路由器,于是设立了两个牌子的工厂,如下图所示:
此时,如果这家公司想要扩大业务,想生产数据线,那只需要添加一个产品接口或者抽象类即可。
代码实现:
public interface IphoneProduct { void start(); void shutdown(); void callup(); void sendSMS(); } 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 sendSMS() { System.out.println("小米发短信"); } } 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 sendSMS() { System.out.println("华为手机发短信"); } } public interface IRouterProduct { void start(); void shutdown(); void openWifi(); void setting(); } 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("小米设置参数"); } } 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("华为设置参数"); } } //抽象产品工厂 public interface IProductFactory { //生成手机 IphoneProduct iphoneProduct(); //生产路由器 IRouterProduct iRouterProduct(); } public class HuaweiFactory implements IProductFactory{ @Override public IphoneProduct iphoneProduct() { return new HuaweiPhone(); } @Override public IRouterProduct iRouterProduct() { return new HuaweiRouter(); } } public class XiaomiFactory implements IProductFactory{ @Override public IphoneProduct iphoneProduct() { return new XiaomiPhone(); } @Override public IRouterProduct iRouterProduct() { return new XiaomiRouter(); } } //客户 public class Client { public static void main(String[] args) { System.out.println("==========小米系列产品============="); //小米工厂 XiaomiFactory xiaomiFactory = new XiaomiFactory(); IphoneProduct iphoneProduct = xiaomiFactory.iphoneProduct(); iphoneProduct.callup(); iphoneProduct.sendSMS(); IRouterProduct iRouterProduct = xiaomiFactory.iRouterProduct(); iRouterProduct.openWifi(); iRouterProduct.setting(); System.out.println("===========华为系列产品==========="); //华为工厂 HuaweiFactory huaweiFactory = new HuaweiFactory(); iphoneProduct = huaweiFactory.iphoneProduct(); iphoneProduct.callup(); iphoneProduct.sendSMS(); iRouterProduct = huaweiFactory.iRouterProduct(); iRouterProduct.openWifi(); iRouterProduct.setting(); } }
应用场景
- JDK中Calender的getInstance方法用了简单工厂模式思想
- JDBC的Connection对象的获取
- Spring中IOC容器创建管理bean对象利用了简单工厂模式
- 反射中Class对象的newInStance方法
工厂模式将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。