版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q1052196521/article/details/79744362
源码git地址 https://github.com/dlovetco/designMode
这个是最后一个也是最难的设计模式啦。估计看到这里的同学们一定像我一样把以前学过的28个设计模式忘得差不多了,下一篇我们就会总结一下我们学过的所有设计模式。
问题提出
请用面向对象的方式表明:
男人成功的时候背后有个伟大的女人,
女人成功的时候背后有个不成功的男人,
男人失败时闷头喝酒
女人失败时默默流泪。
我们可以从题目中看出有两个东西是我们可以抽象出来的:一个人(分为男人,女人),另一个是状态(成功失败)。而人是不可扩展的,状态可以无限扩展。其实代码结构应该为:男人在xxx状态下会yyy,女人在aaa状态下会bbb。
访问者模式
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
package visitormode;
public class VisitorMode {
public static void main(String[] args) {
Human man = new Man();
Human woman = new Woman();
Action success = new Success();
Action failure = new Failure();
man.accept(success);
man.accept(failure);
woman.accept(success);
woman.accept(failure);
}
}
/**
* 人接口
*/
interface Human {
//人接受状态之后做出的反应
void accept(Action action);
}
class Man implements Human {
@Override
public void accept(Action action) {
action.manConclusion(this);
}
}
class Woman implements Human {
@Override
public void accept(Action action) {
action.womanConclusion(this);
}
}
/**
* 状态接口
*/
interface Action {
//男人的反应
void manConclusion(Human man);
//女人的反应
void womanConclusion(Human woman);
}
class Success implements Action {
@Override
public void manConclusion(Human man) {
System.out.println(man.getClass().getSimpleName() + "成功的时候背后有个伟大的女人");
}
@Override
public void womanConclusion(Human woman) {
System.out.println(woman.getClass().getSimpleName() + "成功的时候背后有个不成功的男人");
}
}
class Failure implements Action {
@Override
public void manConclusion(Human man) {
//从man中获取一些信息 我这里偷懒直接用类名了
System.out.println(man.getClass().getSimpleName() + "失败时闷头喝酒");
}
@Override
public void womanConclusion(Human woman) {
System.out.println(woman.getClass().getSimpleName() + "失败时默默流泪");
}
}
输出:
Man成功的时候背后有个伟大的女人
Man失败时闷头喝酒
Woman成功的时候背后有个不成功的男人
Woman失败时默默流泪
注:书中还有一个ObjectStructure类,所做的事情就是管理客户端中new出来的Human对象,然后又提供了一个展示方法供客户端调用。我觉得有没有这个类都无所谓,所以偷个懒没加。
访问者模式适用于数据结构相对稳定的系统,它把数据结构(Human相关)和作用于结构上的操作(Action相关)之间耦合解脱开,使得操作集合可以相对自由的演化(我们增加一个Action不会影响其他类)。访问者的优点在于增加新的操作很容易,但缺点也很明显,新增加一个数据结构(不男不女)很困难(需要在Action的每一个类新增一个方法)。
plantuml
@startuml
interface Human{
{abstract}accept(Action action)
}
Human <|.. Man
class Man{
accept(Action action)
}
Human <|.. Woman
class Woman{
accept(Action action)
}
Human <..> Action
interface Action{
{abstract}manConclusion(Human man)
{abstract}womanConclusion(Human woman)
}
Action <|.. Success
class Success{
manConclusion(Human man)
womanConclusion(Human woman)
}
Action <|.. Failure
class Failure{
manConclusion(Human man)
womanConclusion(Human woman)
}
@enduml