架构师备战软件工程之行为型设计模式

开发 前端
状态模式和策略模式很类似,简直就是亲兄弟一样。而访问者模式其实和观察者模式也很类似。所以我们的设计模式设计到最后,可能就会存在一种模式里有另一种模式的影子。所以我们要搞清楚它们之间的区别。

1、状态模式

简要说明

允许一个对象在其内部改变时改变它的行为

速记关键字

状态变成类

类图如下

状态模式主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。比如订单从待付款到待收货的咋黄台发生变化,执行的逻辑是不一样的。

所以我们将状态抽象为一个接口或者抽象类,对不同状态进行封装成单独的实体,用于实现各种状态处理的逻辑。

再设计一个上下文类,它组合了状态接口,用于发送请求。针对不同的状态提供不同的处理方法即可。

Java代码实现

/**
* 状态接口 提供处理状态的方法
*/
public interface IState {

// 处理状态,交给实现类实现
void handleState();
}

/**
* 未付款状态
*/
public class UnpaidState implements IState{
@Override
public void handleState() {
System.out.println("下单成功,订单状态为待付款");
}
}

/**
* 已付款状态
*/
public class PaidState implements IState{
@Override
public void handleState() {
System.out.println("支付成功,订单状态为已付款");
}
}

/**
* 已取消状态
*/
public class CancelState implements IState{
@Override
public void handleState() {
System.out.println("订单取消支付,订单状态为已取消");
}
}

/**
* 订单状态上下文类
*/
public class Context {
// 组合订单状态
private final IState state;

public Context(IState state) {
this.state = state;
}

// 提供处理订单方法
public void handleOrderByState(){
state.handleState();
}
}

/**
* 测试类
*/
public class Client {
public static void main(String[] args) {
// 创建上下文并创建未支付状态
Context context = new Context(new UnpaidState());
context.handleOrderByState();

// 创建上下文并创建已支付状态
Context context2 = new Context(new PaidState());
context2.handleOrderByState();
}
}

结果输出

其实我们可以看出来,状态模式和策略模式非常像,都有一个Context类,都有一个接口或抽象类被Context组合。而后抽象类或接口有自己的不同实现。

它们确实很像,但是它们确实有区别,因为状态模式围绕着状态的变化,它的子类之间的状态是可以进行转换的,比如订单状态由未付款变为已付款。但是策略模式则不会,只会二者取其一,进行一种策略操作。

2、访问者模式

简要说明

表示一个作用域某对象结构中的个元素的操作,使得在不改变各元素的前提下定义作用域这些元素的新操作。

速记关键字

数据与操作分离

类图如下

角色说明

  • Visitor(抽象访问者):为每种具体的被访问者(ConcreteElement)声明一个访问操作
  • ConcreteVisitor(具体访问者):实现对被访问者(ConcreteElement)的具体访问操作,所以需要组合多个元素,也就是组合一组元素集合
  • Element(抽象被访问者):通常有一个Accept方法,用来接收/引用一个抽象访问者对象(基本原理)
  • ConcreteElement(具体被访问者对象):实现Accept抽象方法,通过传入的具体访问者参数、调用具体访问者对该对象的访问操作方法实现访问逻辑
  • Clent、ObjectStructure(客户端访问过程测试环境):该过程中,被访问者通常为一个集合对象,通过对集合的遍历完成访问者对每一个被访问元素的访问操作;

Java代码实现

/**
* 定义被访问接口
*/
public interface Person {
// 提供一个方法,让访问者可以访问
void accept(Action action);
}

/**
* 访问者,这里提供了多个访问方法,从而获取多个不同的访问结果,它们的参数分别对应具体的被访问元素
*/
public interface Action {
// 得到男性 的测评
void getManResult(Man man);

// 得到女的 测评
void getWomanResult(Woman woman);
}

/**
* 被访问者元素男人实现,传入自己给访问者访问
*/
public class Man implements Person{
@Override
public void accept(Action action) {
action.getManResult(this);
}
}

