工厂模式分为:简单工厂模式、工厂方法模式、抽象工厂模式 Demo In gitee
简单工厂模式的构成:
工厂(Creator)角色:担任这个角色的是简单工厂模式的核心,含有与应用紧密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象,它往往由一个具体类实现。
抽象产品(Product)角色:担任这个角色的类时简单工厂模式所创建的对象的父类,或它们共同拥有的接口。抽象产品角色可以用一个接口或者抽象类实现。
具体产品(Concete Product)角色:简单工厂模式所创建的任何对象都是这个角色的实例,具体产品角色由一个具体类实现。
简单工厂模式
简单工厂模式的UML图:
简单工厂模式的实现:
网上很多的例子都是生产汽车的,我这里稍微做个改变,换汤不换药。写一个生产手机的简单工厂模式。
1、先创建一个抽象的产品类 Product
package org.burning.sport.design.pattern.factorypattern.one; /** * @ProjectName: base-project * @Description: 这里是个抽象类,也可以是个接口 * 这个抽象类定义了一个生产手机的方法, */ public abstract class Product { public abstract void mobilePhone(); }
2、分别创建两个具体产品类 XiaoMiProduct 和 IphoneProduct 都继承产品类 Product
package org.burning.sport.design.pattern.factorypattern.one; /** * @ProjectName: base-project */ public class XiaoMiProduct extends Product { @Override public void mobilePhone() { System.out.println("我是小米手机手机"); } }
package org.burning.sport.design.pattern.factorypattern.one; /** * @ProjectName: base-project */ public class IphoneProduct extends Product { @Override public void mobilePhone() { System.out.println("我是苹果手机手机"); } }
3、创建一个工厂类来Creater生产产品
package org.burning.sport.design.pattern.factorypattern.one; /** * @ProjectName: base-project */ public class Creator { public static Product createProduct(String str) { if("xiaomi".equals(str)) { return new XiaoMiProduct(); } else if("iphone".equals(str)) { return new IphoneProduct(); } return null; } }
4、创建Client来获取产品
package org.burning.sport.design.pattern.factorypattern.one; /** * *工厂模式的的最终目的是为了解耦 * @ProjectName: base-project * @Description: 工厂设计模式----简单工厂模式(静态工厂模式) */ public class ClientMain { public static void main(String[] args) { Product xiaomi = Creator.createProduct("xiaomi"); xiaomi.mobilePhone(); Product iphone = Creator.createProduct("iphone"); iphone.mobilePhone(); } }
总结:简单工厂模式非常简单,但是有个很大的缺点就是:我想再生产一台HUAWEI手机,那我是不是又得创建一个HUAWeiProduct.java? 然后在工厂
Creator.java中再进行 if...else 添加一个新的产品? 这样就会动老的代码。
工厂方法模式
定义:工厂方法模式是一种常见的对象创建型设计模式,此模式的核心精神是封装类中不变的部分提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的
工厂方法模式UML图
例子 一:
工厂方法模式,我们用生产汽车的例子来实现
1、先创建抽象产品角色: BMW.java
package org.burning.sport.design.pattern.factorypattern.two; /** * @ProjectName: base-project * @Description: 抽象产品角色 */ public abstract class BMW { public BMW() {} }
2、创建两个具体产品角色: BMW230.java BMW520.java
package org.burning.sport.design.pattern.factorypattern.two; /** * @ProjectName: base-project * @Description: 具体产品角色 */ public class BMW320 extends BMW { public BMW320() { System.out.println("宝马320初始化"); } }
package org.burning.sport.design.pattern.factorypattern.two; /** * * @ProjectName: base-project * @Description: 具体产品角色 */ public class BMW520 extends BMW { public BMW520() { System.out.println("宝马520初始化"); } }
3、创建一个抽象工厂角色: FactoryBMW.java
package org.burning.sport.design.pattern.factorypattern.two; /** * @ProjectName: base-project * @Description: 抽象工厂角色 */ public interface FactoryBMW { BMW createBMWCar(); }
4、根据业务创建具体工厂角色 BMW320Factory.java BMW520Factory.java
package org.burning.sport.design.pattern.factorypattern.two; /** * @ProjectName: base-project * @Description: 具体工厂角色 */ public class BMW320Factory implements FactoryBMW { @Override public BMW320 createBMWCar() { return new BMW320(); } }
package org.burning.sport.design.pattern.factorypattern.two; /** * @ProjectName: base-project * @Description: 具体工厂角色 */ public class BMW520Factory implements FactoryBMW { @Override public BMW520 createBMWCar() { return new BMW520(); } }
5、最后客户端"选择产品生产"
package org.burning.sport.design.pattern.factorypattern.two; /** * *工厂模式的的最终目的是为了解耦 * @ProjectName: base-project * @Description: 工厂设计模式----工厂方法模式 */ public class CustomerMain { public static void main(String[] args) { BMW320Factory bmwFactory320 = new BMW320Factory(); BMW320 bmw320 = bmwFactory320.createBMWCar(); System.out.println(bmw320); BMW520Factory bmwFactory520 = new BMW520Factory(); BMW520 bmw520 = bmwFactory520.createBMWCar(); System.out.println(bmw520); } }
例子二:
1、抽象产品类
package org.burning.sport.design.pattern.factorypattern.four; /** * 抽象产品角色 */ public abstract class Phone { //手机的公共方法,手机都可以打电话 public void call() { } //手机品牌 public abstract void brand(); }
2、具体产品,两个手机品牌华为和小米
package org.burning.sport.design.pattern.factorypattern.four; /** * 具体产品角色 */ public class HUAWEIPhone extends Phone { @Override public void brand() { System.out.println("华为品质值得信赖"); } }
package org.burning.sport.design.pattern.factorypattern.four; public class MIPhone extends Phone { @Override public void brand() { System.out.println("小米手机,全民的手机"); } }
3、抽象工厂类
package org.burning.sport.design.pattern.factorypattern.four; /** * 抽象工厂角色 */ public abstract class PhoneFactory { public abstract <T extends Phone> T createPhone(Class<T> c); }
4、具体工厂类
package org.burning.sport.design.pattern.factorypattern.four; /** * 具体手机工厂 */ public class ConcretePhoneFactory extends PhoneFactory{ @Override public <T extends Phone> T createPhone(Class<T> c) { Phone phone = null; try { phone = (Phone)Class.forName(c.getName()).newInstance(); System.out.println("工厂生产了一部手机"); phone.brand(); } catch (Exception e) { e.printStackTrace(); } return (T)phone; } }
5.客户端
package org.burning.sport.design.pattern.factorypattern.four; public class Client { public static void main(String[] args) { PhoneFactory factory = new ConcretePhoneFactory(); Phone huawei = factory.createPhone(HUAWEIPhone.class); Phone xiaomi = factory.createPhone(MIPhone.class); } }
总结:
缺点:虽然不用像简单工厂模式一样会改动老的代码,但是如果我的产品太多,那创建的具体产品角色和具体工厂角色就会很多,这个也不是我们所希望的。
抽象工厂模式
下面看一下抽象工厂模式使怎么实现的?我们还是用一个组装汽车的例子来做例子,汽车有发动机和空调等设备。我们工程就生产这两种设备。
一、创建两个抽象产品角色Engin.java和Aircondition.java
/** * 抽象产品角色 */ public interface Engine { }
/** * 抽象产品角色 */ public interface Aircondition { }
二、创建具体产品角色
public class EngineA implements Engine { public EngineA() { System.out.println("制造发动机------> A型号"); } }
public class EngineB implements Engine { public EngineB() { System.out.println("制造发动机-----> B 型号"); } }
public class AirconditionA implements Aircondition { public AirconditionA() { System.out.println("制造空调---->A型号"); } }
public class AirconditionB implements Aircondition { public AirconditionB() { System.out.println("制造空调----->B型号"); } }
三、创建抽象工厂角色AbstractFactory.java
public interface AbstractFactory { public Engine createEngine(); public Aircondition createAircondition(); }
四、创建具体抽象角色
public class FactoryBMW320 implements AbstractFactory{ @Override public Engine createEngine() { return new EngineA(); } @Override public Aircondition createAircondition() { return new AirconditionA(); } }
public class FactoryBMW520 implements AbstractFactory { @Override public Engine createEngine() { return new EngineB(); } @Override public Aircondition createAircondition() { return new AirconditionB(); } }
五、客户端生产产品
public class ClientMain { public static void main(String[] args) { AbstractFactory factory = new FactoryBMW320(); //BMW320产品线 factory.createEngine(); factory.createAircondition(); System.out.println("=============================="); //BMW520产品线 factory = new FactoryBMW520(); factory.createEngine(); factory.createAircondition(); } }
抽象工厂模式的特点:
当每个抽象产品都有多于一个的具体子类的时候(空调有型号A和B两种,发动机也有型号A和B两种),工厂角色怎么知道实例化哪一个子类呢?抽象工厂模式提供两个具体工厂角色(宝马320系列工厂和宝马230系列工厂),分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。简单的说就是一个工厂可以生产一种产品的不同型号。
总结:
第一个简单工厂模式,简单工厂模式需要在具体工厂角色用if...else...来判断生产哪种产品
第二个工厂方法模式,工厂方法模式,一个工厂对应一个产品,也就是说一个工厂只能生产一种产品
参考:
【1】微信,http://www.3xmq.com/article/1516676793462
【2】《设计模式之禅》