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

时间:2022-09-08 21:24:53

1.解析

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

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

区别说明 :

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

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

结果 :

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


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