命令模式

[Musings]
今天是把剩余的命令模式+解释器+迭代器实现下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
public interface Command {
void execute();
void undo();
}

@Getter
public class Light {
private boolean status;

public void lightOn() {
System.out.println("Light on!");
this.status = true;
}

public void lightOff(){
System.out.println("Light off!");
this.status = false;
}

}

@AllArgsConstructor
public class LightsOnCommand implements Command{
private Light light;

@Override
public void execute() {
System.out.println("LightsOnCommand Light On");
light.lightOn();
}

@Override
public void undo() {
System.out.println("LightsOnCommand Undo Light On");
light.lightOff();
}
}

public class RemoteControl {

private Map<Integer, List<Command>> listMap;
private List<Command> undoList = new ArrayList();

public RemoteControl( ) {
this.listMap = new HashMap<>();
}

public void setCommand(int port, List<Command> list) {
listMap.put(port, list);
}

public void onButtonPressed(int port) {
this.listMap.get(port).forEach(
command -> {
command.execute();
this.undoList.add(command);
}
);
}

public void undoButtonPressed() {
if (undoList.size() == 0) return;
Command command = undoList.get(undoList.size() - 1);
command.undo();
undoList.remove(undoList.size()-1);
}
}

这里主要的思路就是command接口的声明,然后创建控制面板类,基于command接口去实现代码,这样控制面板类就可以面向接口编写,后续可以随意扩展command

然后我们写个解释器模式
📚 解释器模式题目:简单查询语言解释器

🎯 问题描述

设计一个简单的数据查询语言解释器,可以解析和执行类似SQL的查询条件。用户输入查询表达式,系统能够解析并过滤出符合条件的数据。

📋 需求说明

支持的基础表达式:

等于:field = value
大于:field > value
小于:field < value
包含:field contains value
支持的逻辑运算符:

与:and
或:or
非:not
查询示例:

text
name = 'Alice' and age > 20
department = 'IT' or (age > 25 and salary > 50000)
not name contains 'test'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
@Data
@AllArgsConstructor
public class User {
private String name;
private int age;
private String department;
private double salary;
}


public interface Expression {
boolean interpret(User users);
}

public class AndExpression implements Expression {
private Expression left;
private Expression right;
public AndExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}

@Override
public boolean interpret(User user) {
boolean interpret = left.interpret(user);
boolean interpret1 = right.interpret(user);
return interpret && interpret1;
}
}
public class EqualsExpression implements Expression {
private String field;
private String value;

public EqualsExpression(String field, String value) {
this.field = field;
this.value = value;
}

@Override
public boolean interpret(User users) {
if("name".equals(field)){
return users.getName().equals(value);
}
return false;
}
}
public class GreaterThanExpression implements Expression{
private String field;
private int value;

public GreaterThanExpression(String field, int value) {
this.field = field;
this.value = value;
}

@Override
public boolean interpret(User users) {
if("age".equals(field)){
return users.getAge()>value;
}
return false;
}
}
public class Main {
public static void main(String[] args) {
User user = new User("Alice", 30, "IT", 6000);
GreaterThanExpression age = new GreaterThanExpression("age", 25);
EqualsExpression name = new EqualsExpression("name", "Alice");
AndExpression andExpression = new AndExpression(age, name);
boolean interpret = andExpression.interpret(user);
System.out.println("年龄大于25吗? " + interpret); // 应该输出 true
}
}

思路就是申明interpreter接口,然后去实现不同的interpreter.
这里有一个悟道,就是在写设计模式的时候,不要看了题目就凭空想实现,想怎么抽象接口和类,而是应该去考虑,最后的main方法怎么写,先考虑结果,然后基于结果去反向推导,为了这样调用,我该如何去实现,如何拆分,设计行为和类.这样做更具像化,也更高效