设计模式之工厂方法模式(Factory Method)

1.解析

简单工厂并不简单,它是整个模式的核心,一旦他出了问题,整个模式都将受影响而不能工作,为了降低风险和为日后的维护、扩展做准备,我们需要对它进行重构,引入工厂方法。

这里写图片描述

区别说明 :

工厂方法和简单工厂的主要区别如下 :

(1) 简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面;
(2) 这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,**互相不受影响;
(3) 以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用修改已有的代码。


2.实例

实例说明 :
餐馆的例子 : 大厅经理接收点菜单 -> 给后厨主任菜单通知做菜 -> 服务员去端菜.简单的说明下工厂方法模式.

$. 后厨风波

(1) 实现产品接口 : 后厨主任, 告知做饭,说话任务

/**
 * 角色:后厨主任
 * 任务:告知制作什么食物
 * 目的:统一制作什么产品
 * @author yuan
 *
 */
public abstract class Foods {
    /**
     * 都要实现的工作,做饭
     */
    public abstract void makeFood();

    /**
     * 非都可实现的工作,说话
     */
    public void sayHello(){}
}

(2) 实现单一产品 : 饺子大厨, 制作饺子,还可以说话

public class JiaoziDaChu extends Foods {

    /**
     * 角色 : 饺子大厨
     * 任务 : 制作饺子
     * 目的 : 实现Foods接口,知道自己干什么
     */

    @Override
    public void makeFood() {
         System.out.println("热腾腾的饺子出锅了:)");
    }

    @Override
    public void sayHello() {
        //饺子大厨说
        System.out.println("我是饺子大厨 : 同志们好啊!");
    }

}

(3) 实现单一产品 : 面条大厨 , 制作面条

public class MianTiaoDaChu implements Foods {

    /**
     * 角色 : 面条大厨
     * 任务 : 制作面条
     * 目的 : 实现Foods接口,知道自己干什么
     */

    @Override
    public void makeFood() {
      System.out.println("热腾腾的面条做好了:)");
    }

}

(4) 实现单一产品: 馒头大厨, 制作馒头

public class ManTouDaChu extends Foods {

    /**
     * 角色 : 馒头大厨
     * 任务 : 制作馒头
     * 目的 : 实现Foods接口,知道自己干什么
     */

    @Override
    public void makeFood() {
       System.out.println("热腾腾的馒头出炉了:)");
    }

}

$. 服务风波 : 服务员听从大厅经理的话

(5) 实现总的任务 : 大厅经理 命令干活

/**
 *角色:大厅经理
 *任务:通知上菜
 *目的:工厂方法为工厂类定义了接口,用多态来削弱了工厂类的职能
 * @author yuan
 *
 */
public abstract class ServiceFactorys {
     //端菜去
    public abstract  Foods getFood();

     //说出是谁
    public  void sayWho(){}

    //说出的年龄
    public void sayAge(){}
}

(6) 实现单一职责 : 饺子服务员,上菜,说名字

public class JiaoZiService extends ServiceFactorys {

    /**
     *角色:饺子专门服务员
     *任务:去后厨拿饺子
     *目的:单一的生产一种产品
     */

    @Override
    public Foods getFood() {
        return new JiaoziDaChu();
    }

    @Override
    public void sayWho() {
        System.out.println("我是 饺子专门服务员 :(");
    }

}

(7) 实现单一职责 : 面条服务员,上菜,说名字

public class MianTiaoService extends ServiceFactorys {

    /**
     *角色:面条专门服务员
     *任务:去后厨拿面条
     *目的:单一的生产一种产品
     */

    @Override
    public Foods getFood() {
        return new MianTiaoDaChu();
    }

    @Override
    public void sayWho() {
        System.out.println("我是 面条专门服务员 :(");
    }
}

(8) 实现单一职责 : 馒头服务员 , 上菜,说名字,说年龄

public class ManTouService extends ServiceFactorys {

    /**
     *角色:馒头专门服务员
     *任务:去后厨拿馒头
     *目的:单一的生产一种产品
     */

    @Override
    public Foods getFood() {
        return new ManTouDaChu();
    }

    @Override
    public void sayWho() {
        System.out.println("我是 馒头专门服务员 :(");    
    }

    @Override
    public void sayAge() {
        System.out.println("我今年20岁!");  
    }

}

$. 用户点饭, 大厅经理告知 上饭

(9) 实现测试 : 用户点菜, 服务上菜

/**
 * 设计模式之工厂方法模式
 */
public class TestDemo {

    /**
     * 角色: 用户
     * 任务: 点菜
     * 目的: 测试
     */

    public static void main(String[] args) {

        ServiceFactorys factorys=new JiaoZiService();
        JiaoziDaChu jiaoziDaChu= (JiaoziDaChu) factorys.getFood();
        jiaoziDaChu.makeFood();
        jiaoziDaChu.sayHello();

        ServiceFactorys mantoufactorys=new ManTouService();
        mantoufactorys.sayWho();
        mantoufactorys.sayAge();
        mantoufactorys.getFood().makeFood();

    }

}

$. 关门数钱

(10) 实例小结
后厨主任 : 实现需要做的任务,必须实现的和非必要实现的任务,主要工作时安排大厨任务.
饺子,面条,馒头大厨 : 任务是做不同的产品.除了做产品,还可以去实现其他方法,比如说话.包含有和具体业务逻辑有关的代码实现。
大厅经历 : 安排服务员任务。
饺子,面条,馒头服务员:必须任务端菜.除了端菜,还可以实现其他方法。包含必要的业务逻辑和代码实现。

结果 :

这里写图片描述


3.优缺点

优点 :
(1)工厂方法模式类允许子类来决定实例化哪一个类.
(2)代码灵活,松耦合和可复用性,将对象创建的代码从客户端移到了工厂类,那就是它的子类。这非常易于维护相关代码,因为对象的创建非常集中。
(3)客户端代码只处理产品的接口,因此可以无需修改客户端的逻辑代码就能添加任何具体的产品。
(4)工厂方法的优势之一就是可以多次返回相同的实例,或者可以返回一个子类而不是一个具体类型的对象。

缺点 :
在可维护性上,可扩展性上是非常差的。


4.用途

使用场景 :
(1)对象的创建如果需要代码复用却没有现成的代码可用时,工厂方法设计模式就派上用场了。
(2)类并不知道需要创建的是什么子类。
(3)子类可以指定应该创建什么样的对象。
(4)父类会委托它的子类创建对象。

模式应用 :
第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。
例如 : Java Collection中的iterator() 方法即属于这种情况。

第二种情况,只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。


5.Demo免积分下载

接口模式demo :
http://download.csdn.net/detail/lablenet/9281223

抽象类模式demo :
http://download.csdn.net/detail/lablenet/9291275

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值