设计模式学习笔记-桥接模式

场景:对于不同国家的人,他们的生活习惯。最简单 什么时候起床,什么时吃饭,什么是睡觉。
在这个场景中, 人就是对象,起床,吃饭,睡觉是人的行为

可能我们会简单的想到下面的实现方式,创建一个人的行为类,然后让不同的人去继承。比如:

abstract class AbstracPerson{
	private $_getUpTiem = null;
	private $_eatTime = null;
	private $_goBedTime = null;
	public  function habit() {
		echo "My habit is get up({$this->_getUpTiem}),eat({$this->_eatTime},goBed({$this->_goBedTime}))";
	}
	public function setHabit() {
		$this->_getUpTiem = $this->getUpTime();
		$this->_eatTime = $this->eatTime();
		$this->_goBedTime = $this->goBedTime();
	}
	public abstract function getUpTime();
	public abstract function eatTime();
	public abstract function goBedTime();
	public abstract function otherThing();
}

class ChinaPerson {
	public  function getUpTime(){
		return "08:00";
	}
	public  function eatTime() {
		return "12:00";
	}
	public  function goBedTime(){
		return  "22:00";
	}

	public  function otherThing(){}	
}

class AmericaPerson {
	public  function getUpTime(){
		return "08:00";
	}
	public  function eatTime() {
		return "13:00";
	}
	public  function goBedTime(){
		return  "23:00";
	}
	public  function otherThing(){}	
}

class JapanesePerson {
	public  function getUpTime(){
		return "08:00";
	}
	public  function eatTime() {
		return "13:00";
	}
	public  function goBedTime(){
		return  "23:00";
	}
	public  function otherThing(){}	
}

确实,上面的实现过程,确实能满足我们的需求,但是否有想过,这样我们就把每个人的行为都固定了。也就是说,中国人就只能有中国人的行为,美国人就只能有美国人的行为。但在现实生活中,有些中国人是可能有美国人的生活习惯,也可以有些人是有日本人的生活习惯。那怎么,我们上面的实现都固定了人的行为。我们无法重复利用这些特定的对象元素和行为元素。只能重新实现,比如

//中国人具有美国人的行为
class ChinaPersonOfAmerica {
	public  function getUpTime(){
		return "08:00";
	}
	public  function eatTime() {
		return "13:00";
	}
	public  function goBedTime(){
		return  "23:00";
	}
	public  function otherThing(){}	
}
//中国人具有日本人的行为
class ChinaPersonOfJapanese {
	public  function getUpTime(){
		return "08:00";
	}
	public  function eatTime() {
		return "13:00";
	}
	public  function goBedTime(){
		return  "23:00";
	}
	public  function otherThing(){}	
}

同样如果日本人需要中国人的行为 或者 美国人需要日本和中国人,也需要经历上述行为,有没有发现问题。
一是行为元素只有3个,只是对象不同,但我们却实现很多的类。但来来去去都是 3种人3个行为。 但我们却可能实现9个类了,行为元素和对象元素没有复用
二是类的增长速度由点可怕,现在只是3个国家,如果是10国家,最多类数目是10*10,如果是200个国家是200*200,这种类的暴增真的好么?

那怎么解决问题呢?向我上面说的,其实来来去去都是 3个行为和3种人的问题。那么是否可以将人和行为分开,单独实现,让它们独自变化,最后让人和行为自由组合,达到人元素和行为元素复用的效果。现在我们顺着这个想法去实现我们的代码。

//对象
abstract class AbstracPerson{
	private $_getUpTiem = null;
	private $_eatTime = null;
	private $_goBedTime = null;
	public function setHabit($habit) {
		$this->_getUpTiem = $habit->getUp();
		$this->_eatTime = $habit->eat();
		$this->_goBedTime = $habit->goBed();
	}
	public function habit() {
		echo "My habit is get up({$this->_getUpTiem}),eat({$this->_eatTime},goBed({$this->_goBedTime}))";
	}
	public abstract function otherThing();
}


//中国
class ChinaPerson extends AbstracPerson{
	public function otherThing() {
		echo "doChinaSomething";
	}
}

//美国
class AmericaPerson extends AbstracPerson{
	public function otherThing() {
		echo "doAmericaSomething";
	}
}

//日本
class JapanesePerson extends AbstracPerson{
	public function otherThing() {
		echo "doJapaneseSomething";
	}	
}

//行为抽象类
interface IAction {
	public function getUp();
	public function eat();
	public function goBed();
}
//中国人的生活习惯
class ChinaAction implements IAction {
	public function getUp() {
		return '08:00';	
	}
	public function eat() {
		return  '12:00';
	}
	public function goBed(){
		return  '22:00';
	}	
} 
//美国人的生活习惯
class AmericaAction implements IAction {
	public function getUp() {
		return '09:00';	
	}
	public function eat() {
		return  '13:00';
	}
	public function goBed(){
		return  '23:00';
	}	
} 
//日本人的生活习惯
class JapaneseAction implements IAction {
	public function getUp() {
		return '07:00';	
	}
	public function eat() {
		return  '12:00';
	}
	public function goBed(){
		return  '21:00';
	}	
} 

$ChinaPerson = new ChinaPerson();
$AmericaPerson = new AmericaPerson();
$ChinaAction = new ChinaAction();
$AmericaAction = new AmericaAction();
$JapaneseAction = new JapaneseAction();

$ChinaPerson->setHabit($ChinaAction); //中国人习惯
$ChinaPerson->setHabit($AmericaAction); //中国美国人习惯
$AmericaPerson->setHabit($JapaneseAction);//美国人 日本习惯

看看,上面的过程是不是简单很多。人的对象元素,和行为元素可以相互组合。我们不需要因为中国人中有他国的习惯而去特定重新实现一个类,只需要通过组合就可以实现。是不是方便很多,同时又减少了类数目,而且复用了对象和行为元素。

上面的实现过程,就是本篇的主角---桥接模式

桥接模式的优缺点:

1.改变对象与其行为的强耦合关系,使之与行为解耦;
2.使对象的行为以及对象本身都能独立变化;
3.人和行为的实现可以被替换,因为使用者只是看到了一个抽象的接口(AbstracPerson,IAction)经常被用来创建组合结构

个人理解:

与策略模式相似, 但桥接模式 重点是 行为与对象的分离 多对多,而策略模式,你一个对象对应多种算法。一对多

猜你喜欢

转载自blog.csdn.net/H_L_S/article/details/86402839
今日推荐