若转载教程,请注明出自SW-X框架官方文档1
<?php
/**
* 设计模式之抽象工厂模式
* 小黄牛
*/
header("Content-type: text/html; charset=utf-8");
/****************************** 产品 *********************************/
# 接口 - 兵营
interface Barracks{
public function Make(); // 生产
}
# 接口 - 装备库
interface Equipment{
public function Make(); // 生产
}
/**************** 生产士兵 ******************/
# 创建 - 步兵
class Infantry implements Barracks{
public function Make() { echo ',步兵防守! <br/>';}
}
# 创建 - 骑兵
class Cavalry implements Barracks{
public function Make() { echo ',骑兵冲锋! <br/>';}
}
/**************** 生产装备 ******************/
# 创建 - 武器
class Arms implements Equipment{
public function Make() { echo '装备武器,攻击力+100 ';}
}
# 创建 - 盔甲
class Nail implements Equipment{
public function Make() { echo '装备盔甲,防御力+50 ';}
}
/****************************** 工厂 *********************************/
# 接口 - 顶级抽象工厂
interface TopFactory{
public function Arms(); // 武器
public function Nail(); // 盔甲
public function Go($Barracks); // 士兵执行动作
}
# 具体化 - 工厂A - 该套餐只能装备武器
class A implements TopFactory{
public function Arms(){return new Arms();} // 只有武器
public function Nail(){return null;} // 没有盔甲
public function Go($Barracks){
$A = $this->Arms();
$N = $this->Nail();
if($A){$A->Make();}
if($N){$N->Make();}
$Barracks->Make();
}
}
# 具体化 - 工厂B - 该套餐只能装备盔甲
class B implements TopFactory{
public function Arms(){return null;} // 没有武器
public function Nail(){return new Nail();} // 只有盔甲
public function Go($Barracks){
$A = $this->Arms();
$N = $this->Nail();
if($A){$A->Make();}
if($N){$N->Make();}
$Barracks->Make();
}
}
# 具体化 - 工厂C - 该套餐什么装备都有,土豪必备
class C implements TopFactory{
public function Arms(){return new Arms();}// 有武器
public function Nail(){return new Nail();} // 有盔甲
public function Go($Barracks){
$A = $this->Arms();
$N = $this->Nail();
if($A){$A->Make();}
if($N){$N->Make();}
$Barracks->Make();
}
}
/****************************** 测试 *********************************/
$A = new A(); // 套装-1
$B = new B(); // 套装-2
$C = new C(); // 套装-3
$B->Go(new Infantry()); // 步兵使用套装-2
$A->Go(new Cavalry()); // 骑兵使用套装-1
$C->Go(new Cavalry()); // 骑兵使用套装-3
浏览器输出
- 装备盔甲,防御力+50,步兵防守!
- 装备武器,攻击力+100,骑兵冲锋!
- 装备武器,攻击力+100装备盔甲,防御力+50,骑兵冲锋!
本案例设计原型
假设兵营里只能生产两种士兵。
步兵 骑兵
| |
防守 冲锋
装备
武器 盔甲
武器与盔甲之间交由工厂去组合,再交由士兵穿戴,执行防守或冲锋动作。
应用场景
1、游戏开发中的多风格系列场景(套餐),比如道路(接口),房屋,管道等。
2、系统要在三个不同平台上运行,比如Windows、Linux、Android上运行,你会怎么设计?通过抽象工厂模式屏蔽掉操作系统对应用的影响。三个不同操作系统上的软件功能、应用逻辑、UI都应该是非常类似,唯一不同的是调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息。
3、需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。
三种工厂模式总结
1.三种在形式和特点上极为相似,最终目的都是解耦。将对象的创建过程进行封装,使客户端可以直接得到对象,而不用去关心如何创建对象。
2.对比
工厂方法模式:用于创建复杂对象。(单点食物)
抽象工厂模式:用于创建一组相关或相互依赖的复杂对象。(买套餐)
工厂方法创建一般只有一个方法,创建一种产品。抽象工厂一般有多个方法,创建一系列产品。
我们不必去在意模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了,而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。