前言

最近开始琢磨设计模式了,发现自己在做程序设计时,老是没有头绪,所以拿起了这本典型的设计模式入门书籍-《Head First 设计模式》,之前就是看这个系列的《Head Frist Java》入门Java的,感觉适合我这种不太会的宝宝。

在这里记录下自己阅读所产生的思考。

内容

设计原则:

  1. 针对接口编程,而不是实现编程
  2. 多用组合,少用继承

策略模式

策略模式就是为接口定义一组算法族,供其选择。

策略模式允许你定义一系列算法,并将它们封装在独立的类中,使得它们可以互换使用。

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
// 策略接口
interface Strategy {
int execute(int a, int b);
}

// 具体策略:加法
class AddStrategy implements Strategy {
public int execute(int a, int b) {
return a + b;
}
}

// 具体策略:减法
class SubtractStrategy implements Strategy {
public int execute(int a, int b) {
return a - b;
}
}

// 上下文类
class Context {
private Strategy strategy;

public Context(Strategy strategy) {
this.strategy = strategy;
}

public int executeStrategy(int a, int b) {
return strategy.execute(a, b);
}
}

// 客户端代码
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context(new AddStrategy());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

context = new Context(new SubtractStrategy());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
}
}

观察者模式

观察者模式中分两个角色,主题(Subject)观察者(Observer)

观察者会统一实现一个接口,其中有用于接收主题通知的方法,主题统一调用。

观察者可随时向主题注册、注销。

观察者模式定义了对象之间的一对多依赖关系,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

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
import java.util.ArrayList;
import java.util.List;

// 主题接口
interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}

// 具体主题
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private int state;

public void setState(int state) {
this.state = state;
notifyObservers();
}

public void registerObserver(Observer o) {
observers.add(o);
}

public void removeObserver(Observer o) {
observers.remove(o);
}

public void notifyObservers() {
for (Observer observer : observers) {
observer.update(state);
}
}
}

// 观察者接口
interface Observer {
void update(int state);
}

// 具体观察者
class ConcreteObserver implements Observer {
private int state;

public void update(int state) {
this.state = state;
System.out.println("Observer updated with state: " + state);
}
}

// 客户端代码
public class ObserverPatternDemo {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observer1 = new ConcreteObserver();
ConcreteObserver observer2 = new ConcreteObserver();

subject.registerObserver(observer1);
subject.registerObserver(observer2);

subject.setState(10);
subject.setState(20);
}
}

装饰者模式

用于解决继承滥用的问题,各个子类中的内容相似,则将组件提取出来作为装饰类。

装饰类与被装饰类实现的接口一致,可用作方法扩展方法增强(包裹方法)。

java.io包多为装饰类。

装饰者模式允许你通过将对象放入包含行为的特殊封装对象中来为原对象增加新的行为。

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
// 组件接口
interface Component {
void operation();
}

// 具体组件
class ConcreteComponent implements Component {
public void operation() {
System.out.println("ConcreteComponent operation");
}
}

// 装饰者抽象类
abstract class Decorator implements Component {
protected Component component;

public Decorator(Component component) {
this.component = component;
}

public void operation() {
component.operation();
}
}

// 具体装饰者
class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}

public void operation() {
super.operation();
addedBehavior();
}

private void addedBehavior() {
System.out.println("ConcreteDecoratorA added behavior");
}
}

// 客户端代码
public class DecoratorPatternDemo {
public static void main(String[] args) {
Component component = new ConcreteComponent();
Component decoratedComponent = new ConcreteDecoratorA(component);

decoratedComponent.operation();
}
}

工厂模式

用于制造对象。

工厂模式提供了一种创建对象的方式,而无需指定具体的类。

简单工厂模式

像静态或者非静态的那种普通的工厂类,叫做简单工厂模式,是大家广为了解的。

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
// 产品接口
interface Product {
void use();
}

// 具体产品A
class ProductA implements Product {
public void use() {
System.out.println("Using ProductA");
}
}

// 具体产品B
class ProductB implements Product {
public void use() {
System.out.println("Using ProductB");
}
}

// 简单工厂
class SimpleFactory {
public static Product createProduct(String type) {
if (type.equals("A")) {
return new ProductA();
} else if (type.equals("B")) {
return new ProductB();
}
return null;
}
}

// 客户端代码
public class SimpleFactoryDemo {
public static void main(String[] args) {
Product productA = SimpleFactory.createProduct("A");
productA.use();

Product productB = SimpleFactory.createProduct("B");
productB.use();
}
}

工厂方法模式

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
// 产品接口
interface Product {
void use();
}

// 具体产品A
class ProductA implements Product {
public void use() {
System.out.println("Using ProductA");
}
}

// 具体产品B
class ProductB implements Product {
public void use() {
System.out.println("Using ProductB");
}
}

// 工厂接口
interface Factory {
Product createProduct();
}

// 具体工厂A
class FactoryA implements Factory {
public Product createProduct() {
return new ProductA();
}
}

// 具体工厂B
class FactoryB implements Factory {
public Product createProduct() {
return new ProductB();
}
}

// 客户端代码
public class FactoryMethodDemo {
public static void main(String[] args) {
Factory factoryA = new FactoryA();
Product productA = factoryA.createProduct();
productA.use();

Factory factoryB = new FactoryB();
Product productB = factoryB.createProduct();
productB.use();
}
}

抽象工厂模式

每个方法都像是工厂模式

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
75
76
77
78
79
80
81
// 产品接口
interface ProductA {
void use();
}

interface ProductB {
void use();
}

// 具体产品A1
class ProductA1 implements ProductA {
public void use() {
System.out.println("Using ProductA1");
}
}

// 具体产品B1
class ProductB1 implements ProductB {
public void use() {
System.out.println("Using ProductB1");
}
}

// 具体产品A2
class ProductA2 implements ProductA {
public void use() {
System.out.println("Using ProductA2");
}
}

// 具体产品B2
class ProductB2 implements ProductB {
public void use() {
System.out.println("Using ProductB2");
}
}

// 抽象工厂接口
interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}

// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
public ProductA createProductA() {
return new ProductA1();
}

public ProductB createProductB() {
return new ProductB1();
}
}

// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
public ProductA createProductA() {
return new ProductA2();
}

public ProductB createProductB() {
return new ProductB2();
}
}

// 客户端代码
public class AbstractFactoryDemo {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
productA1.use();
productB1.use();

AbstractFactory factory2 = new ConcreteFactory2();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
productA2.use();
productB2.use();
}
}

单件模式

单件模式确保一个类只有一个实例,并提供一个全局访问点。

用于创建一个独一无二的对象,有下面两种实现方式

  1. 第一次调用再初始化

    多线程不安全

    1. 直接在方法上加锁:效率低
    2. 双重检查加锁volatile
  2. 直接初始化

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
// 单件类
class Singleton {
private static volatile Singleton instance;

private Singleton() {}

public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}

public void doSomething() {
System.out.println("Singleton is doing something");
}
}

// 客户端代码
public class SingletonPatternDemo {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
singleton.doSomething();
}
}