/**
* 被访问者元素女人实现,传入自己给访问者访问
*/
public class Woman implements Person{
@Override
public void accept(Action action) {
action.getWomanResult(this);
}
}

/**
* 访问者实现类 对不同的被访问元素做不同的访问
*/
class Success implements Action {

@Override
public void getManResult(Man man) {
System.out.println("男人给的评价: 歌手很表演很nice");
}

@Override
public void getWomanResult(Woman woman) {
System.out.println("女人给的评价: 歌手很表演很nice");
}
}

class Normal implements Action {
@Override
public void getManResult(Man man) {
System.out.println("男人给的评价是: 歌手很表演比较普通");
}

@Override
public void getWomanResult(Woman woman) {
System.out.println("女人给的评价是: 歌手很表演比较普通");
}
}

public class Fail implements Action {
@Override
public void getManResult(Man man) {
System.out.println("男人给的评价: 歌手很表演有点糟糕");
}

@Override
public void getWomanResult(Woman woman) {
System.out.println("女人给的评价: 歌手很表演有点糟糕");
}
}

/**
* 数据结构,管理很多人(Man , Woman)
*/
class ObjectStructure {
//维护了一个集合
private List<Person> persons = new LinkedList<>();

//添加
public void add(Person p) {
persons.add(p);
}

//删除
public void delete(Person p) {
persons.remove(p);
}

// 显示测评情况(便利)
public void show(Action action) {
for (Person p : persons) {
p.accept(action);
}
}
}

/**
* 测试类
*/
public class Client {
public static void main(String[] args) {
// 使用数据结构来创建
ObjectStructure os = new ObjectStructure();
// 添加我们我们的访问者
os.add(new Man());
os.add(new Woman());


// 创建成功的被访问者
Success success = new Success();
// 通过数据结果遍历访问者,然后进行访问成功的数据
os.show(success);
System.out.println("========================");

// 创建失败的被访问者
Fail fail = new Fail();
// 通过数据结果遍历访问者,然后进行访问失败的数据
os.show(fail);
System.out.println("========================");

// 创建中肯的的被访问者
Normal normal = new Normal();
os.show(normal);
}
}

其实访问者模式和观察者模式的思想也非常类似,代码实现也很类似。都会提供一个管理被访问者/观察者集合,提供新增和删除方法,并且提供一个遍历集合的方法,并通知所有元素或者指定元素的方法。

它们只是应用场景不一样,其实类图都很类似。

结果输出

3、小结

其实我们可以看出,状态模式和策略模式很类似,简直就是亲兄弟一样。而访问者模式其实和观察者模式也很类似。所以我们的设计模式设计到最后,可能就会存在一种模式里有另一种模式的影子。所以我们要搞清楚它们之间的区别。

责任编辑:武晓燕 来源: 今日头条
相关推荐

2011-10-10 10:10:14

2009-11-04 10:57:35

2011-08-30 10:03:59

软件工程

2022-11-09 07:18:18

驱动测试BDD

2011-04-07 16:20:24

软件架构师架构师架构

2012-12-13 09:47:15

软件架构师架构师

2022-10-19 15:34:11

架构软件安全

2023-06-05 10:07:13

软件工程平台工程师

2022-01-16 07:12:30

软件工程师吵架开发

2023-10-23 11:49:59

2020-08-28 13:20:53

谷歌Android开发者

2009-02-11 13:15:54

软件工程师女工程师google

2011-04-07 16:06:18

测试架构师测试架构

2009-02-12 14:45:17

软件工程师

2022-09-16 08:00:00

软件工程师求职薪酬

2014-08-20 10:24:11

软件工程师

2013-09-03 09:30:44

软件工程师软件工程师头衔

2010-08-10 13:29:58

软件工程师

2011-05-16 10:05:33

软件工程师Java工程师

2021-10-22 08:00:00

架构开发技术
点赞
收藏

51CTO技术栈公众号