设计模式之访问者模式–你永远用不上的设计模式
访问者模式
是解耦数据和操作,但是数据必须是稳定的,这样使增加操作变得更容易。
表示一个作用于某对象结构中的各元素的操作。他使你可以不改变各个元素类的情况下定义作用于这些元素的新操作。
为什么要使用访问者模式
访问者模式需要稳定的数据结构才能发挥作用,然而很少有稳定的数据结构。
当然不是说不稳定的数据结构不能用访问者模式,只不过,增加一个数据结构比较麻烦。因为你需要更改所有的操作。。。。
所以这个设计模式你可能一直都用不到。。。
不过如果真的有需要,那么用它就没错了。
什么是稳定的数据结构呢?
比如男人,女人,人妖。
比如小孩,大人。
这些不会改变的东西。那么操作是什么呢?
比如开心,快乐,事业成功等等。
php实现访问者模式
首先,定义一个访问者接口,也可以说是操作接口。
/**
* 访问者模式
* 操作接口,里面定义了几个数据结构的操作方法
*/
interface Visitor{
//男人的操作
function man();
//女人的操作
function women();
//人妖的操作
function simon();
}
现在来实现一些操作,比如开心
/**
* 访问者模式
* 具体操作,开心,实现了每个数据结构的开心
*/
class happy implements Visitor{
//男人的操作
function man(man $man) {
dump($man->name . '开心');
}
//女人的操作
function women(women $women) {
dump($women->name. '开心');
}
//人妖的操作
function simon(simon $simon) {
dump($simon->name. '开心');
}
}
比如事业成功
/**
* 访问者模式
* 具体操作,事业成功,实现了每个数据结构的事业成功
*/
class success implements Visitor{
//男人的操作
function man(man $man) {
dump($man->name . '事业成功');
}
//女人的操作
function women(women $women) {
dump($women->name. '事业成功');
}
//人妖的操作
function simon(simon $simon) {
dump($simon->name. '事业成功');
}
}
现在操作都实现了,我们需要实现数据结构了,也就是男人,女人,人妖。
/**
* 访问者模式
* 数据结构
*/
abstract class person{
//需要注入访问者,实现不同的操作
abstract function accept(Visitor $visitor);
}
/**
* 访问者模式
* 男人类
*/
class man extends person{
public $name = '男人';
//需要注入访问者,实现不同的操作
function accept(Visitor $visitor) {
//调用访问者的操作,把自己传进去
$visitor->man($this);
}
}
/**
* 访问者模式
* 女人类
*/
class women extends person{
public $name = '女人';
//需要注入访问者,实现不同的操作
function accept(Visitor $visitor) {
//调用访问者的操作,把自己传进去
$visitor->women($this);
}
}
/**
* 访问者模式
* 人妖类
*/
class simon extends person{
public $name = '人妖';
//需要注入访问者,实现不同的操作
function accept(Visitor $visitor) {
//调用访问者的操作,把自己传进去
$visitor->simon($this);
}
}
那客户端怎么调用呢?
$man = new man();
$man->accept(new happy);
$man->accept(new success);
$women = new women();
$women->accept(new happy);
$women->accept(new success);
这样的话就可以实现访问者模式了,如果我们需要添加操作,只需要添加一个操作类然后实现每个数据结构的方法就好了。
但是我们要添加数据结构就麻烦了,要修改所有的操作类。
其实操作类的三个方法可以合并成一个,都接受person
类型的参数,但是如果这三个数据类型的操作不一样呢?所以还是分成三个比较好。
代码放在了我的github上面。