设计模式之 简单工厂模式

简单工厂模式基本介绍:

1:简单工厂模式时属于创建型模式,是工厂模式的一种,简单工厂模式时由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式时工厂模式家族中最简单实用的模式。

2:简单工厂模式,定义了一个创建对象的类,有这个类来封装实例化对象的行为(代码)。

3:在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式

工厂方法(FactoryMethod)模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。者满足创建型模式中所要求的“创建与使用相分离”的特点。

我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”,它不属于GOF 的23种经典设计模式,他的缺点是增加新产品时会违背“开闭原则”。
本节介绍的“工厂方法模式”是对简单工厂模式的进一步抽象化,其好处是可以是使系统在不修改原来的代码的情况下引进新的产品,即满足开闭原则。

工厂模式的主要优点有:

  1)用户只需要知道具体工厂的名称就可以得到所需要的产品,无需知道产品的具体创建过程。
    如:你只需要知道 格力 是做空调的,小米是做手机的,但是他们怎么做到,就不需要你关心了。

  2)在系统增加新产品时只需要添加具体的产品类和对应的具体工厂,无须对原工厂进行任何修改,满足开闭原则。
    其缺点是:没增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。

 模式的结构:

工厂方法模式的主要角色如下:
1)抽象工厂(AbstractFactory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 new Product() 来创建产品。。 2)具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。 3)抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。 4)具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

 


 

传统模式——案例说明:

我有一个军工企业,我们是生成军火的,我们旗下有很多工厂,能上天的有飞机导弹、能下海的有轮船、两栖登陆舰 等等。甚至 手枪、手雷我们都有工厂进行生成——吹牛又不交钱。但是在建厂的时候我并没有学习设计模式,我的工厂是这样建设的。

1)先建 几个厂 (如:飞机、大炮、手枪工厂)
2)获取订单后,通知对应的工厂进行生产和交付。

传统模式——代码展示:

/**
 * 飞机工厂
 */
public class AircraftFactory{

    /**
     * 生产飞机
     */
    public void generate(){
        System.out.println("正在生产飞机...");
    }

    /**
     * 交付飞机
     */
    void deliver() {
        System.out.println("正在交付飞机...");
    }
}

/**
 * 大炮工厂
 */
public class CannonFactory{

    /**
     * 生产大炮
     */
    public void generate(){
        System.out.println("正在生产大炮...");
    }

    /**
     * 交付大炮
     */
    void deliver() {
        System.out.println("正在交付大炮...");
    }
}

/**
 * 手枪工厂
 */
public class PistolFactory {

    /**
     * 生产手枪
     */
    public void generate(){
        System.out.println("正在生产手枪...");
    }

    /**
     * 交付手枪
     */
    void deliver() {
        System.out.println("正在交付手枪...");
    }
}

/**
 * 订单
 */
public class Order {

    private String type;

    public Order(String type){
        this.type=type;
    }

    /**
     * 通知 工厂生产产品,并且进行交付
     */
    public void notice(){
        if("飞机".equals(type)){
            AircraftFactory arsenal=new AircraftFactory();
            //生产
            arsenal.generate();
            //交付
            arsenal.deliver();
        }else if("大炮".equals(type)){
            CannonFactory arsenal=new CannonFactory();
            //生产
            arsenal.generate();
            //交付
            arsenal.deliver();
        }if("手枪".equals(type)){
            PistolFactory arsenal=new PistolFactory();
            //生产
            arsenal.generate();
            //交付
            arsenal.deliver();
        }

    }

}

/**
 * 客户端,接待用户
 */
public class Client {

    public static void main(String[] args) {
        //获取订单
        Order order=new Order("大炮");
        //通知工厂进行生产
        order.notice();
    }
}

//运行结果
正在生产大炮...
正在交付大炮...

传统模式的优缺点:

1) 优点:比较好理解,简单容易操作
2) 缺点:违反了设计模式的OCP原则,即多扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不要修改代码,或者尽可能少修改代码。

 简答工厂模式——案例说明:

由于我的公司生产的军工产品品质一致好评,获得很多企业的好评,所以订单也越来越多,慢慢发现我之前的工厂设计有问题。扩容性太差,改动配置地方太多了。
如果我要生产坦克,我不仅要建一个坦克厂,也要新增一个坦克状态。于是我找了一个懂设计模式的人帮我设计。他给我的设计方案是这样的。

每个工厂生产模式都是一样的 先进行 generate(生产) 再进行 deliver(交付) ,这里我们只要统一的管理起来就行了。
听了设计师的话,我就建立一个 兵工厂抽象类,其他工厂都先继承兵工厂,实现兵工厂的 generate() 再进行 deliver()。 到最后不论是 生产和交付,我只需要找兵工厂这个抽象类即可。

注:不一定是抽象类,接口也行。

 简答工厂模式——代码展示:

/**
 * 兵工厂
 * 抽象工厂
 */
public abstract class Arsenal {
    /**
     * 生产 商品
     */
    abstract void generate();

    /**
     * 交付商品
     */
    abstract void deliver();

}

/**
 * 大炮工厂
 */
public class CannonFactory  extends Arsenal{

