工厂模式(Factory Pattern)

工厂模式分为:简单(静态)工厂模式、工厂方法模式、抽象工厂模式

简单工厂模式的构成:

工厂(Creator):担任这个角色的是简单工厂模式的核心,含有与应用紧密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象,它往往由一个具体类实现。

抽象产品(Product):担任这个角色的类时简单工厂模式所创建的对象的父类,或它们共同拥有的接口。抽象产品角色可以用一个接口或者抽象类实现。

具体产品(Concete Product):简单工厂模式所创建的任何对象都是这个角色的实例,具体产品角色由一个具体类实现。

1、简单工厂模式:

简单工厂模式的UML图

简单工厂模式的实现

  网上很多的例子都是生产汽车的,我这里稍微做个改变,换汤不换药。写一个生产手机的简单工厂模式。

1.1、先创建一个抽象的产品类 Product

复制代码
package org.burning.sport.design.pattern.factorypattern.one;

/**
 *  @ProjectName: base-project 
 *  @Description: 这里是个抽象类,也可以是个接口
 *                 这个抽象类定义了一个生产手机的方法,
 */
public abstract class Product {
    public abstract void mobilePhone();
}
复制代码

1.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("我是苹果手机手机");
    }
}
复制代码

1.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;
    }
}
复制代码

1.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 添加一个新的产品? 这样就会动老的代码(违反开闭-原则)。

2、工厂方法模式

定义:工厂方法模式是一种常见的对象创建型设计模式,此模式的核心精神是封装类中不变的部分提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的

工厂方法模式UML图

 

2.1 例子一:

我们用生产汽车的例子来实现

2.1.1 先创建抽象产品角色:  BMW.java

复制代码
package org.burning.sport.design.pattern.factorypattern.two;

/**
 *  @ProjectName: base-project 
 *  @Description: 抽象产品角色
 */
public abstract class BMW {
    public BMW() {}
}
复制代码

2.1.2 创建两个具体产品角色: BMW320.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初始化");
    }
}
复制代码

2.1.3 创建一个抽象工厂角色: FactoryBMW.java

复制代码
package org.burning.sport.design.pattern.factorypattern.two;

/**
 *  @ProjectName: base-project 
 *  @Description: 抽象工厂角色
 */
public interface FactoryBMW {
    BMW createBMWCar();
}
复制代码

2.1.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();
    }
}
复制代码

2.1.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);
    }
}
复制代码

 2.2 例子二

2.2.1 抽象产品类

复制代码
package org.burning.sport.design.pattern.factorypattern.four;
/**
 * 抽象产品角色
 */
public abstract class Phone {
    //手机的公共方法,手机都可以打电话
    public void call() {
    }
    //手机品牌
    public abstract void brand();
}
复制代码

2.2.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("小米手机,全民的手机");
    }

}
复制代码

2.2.3 抽象工厂类

package org.burning.sport.design.pattern.factorypattern.four;
/**
 * 抽象工厂角色
 */
public abstract class PhoneFactory {
    public abstract <T extends Phone> T createPhone(Class<T> c);
}

2.2.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;
    }

}
复制代码

2.2.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);
    }
}
复制代码

总结:

  缺点:虽然不用像简单工厂模式一样会改动老的代码,但是如果我的产品太多,那创建的具体产品角色和具体工厂角色就会很多,这个也不是我们所希望的。

3、抽象工厂模式

下面看一下抽象工厂模式使怎么实现的?我们还是用一个组装汽车的例子来做例子,汽车有发动机和空调等设备。我们工程就生产这两种设备。

3.1 创建两个抽象产品角色Engin.java和Aircondition.java

/**
 * 抽象产品角色
 */
public interface Engine {
}
/**
 * 抽象产品角色
 */
public interface Aircondition {
}

3.2 创建具体产品角色

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型号");
    }
}

3.3 创建抽象工厂角色AbstractFactory.java

public interface AbstractFactory {
    public Engine createEngine();
    public Aircondition createAircondition();
}

3.4 创建具体抽象角色

复制代码
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();
    }
}
复制代码

3.5 客户端生产产品

复制代码
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】《设计模式之禅》

posted @   寻找风口的猪  阅读(557)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示