软件设计原理3-设计模式

设计模式基础

设计模式的精髓是对多态的使用

装饰器模式

装饰模式最大的特点是,通过类的构造函数传入一个同类对象,也就是每个类实现的接口和构造函数传入的对象是同一个接口。

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
public interface AnyThing {
void exe();
}

public class Moon implements AnyThing {
private AnyThing a;
public Moon(AnyThing a) {
this.a = a;
}
public void exe() {
System.out.print("明月装饰了");
a.exe();
}
}

public class Dream implements AnyThing {
private AnyThing a;
public Dream(AnyThing a) {
this.a=a;
}
public void exe() {
System.out.print("梦装饰了");
a.exe();
}
}

public class You implements AnyThing {
private AnyThing a;
public You(AnyThing a) {
this.a = a;
}
public void exe() {
System.out.print("你");
}
}

调用:

1
2
3
4
5
6
7
8
9
10
AnyThing t = new Moon(new Dream(new You(null)));
t.exe();

输出:明月装饰了梦装饰了你


AnyThing t = new Dream(new Moon(new You(null)));
t.exe();

输出:梦装饰了明月装饰了你

面试官让你“聊聊设计模式”,也许你可以这样回答:“除了单例和工厂,我更喜欢适配器和观察者,还有,组合模式在处理树形结构的时候也非常有用。”

组合模式遍历树:

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
public class DefaultModule implements Module {

private final String value;

public DefaultModule(String value) {
this.value = value;
}

@Override
public void print() {
System.out.println(value);
}
}

public class ComponentModule implements Module {

private final Module currentModule;

private final List<Module> modules;

public ComponentModule(Module currentModule, Module... modules) {
this.currentModule = currentModule;
this.modules = Arrays.asList(modules);
}

@Override
public void print() {
this.currentModule.print();
this.modules.forEach(Module::print);
}
}

public interface Module {

void print();

static void main(String[] args) {
ComponentModule subModule31 = new ComponentModule(
new DefaultModule("31"),
new DefaultModule("311"),
new DefaultModule("312"),
new DefaultModule("313")
);

ComponentModule subModule3 = new ComponentModule(
new DefaultModule("3"),
subModule31,
new DefaultModule("32"),
new DefaultModule("33")
);

ComponentModule module = new ComponentModule(
new DefaultModule("0"),
new DefaultModule("1"),
new DefaultModule("2"),
subModule3
);

module.print();
}
}

设计模式应用:编程框架中的设计模式

什么是框架

框架式对某一类架构方案可复用设计与实现

Tomcat是框架,它完成了Web应用请求响应的主体流程。框架应用满足依赖倒置原则.

框架会调用我们编写的代码,而我们编写的代码则会调用工具完成某些特定的功能,比如输出日志,进行正则表达式匹配等.

dp

Web容器中的设计模式

1.策略模式

  • 策略接口:J2EE规范定义的Servlet接口
  • 策略实现:我们看开发的Servlet具体类
  • Client程序:Tomcat

2.模板方法模式

  • 父类中抽象方法定义计算的骨架和过程,抽象方法的实现留在子类。
  • HttpServlet extends GenericServlet implements Servlert
  • HttpServlet中的service方法 针对不同的HTTP请求类型调用相应的方法,service方法就是一个模板方法。

JUnit中的设计模式

1.模板方法模式 测试用例的方法执行顺序固定在模板方法TestCase.runBare

2.测试套件TestSuite 采用组合模式

  • TestSuite.addTest(TestCase test)
  • TestSuite.addTest(TestSuite test)

组件的设计原则

软件设计的核心目标是高内聚、低耦合。从这两个角度思考组件的设计原则。

组件内聚原则

组件内聚原则主要讨论哪些类应该聚合在同一个组件中,以便组件既能提供相对完整的功能,又不至于太过庞大。

  1. 复用发布等同原则:软件复用的最小粒度应该等同于其发布的最小粒度。
  2. 共同封闭原则:我们应该将那些会同时修改,并且为了相同目的而修改的类放到同一个组件中。
  3. 共同复用原则:不要强迫一个组件的用户依赖他们不需要的东西。

组件耦合原则

组件内聚原则讨论的是组件应该包含哪些功能和类,而组件耦合原则讨论组件之间的耦合关系应该如何设计。

  1. 无循环依赖原则:组件依赖关系中不应该出现环。
  2. 稳定依赖原则:组件依赖关系必须指向更稳定的方向。组件不应该依赖一个比自己还不稳定的组件。
  3. 稳定抽象原则:一个组件的抽象化程度应该与其稳定性程度一致。也就是说,一个稳定的组件应该是抽象的,而不稳定的组件应该是具体的。如果你设计的组件是具体的、不稳定的,那么可以为这个组件对外提供服务的类设计一组接口,并把这组接口封装在一个专门的组件中,那么这个组件相对就比较抽象、稳定。如前面讲的依赖倒置原则 (DIP)。

书籍

  1. UML精粹
  2. 敏捷软件开发:原则、模式与实践
  3. 架构整洁之道
  4. 企业应用架构模式