    /**
     * 生产大炮
     */
    @Override
    public void generate(){
        System.out.println("正在生产大炮...");
    }

    /**
     * 交付大炮
     */
    @Override
    void deliver() {
        System.out.println("正在交付大炮...");
    }
}

/**
 * 飞机工厂
 */
public class AircraftFactory extends Arsenal{

    /**
     * 生产飞机
     */
    @Override
    public void generate(){
        System.out.println("正在生产飞机...");
    }

    /**
     * 交付飞机
     */
    @Override
    void deliver() {
        System.out.println("正在交付飞机...");
    }
}

/**
 * 手枪工厂
 */
public class PistolFactory  extends Arsenal{

    /**
     * 生产手枪
     */
    @Override
    public void generate(){
        System.out.println("正在生产手枪...");
    }

    /**
     * 交付手枪
     */
    @Override
    void deliver() {
        System.out.println("正在交付手枪...");
    }
}

/**
 * 订单
 */
public class Order {

    private String type;

    public Order(String type){
        this.type=type;
    }

    /**
     * 通知 工厂生产产品,并且进行交付
     */
    public Arsenal notice(){
        Arsenal arsenal=null;
        if("飞机".equals(type)){
            arsenal=new AircraftFactory();
        }else if("大炮".equals(type)){
            arsenal=new CannonFactory();
        }if("手枪".equals(type)){
            arsenal=new PistolFactory();
        }
        return arsenal;
    }
}

/**
 * 客户端,接待用户
 */
public class Client {
    public static void main(String[] args) {
        //获取订单
        Order order=new Order("大炮");
        //通知工厂进行生产
        Arsenal arsenal= order.notice();
        //生产
        arsenal.generate();
        //交付
        arsenal.deliver();
    }
}

//运行结果
正在生产大炮...
正在交付大炮...

若获取一个新订单(如坦克 订单),我们只需要这样。

/**
 * 坦克工厂
 */
public class TankFactory extends  Arsenal{
    /**
     * 生产坦克
     */
    @Override
    public void generate(){
        System.out.println("正在生产坦克...");
    }

    /**
     * 交付坦克
     */
    @Override
    void deliver() {
        System.out.println("正在交付坦克...");
    }
}

/**
 * 订单
 */
public class Order {

    private String type;

    public Order(String type){
        this.type=type;
    }

    /**
     * 通知 工厂生产产品,并且进行交付
     */
    public Arsenal notice(){
        Arsenal arsenal=null;
        if("飞机".equals(type)){
            arsenal=new AircraftFactory();
        }else if("大炮".equals(type)){
            arsenal=new CannonFactory();
        }if("手枪".equals(type)){
            arsenal=new PistolFactory();
        }else if("坦克".equals(type)){
            arsenal=new TankFactory();
        }

        return arsenal;
    }

}

/**
 * 客户端,接待用户
 */
public class Client {

    public static void main(String[] args) {
        //获取订单
        Order order=new Order("坦克");
        //通知工厂进行生产
        Arsenal arsenal= order.notice();
        //生产
        arsenal.generate();
        //交付
        arsenal.deliver();

    }
}

//运行结果
正在生产坦克...
正在交付坦克...

静态工厂模式:

简单工厂模式也叫静态方法工厂模式
就是将创建 工厂的 方法定义成了静态的方法,这样的好处就是调用方便。

代码展示

/**
 * 订单
 */
public class Order {

    /**
     * 通知 工厂生产产品,并且进行交付
     */
    public static Arsenal notice(String type){
        Arsenal arsenal=null;
        if("飞机".equals(type)){
            arsenal=new AircraftFactory();
        }else if("大炮".equals(type)){
            arsenal=new CannonFactory();
        }if("手枪".equals(type)){
            arsenal=new PistolFactory();

        }else if("坦克".equals(type)){
            arsenal=new TankFactory();
        }

        return arsenal;
    }

}

/**
 * 客户端,接待用户
 */
public class Client {

    public static void main(String[] args) {
        //通知工厂进行生产
        Arsenal arsenal= Order.notice("坦克");
        //生产
        arsenal.generate();
        //交付
        arsenal.deliver();

    }
}

//运行结果
正在生产坦克...
正在交付坦克...

符合OCP 原则 :

上面的案例都不符合ocp原则(创建一个新的工厂就不应该再去动Order 类)所以我们应该这么做。通过反射机制来创建对应的对象。 
这样即便有再多的订单,创建再多的工厂也不用再去关心是否有对应的状态了,也符合了ocp原则。

代码展示:

/**
 * 订单
 */
public class Order {

    /**
     * 通知
     */
    public static Arsenal notice(Class clazz) {
        //采用反射的方式来创建对象,
        //符合 ocp 原则
        try {
            return (Arsenal) clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

}

/**
 * 客户端,接待用户
 */
public class Client {

    public static void main(String[] args) {
        //通知工厂进行生产
        Arsenal arsenal= Order.notice(TankFactory.class);
        //生产
        arsenal.generate();
        //交付
        arsenal.deliver();

    }
}

// 运行结果

正在生产坦克...
正在交付坦克...

 

持续更新...

posted @ 2019-12-15 19:55  不朽_张  阅读(159)  评论(0)    收藏  举报