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 协议》,转载必须注明作者和本文链接

你可能感兴趣的:(php函数隔离)