php 桥接模式

学习PHP设计模式20-桥接模式

在面向对象设计的时候,我们一般会根据需要,设计不同的类。但是如果两个类需要类似的功能的时候,我们就会遇到问题,到底重用还是重写。

更复杂的是,如果一些功能需要临时转换就麻烦了,比如星际里面的虫族,地面部队可以钻到地下,然后隐形。

但是小狗在地下不能动,而地刺可以攻击。尽管可以设计不同的类,但问题是玩家可以看到自己的部队埋在地下(一个洞),而敌人看不到。

这涉及功能的切换,而且星际里面有很多探测隐形的东西,这样就更频繁了。

待解决的问题:我们要临时切换一些功能的实现方式,而且在此基础上不同的调用类又有所不同。

思路:将钻地区分两种实现,不同的部队类在它的基础上进一步扩展。

桥接(Bridge)模式示例:

<?php

//虫族的基础类

class Zerg

{

  // 实现钻地的基本对象

  public $imp;

  //负责切换钻地基本对象的方法

  public function setImp($imp)

  {

  $this->imp = $imp;

  }

  //部队的钻地方法,可以扩展基本对象的钻地

  public function underground()

  {

  $this->imp->underground();

  }

}

// 小狗的类

class Zergling extends Zerg

{

  //调用基本的钻地方法,然后实现扩展,这里简单的echo

  public function underground()

  {

    parent::underground();

    echo ‘小狗不能动<br>’;

  }

}

// 地刺的类

class Lurker extends Zerg

{

  //调用基本的钻地方法,然后实现扩展,这里简单的echo

  public function underground()

  {

    parent::underground();

    echo ‘地刺能够进行攻击<br>’;

  }

}

// 钻地的基本接口

interface Implementor

{

  //基本的钻地方法

  public function underground();

}

//隐形钻地的基本类

class InvisibleImp implements Implementor

{

  //基本的钻地方法

  public function underground()

  {

    echo ‘隐形了,什么也看不到<br>’;

  }

}

//不隐形钻地的基本类,比如玩家自己看到的或被探测到的

class VisibleImp implements Implementor

{

  //基本的钻地方法

  public function underground()

  {

    echo ‘地上一个洞<br>’;

  }

}

//造一个小狗

$z1 = new Zergling();

//玩家把它埋入前沿阵地,假设此时有敌人经过,代码进行切换

$z1->setImp(new InvisibleImp());

//敌人看不到小狗,但是小狗也不能进攻

$z1->underground();

// 造一个地刺

$l1 = new Lurker();

//玩家把它埋入前沿阵地,假设此时有敌人经过,代码进行切换

$l1->setImp(new InvisibleImp());

//敌人看不到地刺,但是地刺能攻击敌人

$l1->underground();

//敌人急了,马上飞过来一个科技球,代码进行切换

$l1->setImp(new VisibleImp());

//敌人看到地刺了,地刺继续攻击敌人

$l1->underground();

?>

用途总结:桥接模式可以将基本的实现和具体的调用类分开,调用类可以扩展更复杂的实现。

实现总结:需要一些基本执行类,实现基本的方法,比如上面的两个钻地类。同时我们可以设计多个不同的扩展调用类,将基本的功能扩展,比如地刺和小狗就进一步实现了不同的在地下的行为。