php函数隔离,设计模式实例讲解 - 接口隔离

说明

接口隔离原则的通俗描述如下

客户端不应当被迫实现它不需要用到的接口

不好的示例

工人包括工作和睡觉两种行为

class Worker {

public function work()

{

}

public function sleep()

{

}

}

机长则负责管理生产,需要管理生产要素

class Captain {

public function manage(Worker $worker)

{

$worker->work();

$worker->sleep();

}

}

但是生产要素不仅仅包括工人,机器也算。通常,我们会约定好「生产要素」

interface WorkerInterface {

public function work();

public function sleep();

}

再分别定义人和机器

class HumanWorker implements WorkerInterface {

public function work()

{

return 'human working'

}

public function sleep()

{

return 'human sleeping';

}

}

class AndroidWorker implements WorkerInterface {

public function work()

{

return 'Android working';

}

public function sleep()

{

return null;

}

}

现在,问题来了。机器没有 sleep 这个行为,却被迫去实现该接口。这明显违反了接口隔离原则。

改进 1

首先,我们想到以将「工作」和「睡觉」两个行为分别隔离出来

工作接口

interface WorkableInterface

{

public function work();

}

睡觉接口

interface SleepableInterface

{

public function sleep();

}

工人和机器根据自身情况去实现这些接口

class HumanWorker implements WorkableInterface, SleepableInterface

{

public function work()

{

return 'human working.';

}

public function sleep()

{

return 'human sleeping';

}

}

class AndroidWorker implements WorkableInterface

{

public function work()

{

return 'android working.';

}

public function beManaged()

{

$this->work();

}

}

机长

class Captain

{

public function manage($worker)

{

if($worker instanceof WorkableInterface){

$worker->work();

} else if($worker instanceof SleepableInterface){

$worker->sleep();

}

}

}

虽然我们分离了工作和睡觉两个行为,避免了违反接口隔离原则。但是该例子仍然有问题,我们可以看出, Caption 类对 manage 是开放的,一旦添加新的生产要素,就必须去修改该代码,很明显,违背了开放封闭原则。

最终改进

Captain 的变化的行为为 manage,将其分离出来

interface WorkableInterface

{

public function work();

}

interface ManageableInterface

{

public function beManaged();

}

对应的生产要素分别实现相应的接口

class HumanWorker implements WorkableInterface, SleepableInterface, ManageableInterface

{

public function work()

{

return 'human working.';

}

public function sleep()

{

return 'human sleeping';

}

public function beManaged()

{

$this->work();

$this->sleep();

}

}

class AndroidWorker implements WorkableInterface, ManageableInterface

{

public function work()

{

return 'android working.';

}

public function beManaged()

{

$this->work();

}

}

保持 Captain 类的封闭性

class Captain

{

public function manage(ManageableInterface $worker)

{

$worker->beManaged();

}

}

本作品采用《CC 协议》,转载必须注明作者和本文链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值