英雄与行为,依赖的诞生

首先定义一个英雄,英雄具有一些行为:

class Hero {
protected $behavior = []; public function show()
{
var_dump($this->behavior);
}
}

然后定义一种名为攻击行为:

class Attack {
protected $value = 0; public function __construct($value)
{
$this->value = $value;
}
}

改造一下英雄类,让英雄在出生的时候具有攻击行为:

class Hero {
protected $behavior = []; public function __construct()
{
array_push($this->behavior, new Attack(10));
} public function show()
{
var_dump($this->behavior);
}
}

这样,英雄和某个具体的行为就产生了一种依赖关系。

英雄学会了越来越多的行为

随着英雄的成长,英雄学会了越来越多的行为:

class Defend {
protected $value = 0;
public function __construct($value){}
} class Move {
protected $speed;
public function __construct($speed){}
} class Skill1 {
protected $name = '暴击';
public function __construct(){}
} class Skill2 {
protected $name = '眩晕';
public function __construct(){}
}

改造一下英雄类,让英雄在出生的时候具有这些行为:

class Hero {
protected $behavior = []; public function __construct()
{
array_push($this->behavior, new Attack(10));
array_push($this->behavior, new Defend(5));
array_push($this->behavior, new Move(30));
array_push($this->behavior, new Skill1());
array_push($this->behavior, new Skill2());
} public function show()
{
var_dump($this->behavior);
}
}

随着行为的增加,暴露出了几个问题:

  1. 每增加一种行为,就必须修改一次英雄类;
  2. 如果想让不同的英雄拥有不同的技能,需要创建很多不同的英雄类。

通过工厂模式,实现依赖转移

定义一个行为工厂,英雄出生时可以在行为工厂中挑选行为:

class BehaviorFactory
{
public function makeBehavior($behaviorName, $options=[])
{
switch ($behaviorName) {
case 'Attack': return new Attack($options[0]);
case 'Defend': return new Defend($options[0]);
case 'Move': return new Move($options[0]);
case 'Skill1': return new Skill1();
case 'Skill2': return new Skill2();
}
}
}

修改英雄类,让英雄可以去工厂中学习行为:

class Hero
{
protected $behavior = []; public function __construct(array $behaviors)
{
// 初始化工厂
$factory = new BehaviorFactory(); // 通过工厂提供的方法制造需要的模块
foreach ($behaviors as $behaviorName => $behaviorOptions) {
$this->behavior[] = $factory->makeBehavior($behaviorName, $behaviorOptions);
}
}
} $hero = new Hero([
'Attack' => [10],
'Defend' => [5],
'Move' => [30],
'Skill1' => [],
]);

引入工厂模式,我们解决了上述的两个问题:

  1. 使得英雄类不再依赖其他行为类,增加任意一种行为,都不需要修改英雄类;
  2. 如果想要不同的英雄拥有不同的技能,在英雄出生时选择即可。

但同时我们也引入了一个新的问题,每增加一种行为,就需要在工厂中增加一条生产线。

后面,我们将讲解如果使用一个更高级的工厂-服务容器来解决工厂模式存在的问题。

最新文章

  1. 深入浅出node(2) 模块机制
  2. 关于WPF中RichTextBox失去焦点后如何保持高亮显示所选择的内容
  3. Outer Join Query Over Dblink Can Fail With ORA-904 (Doc ID 730256.1)
  4. iOS AVAudioRecorder 录音频率、声道、位数配置 wav格式
  5. java 多线程——quartz 定时调度的例子
  6. bzoj 2561: 最小生成树
  7. ubuntu免验证登陆权限问题
  8. CentOS 7 更改网卡名到以前的eth0
  9. Maven实战——生命周期和插件
  10. LInkedHashMap实现最近被使用(LRU)缓存
  11. Linux下docker报错syntax error:unexpected protocol at end of statement
  12. delphi中adoquery控件中某个字段Onvalidate事件的用法?
  13. C++ 窗口
  14. linux网络 skb_buff
  15. html中空格字符实体整理
  16. 46.HTML---18个学习 flexbox 的优质资源
  17. Linux 模块管理
  18. Hadoop MapReduce流程及容错
  19. leetcode-填充同一层的兄弟节点Ⅱ
  20. PreparedStatement 查询 In 语句 setArray 等介绍。

热门文章

  1. vue-cli2嵌入html
  2. Oracle常用函数(SQL语句)
  3. 【Linux】【Services】【SaaS】Docker+kubernetes(8. 安装和配置Kubernetes)
  4. RPC、HTTP、RESTful
  5. Hibernate的基本功能:对数据库的增删改查(创建对象实例)
  6. 【C/C++】vector 动态二维数组
  7. DMA(Data Migration Assistant)迁移SQLServer数据库
  8. Tableau预测指示器的运用
  9. Tableau如何绘制多边形地图
  10. Jmeter——脱离Jenkins后,Ant集成邮件通知