原文详见:http://www.ucai.cn/blogdetail/7023?mid=1&f=12
可以在线运行查看效果哦! ? ?
?
<接上一篇>
4、观察者模式(Observer):
? ? ? ? ?又叫发布订阅模式,当一个主体对象发生改变时,依赖它的多个观察者对象都得到通知并自动更新响应。就像报社一样,今天发布的消息只要是看这份报纸的人看到的都是同样的内容。如果发布另一份报纸,也是一样的。
???????? 好处:广播式通信,范围大,一呼百应,便于操作一个组团,“公有制”。
???????? 弊端:不能单独操作组团里的个体,不能实行按需分配。
? ? ? ? ?应用场景:操作多个对象,并操作相同。
代码实现:
?
?
[php]?view plaincopy
?
class="dp-c">
- <?php??
- ??
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- ??
- function?output($string)?{??
- ????echo????$string?.?"\n";??
- }??
- ??
- ??
- ??
- ??
- class?Order{??
- ??????
- ????private?$id?=?'';??
- ??
- ??????
- ????private?$userId?=?'';??
- ??
- ??????
- ????private?$userName?=?'';??
- ??
- ??????
- ????private?$price?=?'';??
- ??
- ??????
- ????private?$orderTime?=?'';??
- ??
- ??????
- ????public?function?__set($name,?$value){??
- ????????if?(isset($this->$name)){??
- ????????????$this->$name?=?$value;??
- ????????}??
- ????}??
- ??
- ??????
- ????public?function?__get($name){??
- ????????if?(isset($this->$name)){??
- ????????????return?$this->$name;??
- ????????}??
- ????????return?"";??
- ????}??
- }??
- ??
- ??
- class?FakeDB{??
- ????public?function?save($data){??
- ????????return?true;??
- ????}??
- }??
- ??
- ??
- class?Client?{??
- ??????
- ????public?static?function?test()?{??
- ??
- ??????????
- ????????$order?=?new?Order();??
- ????????$order->id?=?1001;??
- ????????$order->userId?=?9527;??
- ????????$order->userName?=?"God";??
- ????????$order->price?=?20.0;??
- ????????$order->orderTime?=?time();??
- ??
- ??????????
- ????????$db?=?new?FakeDB();??
- ????????$result?=?$db->save($order);??
- ????????if?($result){??
- ??
- ??????????????
- ????????????output(?"[OrderId:{$order->id}]?[UseId:{$order->userId}]?[Price:{$order->price}]"?);??
- ??
- ??????????????
- ????????????output(?"Dear?{$order->userName}:?Your?order?{$order->id}?was?confirmed!"?);??
- ??
- ??????????????
- ????????????output(?"Dear?Manager:?User?{$order->userName}(ID:{$order->userId})?submitted?a?new?order?{$order->id},?please?handle?it?ASAP!"?);??
- ??
- ????????}??
- ??
- ????}??
- ??
- }??
- ??
- Client::test();??
- ??
- ??
- <?php??
- ??
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- ??
- function?output($string)?{??
- ????echo????$string?.?"\n";??
- }??
- ??
- ??
- ??
- ??
- class?Order{??
- ??????
- ????private?$id?=?'';??
- ??
- ??????
- ????private?$userId?=?'';??
- ??
- ??????
- ????private?$userName?=?'';??
- ??
- ??????
- ????private?$price?=?'';??
- ??
- ??????
- ????private?$orderTime?=?'';??
- ??
- ??????
- ????public?function?__set($name,?$value){??
- ????????if?(isset($this->$name)){??
- ????????????$this->$name?=?$value;??
- ????????}??
- ????}??
- ??
- ??????
- ????public?function?__get($name){??
- ????????if?(isset($this->$name)){??
- ????????????return?$this->$name;??
- ????????}??
- ????????return?"";??
- ????}??
- }??
- ??
- ??
- class?OrderSubject?implements?SplSubject?{??
- ????private?$observers;??
- ????private?$order;??
- ??
- ????public?function?__construct(Order?$order)?{??
- ????????$this->observers?=?new?SplObjectStorage();??
- ????????$this->order?=?$order;??
- ????}??
- ??
- ??????
- ????public?function?attach(SplObserver?$observer)?{??
- ????????$this->observers->attach($observer);??
- ????}??
- ??
- ??????
- ????public?function?detach(SplObserver?$observer)?{??
- ????????$this->observers->detach($observer);??
- ????}??
- ??
- ??????
- ????public?function?notify()?{??
- ????????foreach?($this->observers?as?$observer)?{??
- ????????????$observer->update($this);??
- ????????}??
- ????}??
- ??
- ??????
- ????public?function?getOrder()?{??
- ????????return?$this->order;??
- ????}??
- }??
- ??
- ??
- class?ActionLogObserver?implements?SplObserver{??
- ????public?function?update(SplSubject?$subject)?{??
- ?????????$order?=?$subject->getOrder();??
- ???????????
- ?????????output(?"[OrderId:{$order->id}]?[UseId:{$order->userId}]?[Price:{$order->price}]"?);??
- ????}??
- }??
- ??
- ??
- class?UserMailObserver?implements?SplObserver{??
- ????public?function?update(SplSubject?$subject)?{??
- ?????????$order?=?$subject->getOrder();??
- ???????????
- ?????????output(?"Dear?{$order->userName}:?Your?order?{$order->id}?was?confirmed!"?);??
- ????}??
- }??
- ??
- ??
- class?AdminMailObserver?implements?SplObserver{??
- ????public?function?update(SplSubject?$subject)?{??
- ?????????$order?=?$subject->getOrder();??
- ???????????
- ?????????output(?"Dear?Manager:?User?{$order->userName}(ID:{$order->userId})?submitted?a?new?order?{$order->id},?please?handle?it?ASAP!"?);??
- ????}??
- }??
- ??
- ??
- class?FakeDB{??
- ????public?function?save($data){??
- ????????return?true;??
- ????}??
- }??
- ??
- ??
- class?Client?{??
- ??????
- ????public?static?function?test()?{??
- ??
- ??????????
- ????????$order?=?new?Order();??
- ????????$order->id?=?1001;??
- ????????$order->userId?=?9527;??
- ????????$order->userName?=?"God";??
- ????????$order->price?=?20.0;??
- ????????$order->orderTime?=?time();??
- ??
- ??????????
- ????????$subject?=?new?OrderSubject($order);??
- ????????$actionLogObserver?=?new?ActionLogObserver();??
- ????????$userMailObserver?=?new?UserMailObserver();??
- ????????$adminMailObserver?=?new?AdminMailObserver();??
- ????????$subject->attach($actionLogObserver);??
- ????????$subject->attach($userMailObserver);??
- ????????$subject->attach($adminMailObserver);??
- ??????????
- ????????$db?=?new?FakeDB();??
- ????????$result?=?$db->save($order);??
- ????????if?($result){??
- ??????????????
- ????????????$subject->notify();??
- ????????}??
- ??
- ????}??
- ??
- }??
- ??
- Client::test();??
?
?
5、中介者模式(Mediator):
? ? ? ? ?用中介对象封装一系列的对象交互,中介使各对象不需要显式地相互引用。类似于邮局,邮寄者和收件者不用自己跑很远路,通过邮局就可以。
? ? ? ? ?好处:简化了对象之间的关系,减少子类的生成。
? ? ? ? ?弊端:中介对象可能变得非常复杂,系统难以维护。
? ? ? ? ?应用场景:不需要显示地建立交互。
代码实现:
?
[php]?view plaincopy
?
- <?php??
- ??
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- ??
- ??
- function?output($string)?{??
- ????echo????$string?.?"\n";??
- }??
- ??
- ??
- ??
- ??
- abstract?class?Mediator?{???
- ????abstract?public?function?send($message,$colleague);???
- }???
- ??
- abstract?class?Colleague?{???
- ????private?$_mediator?=?null;???
- ????public?function?__construct($mediator)?{???
- ????????$this->_mediator?=?$mediator;???
- ????}???
- ????public?function?send($message)?{???
- ????????$this->_mediator->send($message,$this);???
- ????}???
- ????abstract?public?function?notify($message);???
- }???
- ??
- class?ConcreteMediator?extends?Mediator?{???
- ????private?$_colleague1?=?null;???
- ????private?$_colleague2?=?null;???
- ????public?function?send($message,$colleague)?{???
- ????????if($colleague?==?$this->_colleague1)?{???
- ????????????$this->_colleague1->notify($message);???
- ????????}?else?{???
- ????????????$this->_colleague2->notify($message);???
- ????????}???
- ????}??
- ????public?function?set($colleague1,$colleague2)?{???
- ????????$this->_colleague1?=?$colleague1;???
- ????????$this->_colleague2?=?$colleague2;???
- ????}???
- }???
- ??
- class?Colleague1?extends?Colleague?{???
- ????public?function?notify($message)?{??
- ????????output(sprintf('Colleague-1:?%s',?$message));??
- ????}???
- }???
- ??
- class?Colleague2?extends?Colleague?{???
- ????public?function?notify($message)?{???
- ????????output(sprintf('Colleague-2:?%s',?$message));??
- ????}???
- }???
- ??
- ??
- ??
- class?Client?{????
- ????????
- ????public?static?function?test(){????
- ??
- ??????????
- ????????$objMediator?=?new?ConcreteMediator();???
- ????????$objC1?=?new?Colleague1($objMediator);???
- ????????$objC2?=?new?Colleague2($objMediator);???
- ????????$objMediator->set($objC1,$objC2);???
- ????????$objC1->send("to?c2?from?c1");???
- ????????$objC2->send("to?c1?from?c2");???
- ??
- ????}????
- ????????
- }????
- ????
- Client::test();???
?
?
6、状态模式(State) :
? ? ? ? ? 对象在不同状态下表现出不同的行为。就像女朋友一样,高兴了牵你的手,不高兴了遛狗。在两种状态下变现出不同的行为。
? ? ? ? ?好处:避免if语句实用,方便增加新状态,封装了状态转换规则。
? ? ? ? ?弊端:增加系统类和对象的数量。
? ? ? ? ?应用场景:用于对象的不同功能的转换。
代码实现:
?
[php]?view plaincopy
?
- <?php??
- ??
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- ??
- function?output($string)?{??
- ????echo????$string?.?"\n";??
- }??
- ??
- abstract?class?ILift?{????
- ??
- ??????
- ????const?OPENING_STATE?=?1;????
- ????const?CLOSING_STATE?=?2;????
- ????const?RUNNING_STATE?=?3;????
- ????const?STOPPING_STATE?=?4;???
- ????????
- ??????
- ????public?abstract?function?setState($state);????
- ????
- ??????
- ????public?abstract?function?open();????
- ????
- ??????
- ????public?abstract?function?close();????
- ????
- ??????
- ????public?abstract?function?run();????
- ????
- ??????
- ????public?abstract?function?stop();????
- ??
- }????
- ????
- ?
- ?
- ?????
- class?Lift?extends?ILift?{????
- ??
- ????private?$state;????
- ????
- ????public?function?setState($state)?{????
- ????????$this->state?=?$state;????
- ????}????
- ??
- ??????
- ????public?function?close()?{????
- ??
- ??????????
- ????????switch?($this->state)?{????
- ????????????case?ILift::OPENING_STATE:????
- ????????????????$this->setState(ILift::CLOSING_STATE);????
- ????????????break;????
- ????????????case?ILift::CLOSING_STATE:????
- ??????????????????
- ????????????????return?;????
- ????????????break;????
- ????????????case?ILift::RUNNING_STATE:???
- ??????????????????
- ????????????????return?;????
- ????????????break;????
- ????????????case?ILift::STOPPING_STATE:????
- ??????????????????
- ????????????????return?;????
- ????????????break;????
- ????????}????
- ??
- ????????output('Lift?colse');????
- ??
- ????}????
- ????
- ??????
- ????public?function?open()?{????
- ??????????
- ????????switch($this->state){????
- ????????????case?ILift::OPENING_STATE:???
- ??????????????????
- ????????????????return?;????
- ????????????break;????
- ????????????case?ILift::CLOSING_STATE:???
- ????????????????$this->setState(ILift::OPENING_STATE);????
- ????????????break;????
- ????????????case?ILift::RUNNING_STATE:???
- ??????????????
- ????????????????return?;????
- ????????????break;????
- ????????????case?ILift::STOPPING_STATE:???
- ????????????????$this->setState(ILift::OPENING_STATE);????
- ????????????break;????
- ????????}????
- ????????output('Lift?open');????
- ????}????
- ??????
- ????public?function?run()?{????
- ????????switch($this->state){????
- ????????????case?ILift::OPENING_STATE:???
- ??????????????????
- ????????????????return?;????
- ????????????break;????
- ????????????case?ILift::CLOSING_STATE:???
- ????????????????$this->setState(ILift::RUNNING_STATE);????
- ????????????break;????
- ????????????case?ILift::RUNNING_STATE:???
- ??????????????????
- ????????????????return?;????
- ????????????break;????
- ????????????case?ILift::STOPPING_STATE:???
- ????????????????$this->setState(ILift::RUNNING_STATE);????
- ????????}????
- ????????output('Lift?run');????
- ????}????
- ????
- ??????
- ????public?function?stop()?{????
- ????????switch($this->state){????
- ????????????case?ILift::OPENING_STATE:???
- ??????????????????
- ????????????????return?;????
- ????????????break;????
- ????????????case?ILift::CLOSING_STATE:???
- ????????????????$this->setState(ILift::CLOSING_STATE);????
- ????????????break;????
- ????????????case?ILift::RUNNING_STATE:???
- ????????????????$this->setState(ILift::CLOSING_STATE);????
- ????????????break;????
- ????????????case?ILift::STOPPING_STATE:???
- ??????????????????
- ????????????????return?;????
- ????????????break;????
- ????????}????
- ????????output('Lift?stop');????
- ????}????
- ????????
- }????
- ??
- ??
- ??
- class?Client?{??
- ??????
- ????public?static?function?test()?{??
- ??
- ????????$lift?=?new?Lift();?????
- ???????????????
- ??????????
- ????????$lift->setState(ILift::STOPPING_STATE);?????
- ??????????
- ????????$lift->open();?????
- ???????????????
- ??????????
- ????????$lift->close();?????
- ???????????????
- ??????????
- ????????$lift->run();????????
- ??
- ???????????
- ????????$lift->stop();????
- ??
- ????}??
- ??
- }??
- ??
- Client::test();??
- ??
- ??
- <?php??
- ??
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- ??
- function?output($string)?{??
- ????echo????$string?.?"\n";??
- }??
- ??
- ?
- ?
- ?
- ?????
- abstract?class?LiftState{????
- ????
- ??????
- ????protected??$_context;????
- ????
- ????public?function?setContext(Context?$context){????
- ????????$this->_context?=?$context;????
- ????}????
- ????
- ??????
- ????public?abstract?function?open();????
- ????
- ??????
- ????public?abstract?function?close();????
- ????
- ??????
- ????public?abstract?function?run();????
- ????
- ??????
- ????public?abstract?function?stop();????
- ????
- }????
- ????
- ????
- ?
- ?
- ?????
- class?Context?{????
- ??????
- ????static??$openningState?=?null;????
- ????static??$closeingState?=?null;????
- ????static??$runningState??=?null;????
- ????static??$stoppingState?=?null;????
- ????
- ????public?function?__construct()?{????
- ????????self::$openningState?=?new?OpenningState();????
- ????????self::$closeingState?=?new?ClosingState();????
- ????????self::$runningState?=??new?RunningState();????
- ????????self::$stoppingState?=?new?StoppingState();????
- ????
- ????}????
- ????
- ??????
- ????private??$_liftState;????
- ????
- ????public?function?getLiftState()?{????
- ????????return?$this->_liftState;????
- ????}????
- ????
- ????public?function?setLiftState($liftState)?{????
- ????????$this->_liftState?=?$liftState;????
- ??????????
- ????????$this->_liftState->setContext($this);????
- ????}????
- ????
- ????
- ????public?function?open(){????
- ????????$this->_liftState->open();????
- ????}????
- ????
- ????public?function?close(){????
- ????????$this->_liftState->close();????
- ????}????
- ????
- ????public?function?run(){????
- ????????$this->_liftState->run();????
- ????}????
- ????
- ????public?function?stop(){????
- ????????$this->_liftState->stop();????
- ????}????
- }????
- ????
- ?
- ?
- ?????
- class?OpenningState?extends?LiftState?{????
- ????
- ?????
- ?
- ?
- ????
- ????public?function?close()?{????
- ??????????
- ????????$this->_context->setLiftState(Context::$closeingState);????
- ??????????
- ????????$this->_context->getLiftState()->close();????
- ????}????
- ????
- ??????
- ????public?function?open()?{????
- ????????output('lift?open...');??
- ????}????
- ??????
- ????public?function?run()?{????
- ??????????
- ????}????
- ????
- ??????
- ????public?function?stop()?{????
- ??????????
- ????}????
- ????
- }????
- ????
- ?
- ?
- ?????
- class?ClosingState?extends?LiftState?{????
- ????
- ??????
- ????public?function?close()?{????
- ????????output('lift?close...');??
- ????
- ????}????
- ??????
- ????public?function?open()?{????
- ????????$this->_context->setLiftState(Context::$openningState);????
- ????????$this->_context->getLiftState()->open();????
- ????}????
- ????
- ??????
- ????public?function?run()?{????
- ????????$this->_context->setLiftState(Context::$runningState);???
- ????????$this->_context->getLiftState()->run();????
- ????}????
- ????
- ??????
- ????????
- ????public?function?stop()?{????
- ????????$this->_context->setLiftState(Context::$stoppingState);????
- ????????$this->_context->getLiftState()->stop();????
- ????}????
- ????
- }????
- ????
- ?
- ?
- ?????
- class?RunningState?extends?LiftState?{????
- ????
- ??????
- ????public?function?close()?{????
- ??????????
- ????}????
- ????
- ??????
- ????public?function?open()?{????
- ??????????
- ????}????
- ????
- ??????
- ????public?function?run()?{????
- ????????output('lift?run...');??
- ????}????
- ????
- ??????
- ????public?function?stop()?{????
- ????????$this->_context->setLiftState(Context::$stoppingState);???
- ????????$this->_context->getLiftState()->stop();????
- ????}????
- ????
- }????
- ????
- ????
- ????
- ?
- ?
- ?????
- class?StoppingState?extends?LiftState?{????
- ????
- ??????
- ????public?function?close()?{????
- ??????????
- ????}????
- ????
- ??????
- ????public?function?open()?{????
- ????????$this->_context->setLiftState(Context::$openningState);????
- ????????$this->_context->getLiftState()->open();????
- ????}????
- ??????
- ????public?function?run()?{????
- ????????$this->_context->setLiftState(Context::$runningState);????
- ????????$this->_context->getLiftState()->run();????
- ????}????
- ??????
- ????public?function?stop()?{????
- ????????output('lift?stop...');??
- ????}????
- ????
- }????
- ????
- ?
- ?
- ?????
- class?Client?{????
- ????
- ????public?static?function?test()?{????
- ????????$context?=?new?Context();????
- ????????$context->setLiftState(new?ClosingState());????
- ????
- ????????$context->open();????
- ????????$context->close();????
- ????????$context->run();????
- ????????$context->stop();????
- ????}????
- }????
- ??
- Client::test(); ??