├── demo
├── src
│ └── com
│ │ └── hit
│ │ └── math
│ │ ├── observer
│ │ ├── mime
│ │ │ ├── DisplayElement.java
│ │ │ ├── Observer.java
│ │ │ ├── Subject.java
│ │ │ ├── WeatherStation.java
│ │ │ ├── CurrentConditionsDisplay.java
│ │ │ ├── PredictConditionsDisplay.java
│ │ │ └── WeatherData.java
│ │ └── api
│ │ │ ├── WeatherStationApi.java
│ │ │ ├── WeatherDataApi.java
│ │ │ └── CurrentConditionsDisplayApi.java
│ │ ├── decorate
│ │ ├── CondimentDecorator.java
│ │ ├── Decat.java
│ │ ├── Espresso.java
│ │ ├── Beverage.java
│ │ ├── DarkRoast.java
│ │ ├── HouseBlend.java
│ │ ├── Milk.java
│ │ ├── Soy.java
│ │ ├── Whip.java
│ │ ├── Mocha.java
│ │ └── StarbuzzCoffer.java
│ │ ├── strategy
│ │ ├── Quack.java
│ │ ├── FlyBehavior.java
│ │ ├── FlyNoWay.java
│ │ ├── Squeak.java
│ │ ├── FlyWithWings.java
│ │ ├── QuackBehavior.java
│ │ ├── ModelDuck.java
│ │ ├── MuteDuck.java
│ │ ├── MallarDuck.java
│ │ ├── MiniDuckSimulator.java
│ │ └── Duck.java
│ │ └── singleton
│ │ ├── SingletonVariant.java
│ │ ├── Singleton.java
│ │ ├── SingletonSynchronized.java
│ │ └── SingletonDoubleCheck.java
└── test
│ └── com
│ └── hit
│ └── math
│ └── pattern
│ ├── DecorateTest.java
│ ├── SingletonTest.java
│ ├── StrategyTest.java
│ └── ObserverTest.java
├── .gitignore
├── LICENSE
├── README_CH.md
└── README.md
/demo/src/com/hit/math/observer/mime/DisplayElement.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.observer.mime;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/18,23:11
6 | * https:github.com/guobinhit
7 | * description:观察者模式(展示接口)
8 | */
9 | public interface DisplayElement {
10 | void display();
11 | }
12 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/observer/mime/Observer.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.observer.mime;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/18,23:12
6 | * https:github.com/guobinhit
7 | * description:观察者模式(观察者接口)
8 | */
9 | public interface Observer {
10 | void update(float temperature, float humidity, float pressure);
11 | }
12 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/decorate/CondimentDecorator.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.decorate;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/21,15:58
6 | * https:github.com/guobinhit
7 | * description:装饰模式(口味装饰抽象类)
8 | */
9 | public abstract class CondimentDecorator extends Beverage {
10 | public abstract String getDescription();
11 | }
12 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/strategy/Quack.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.strategy;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/17,19:43
6 | * https:github.com/guobinhit
7 | * description:策略模式(接口实现类)
8 | */
9 | public class Quack implements QuackBehavior {
10 |
11 | @Override
12 | public void quack() {
13 | System.out.println("Quack, quack, quack...");
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/strategy/FlyBehavior.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.strategy;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/17,19:32
6 | * https:github.com/guobinhit
7 | * description:策略模式(抽象行为接口)
8 | */
9 | public interface FlyBehavior {
10 |
11 | /**
12 | * 接口中的变量默认被 public static final 修饰
13 | * 接口中的方法默认被 public abstract 修饰
14 | */
15 | void fly();
16 | }
17 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/strategy/FlyNoWay.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.strategy;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/17,19:42
6 | * https:github.com/guobinhit
7 | * description:策略模式(接口实现类)
8 | */
9 | public class FlyNoWay implements FlyBehavior {
10 |
11 | @Override
12 | public void fly() {
13 | System.out.println("I don't know how to fly!");
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/strategy/Squeak.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.strategy;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/17,19:44
6 | * https:github.com/guobinhit
7 | * description:策略模式(接口实现类)
8 | */
9 | public class Squeak implements QuackBehavior {
10 |
11 | @Override
12 | public void quack() {
13 | System.out.println("Squeak, squeak, squeak...");
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/strategy/FlyWithWings.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.strategy;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/17,19:39
6 | * https:github.com/guobinhit
7 | * description:策略模式(接口实现类)
8 | */
9 | public class FlyWithWings implements FlyBehavior {
10 |
11 | @Override
12 | public void fly() {
13 | System.out.println("I'm flying with wings!");
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/strategy/QuackBehavior.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.strategy;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/17,19:33
6 | * https:github.com/guobinhit
7 | * description:策略模式(抽象行为接口)
8 | */
9 | public interface QuackBehavior {
10 |
11 | /**
12 | * 接口中的变量默认被 public static final 修饰
13 | * 接口中的方法默认被 public abstract 修饰
14 | */
15 | void quack();
16 | }
17 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/decorate/Decat.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.decorate;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/21,15:59
6 | * https:github.com/guobinhit
7 | * description:装饰模式
8 | */
9 | public class Decat extends Beverage {
10 |
11 | public Decat() {
12 | description = "Dacat";
13 | }
14 |
15 | @Override
16 | public double cost() {
17 | return 1.05;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/decorate/Espresso.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.decorate;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/21,15:59
6 | * https:github.com/guobinhit
7 | * description:装饰模式
8 | */
9 | public class Espresso extends Beverage {
10 |
11 | public Espresso() {
12 | description = "Espresso";
13 | }
14 |
15 | @Override
16 | public double cost() {
17 | return 1.99;
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/decorate/Beverage.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.decorate;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/21,15:58
6 | * https:github.com/guobinhit
7 | * description:装饰模式(饮料抽象类)
8 | */
9 | public abstract class Beverage {
10 | String description = "Unknown Beverage";
11 |
12 | public String getDescription() {
13 | return description;
14 | }
15 |
16 | public abstract double cost();
17 | }
18 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/decorate/DarkRoast.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.decorate;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/21,15:58
6 | * https:github.com/guobinhit
7 | * description:装饰模式
8 | */
9 | public class DarkRoast extends Beverage {
10 |
11 | public DarkRoast() {
12 | description = "Dark Roast Coffer";
13 | }
14 |
15 | @Override
16 | public double cost() {
17 | return 0.90;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/decorate/HouseBlend.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.decorate;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/21,15:59
6 | * https:github.com/guobinhit
7 | * description:装饰模式
8 | */
9 | public class HouseBlend extends Beverage {
10 |
11 | public HouseBlend() {
12 | description = "House Blend Coffer";
13 | }
14 |
15 | @Override
16 | public double cost() {
17 | return 0.80;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/observer/mime/Subject.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.observer.mime;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/18,23:12
6 | * https:github.com/guobinhit
7 | * description:观察者模式(主题接口)
8 | */
9 | public interface Subject {
10 |
11 | /**
12 | * 此接口中包含了观察者模式必须具备的方法,包括注册观察者、移除观察者和通知观察者
13 | */
14 | void registerObserver(Observer o);
15 |
16 | void removeObserver(Observer o);
17 |
18 | void notifyObservers();
19 | }
20 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/strategy/ModelDuck.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.strategy;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/17,19:54
6 | * https:github.com/guobinhit
7 | * description:策略模式(抽象类 Duck 的具体实现类)
8 | */
9 | public class ModelDuck extends Duck {
10 |
11 | /**
12 | * 通过无参的构造器,对行为进行初始化
13 | */
14 | public ModelDuck() {
15 | flyBehavior = new FlyNoWay();
16 | quackBehavior = new Squeak();
17 | }
18 |
19 | @Override
20 | public void display() {
21 | System.out.println("I'm a Model Duck!");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/strategy/MuteDuck.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.strategy;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/17,20:04
6 | * https:github.com/guobinhit
7 | * description:策略模式(抽象类 Duck 的具体实现类)
8 | */
9 | public class MuteDuck extends Duck {
10 |
11 | /**
12 | * 通过无参的构造器,对行为进行初始化
13 | */
14 | public MuteDuck() {
15 | flyBehavior = new FlyNoWay();
16 | quackBehavior = new Squeak();
17 | }
18 |
19 | @Override
20 | public void display() {
21 | System.out.println("I'm not a real Duck!");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/strategy/MallarDuck.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.strategy;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/17,19:54
6 | * https:github.com/guobinhit
7 | * description:策略模式(抽象类 Duck 的具体实现类)
8 | */
9 | public class MallarDuck extends Duck {
10 |
11 | /**
12 | * 通过无参的构造器,对行为进行初始化
13 | */
14 | public MallarDuck() {
15 | flyBehavior = new FlyWithWings();
16 | quackBehavior = new Quack();
17 | }
18 |
19 | @Override
20 | public void display() {
21 | System.out.println("I'm a really Mallard Duck!");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/decorate/Milk.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.decorate;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/21,16:00
6 | * https:github.com/guobinhit
7 | * description:装饰模式
8 | */
9 | public class Milk extends CondimentDecorator {
10 | Beverage beverage;
11 |
12 | public Milk(Beverage beverage) {
13 | this.beverage = beverage;
14 | }
15 |
16 | @Override
17 | public String getDescription() {
18 | return beverage.getDescription() + ", Milk";
19 | }
20 |
21 | @Override
22 | public double cost() {
23 | return 0.10 + beverage.cost();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/decorate/Soy.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.decorate;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/21,16:00
6 | * https:github.com/guobinhit
7 | * description:装饰模式
8 | */
9 | public class Soy extends CondimentDecorator {
10 | Beverage beverage;
11 |
12 | public Soy(Beverage beverage) {
13 | this.beverage = beverage;
14 | }
15 |
16 | @Override
17 | public String getDescription() {
18 | return beverage.getDescription() + ", Soy";
19 | }
20 |
21 | @Override
22 | public double cost() {
23 | return 0.15 + beverage.cost();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/decorate/Whip.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.decorate;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/21,16:01
6 | * https:github.com/guobinhit
7 | * description:装饰模式
8 | */
9 | public class Whip extends CondimentDecorator {
10 | Beverage beverage;
11 |
12 | public Whip(Beverage beverage) {
13 | this.beverage = beverage;
14 | }
15 |
16 | @Override
17 | public String getDescription() {
18 | return beverage.getDescription() + ", Whip";
19 | }
20 |
21 | @Override
22 | public double cost() {
23 | return 0.10 + beverage.cost();
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/decorate/Mocha.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.decorate;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/21,16:00
6 | * https:github.com/guobinhit
7 | * description:装饰模式(摩卡,继承口味装饰类)
8 | */
9 | public class Mocha extends CondimentDecorator {
10 | Beverage beverage;
11 |
12 | public Mocha(Beverage beverage) {
13 | this.beverage = beverage;
14 | }
15 |
16 | @Override
17 | public String getDescription() {
18 | return beverage.getDescription() + ", Mocha";
19 | }
20 |
21 | @Override
22 | public double cost() {
23 | return 0.20 + beverage.cost();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/singleton/SingletonVariant.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.singleton;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/16,22:04
6 | * https://github.com/guobinhit
7 | * description:单例模式(急切实例化)
8 | */
9 | public class SingletonVariant {
10 |
11 | /**
12 | * 定义单例全局变量
13 | */
14 | private static SingletonVariant uniqueInstance = new SingletonVariant();
15 |
16 | /**
17 | * 私有化构造函数
18 | */
19 | private SingletonVariant() {
20 | }
21 |
22 | /**
23 | * 提供获取实例的公共静态方法
24 | *
25 | * @return SingletonVariant
26 | */
27 | public static SingletonVariant getInstance() {
28 | return uniqueInstance;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/observer/api/WeatherStationApi.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.observer.api;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/18,23:10
6 | * https:github.com/guobinhit
7 | * description:观察者模式(气象站)
8 | */
9 | public class WeatherStationApi {
10 | public static void main(String[] args) {
11 | WeatherDataApi weatherDate = new WeatherDataApi();
12 | CurrentConditionsDisplayApi conditionsDisplay = new CurrentConditionsDisplayApi(weatherDate);
13 | // 展示初始化布告板
14 | conditionsDisplay.display();
15 | // 更新布告板,仍然皆为初始化值
16 | conditionsDisplay.update(weatherDate,null);
17 | // 修改布告板数据
18 | weatherDate.setMeasurements(80,65,30.4f);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/singleton/Singleton.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.singleton;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/16,21:56
6 | * https:github.com/guobinhit
7 | * description:经典单例模式(延迟实例化)
8 | */
9 | public class Singleton {
10 |
11 | /**
12 | * 定义单例全局变量
13 | */
14 | private static Singleton uniqueInstance;
15 |
16 | /**
17 | * 私有化构造函数
18 | */
19 | private Singleton() {
20 | }
21 |
22 | /**
23 | * 提供获取实例的公共静态方法
24 | *
25 | * @return Singleton
26 | */
27 | public static Singleton getInstance() {
28 | if (uniqueInstance == null) {
29 | uniqueInstance = new Singleton();
30 | }
31 | return uniqueInstance;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
25 |
26 | /target/
27 | !.mvn/wrapper/maven-wrapper.jar
28 |
29 | ### STS ###
30 | .apt_generated
31 | .classpath
32 | .factorypath
33 | .project
34 | .settings
35 | .springBeans
36 | .sts4-cache
37 |
38 | ### IntelliJ IDEA ###
39 | .idea
40 | *.iws
41 | *.iml
42 | *.ipr
43 | *.jar
44 | *.class
45 |
46 | ### NetBeans ###
47 | /nbproject/private/
48 | /build/
49 | /nbbuild/
50 | /dist/
51 | /nbdist/
52 | /.nb-gradle/
53 | **/target/
54 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/singleton/SingletonSynchronized.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.singleton;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/16,22:09
6 | * https:github.com/guobinhit
7 | * description:单例模式(增加 synchronized 同步关键字,可用于多线程)
8 | */
9 | public class SingletonSynchronized {
10 |
11 | /**
12 | * 定义单例全局变量
13 | */
14 | private static SingletonSynchronized uniqueInstance;
15 |
16 | /**
17 | * 私有化构造函数
18 | */
19 | private SingletonSynchronized() {
20 | }
21 |
22 | /**
23 | * 提供获取实例的公共静态同步方法
24 | *
25 | * 通过增加 synchronized 关键字到 getInstance() 方法中,
26 | * 我们迫使每个线程在进入这个方法之前,都要先等候别的线程离开该方法
27 | *
28 | * 也就是说,不会有两个线程同时进入这个方法
29 | *
30 | * @return SingletonSynchronized
31 | */
32 | public static synchronized SingletonSynchronized getInstance() {
33 | if (uniqueInstance == null) {
34 | uniqueInstance = new SingletonSynchronized();
35 | }
36 | return uniqueInstance;
37 | }
38 | }
--------------------------------------------------------------------------------
/demo/src/com/hit/math/decorate/StarbuzzCoffer.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.decorate;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/21,16:01
6 | * https:github.com/guobinhit
7 | * description:装饰模式(咖啡店测试类)
8 | */
9 | public class StarbuzzCoffer {
10 | public static void main(String[] args) {
11 | /**
12 | * 装饰模式:
13 | * 缺点,子类比较多,繁杂;
14 | * 优点,组合方便,使用灵活。
15 | */
16 | Beverage beverage = new Espresso();
17 | System.out.println(beverage.getDescription() + " $" + beverage.cost());
18 |
19 | Beverage beverage2 = new Decat();
20 | beverage2 = new Mocha(beverage2);
21 | beverage2 = new Milk(beverage2);
22 | System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
23 |
24 | Beverage beverage3 = new HouseBlend();
25 | beverage3 = new Mocha(beverage3);
26 | beverage3 = new Soy(beverage3);
27 | beverage3 = new Whip(beverage3);
28 | System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
29 | }
30 | }
--------------------------------------------------------------------------------
/demo/src/com/hit/math/observer/mime/WeatherStation.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.observer.mime;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/18,23:13
6 | * https:github.com/guobinhit
7 | * description:观察者模式(气象站)
8 | */
9 | public class WeatherStation {
10 | public static void main(String[] args) {
11 | // 创建 WeatherData 对象,用于传递给观察者实现类的构造器
12 | WeatherData weatherData = new WeatherData();
13 | CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
14 | PredictConditionsDisplay predictConditionsDisplay = new PredictConditionsDisplay(weatherData);
15 | // 展示初始化布告板
16 | currentConditionsDisplay.display();
17 | // 更新布告板
18 | currentConditionsDisplay.update(88, 78, 32.4f);
19 | // 修改布告板数据
20 | weatherData.setMeasurements(80, 65, 30.4f);
21 |
22 | /**
23 | * 实际上,在修改 currentConditionsDisplay 的时候,
24 | * predictConditionsDisplay 就会得到通知,再次输出一遍,用于对比
25 | */
26 | predictConditionsDisplay.display();
27 | }
28 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Charies Gavin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/demo/test/com/hit/math/pattern/DecorateTest.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.pattern;
2 |
3 | import com.hit.math.decorate.*;
4 |
5 | /**
6 | * author:Charies Gavin
7 | * date:2020/8/6, 22:50
8 | * https://github.com/guobinhit
9 | * description:装饰模式
10 | */
11 | public class DecorateTest {
12 | public static void main(String[] args) {
13 | /**
14 | * 装饰模式:
15 | * 缺点,子类比较多,繁杂;
16 | * 优点,组合方便,使用灵活。
17 | */
18 | Beverage beverage = new Espresso();
19 | System.out.println(beverage.getDescription() + " $" + beverage.cost());
20 |
21 | Beverage beverage2 = new Decat();
22 | beverage2 = new Mocha(beverage2);
23 | beverage2 = new Milk(beverage2);
24 | System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
25 |
26 | Beverage beverage3 = new HouseBlend();
27 | beverage3 = new Mocha(beverage3);
28 | beverage3 = new Soy(beverage3);
29 | beverage3 = new Whip(beverage3);
30 | System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
31 |
32 | Beverage beverage4 = new DarkRoast();
33 | beverage4 = new Whip(beverage4);
34 | System.out.println(beverage4.getDescription() + " $" + beverage4.cost());
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/singleton/SingletonDoubleCheck.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.singleton;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/16,22:17
6 | * https:github.com/guobinhit
7 | * description:单例模式(多重检查加锁,可用于多线程)
8 | */
9 | public class SingletonDoubleCheck {
10 |
11 | /**
12 | * volatile 关键字确保当 uniqueInstance 变量被初始化为 SingletonDoubleCheck 实例时,
13 | * 多个线程正确地处理 uniqueInstance 变量
14 | */
15 | private volatile static SingletonDoubleCheck uniqueInstance;
16 |
17 | /**
18 | * 私有化构造方法
19 | */
20 | private SingletonDoubleCheck() {
21 | }
22 |
23 | /**
24 | * 提供获取实例的公共静态方法
25 | *
26 | * 检查实例时,如果不存在,就进入同步块,同步块的锁为 SingletonDoubleCheck.class
27 | *
28 | * @return SingletonDoubleCheck
29 | */
30 | public static SingletonDoubleCheck getInstance() {
31 | /**
32 | * 注意:只有第一次才彻底执行这里的代码
33 | */
34 | if (uniqueInstance == null) {
35 | synchronized (SingletonDoubleCheck.class) {
36 | /**
37 | * 进入同步块后,再检查一次,如果仍是 null,则创建实例
38 | */
39 | if (uniqueInstance == null) {
40 | uniqueInstance = new SingletonDoubleCheck();
41 | }
42 | }
43 | }
44 | return uniqueInstance;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/strategy/MiniDuckSimulator.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.strategy;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * author:Charies Gavin
8 | * date:2017/9/17,19:57
9 | * https:github.com/guobinhit
10 | * description:策略模式(模拟测试类)
11 | */
12 | public class MiniDuckSimulator {
13 | public static void main(String[] args) {
14 | /**
15 | * 创建 Duck 实例
16 | */
17 | Duck mallarDuck = new MallarDuck();
18 | Duck muteDuck = new MuteDuck();
19 | List duckList = new ArrayList<>();
20 | duckList.add(mallarDuck);
21 | duckList.add(muteDuck);
22 |
23 | /**
24 | * 循环
25 | */
26 | for (Duck duck : duckList) {
27 | MiniDuckSimulator.duckGoGO(duck);
28 | }
29 |
30 | System.out.println("----- 动态修改 Duck 的行为 -----");
31 |
32 | /**
33 | * 创建 ModelDuck,动态修改 ModelDuck 的行为
34 | */
35 | Duck modelDuck = new ModelDuck();
36 | modelDuck.performFly();
37 | modelDuck.setFlyBehavior(new FlyWithWings());
38 | modelDuck.performFly();
39 | }
40 |
41 | /**
42 | * 封装 Duck 行为
43 | *
44 | * @param duck
45 | */
46 | private static void duckGoGO(Duck duck) {
47 | duck.performQuack();
48 | duck.performFly();
49 | duck.swim();
50 | duck.display();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/strategy/Duck.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.strategy;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/9/17,19:45
6 | * https:github.com/guobinhit
7 | * description:策略模式(抽象类)
8 | */
9 | public abstract class Duck {
10 |
11 | /**
12 | * 多用组合,少用继承,增加代码灵活性
13 | */
14 | FlyBehavior flyBehavior;
15 | QuackBehavior quackBehavior;
16 |
17 | /**
18 | * 无参构造器,也可以称之为默认构造器
19 | */
20 | public Duck() {
21 | }
22 |
23 | /**
24 | * 将方法用 abstract 修饰,强制导出类必须覆盖此方法
25 | */
26 | public abstract void display();
27 |
28 | /**
29 | * 通用执行方法,只要是 FlyBehavior 的实现类,都可以调用此方法
30 | */
31 | public void performFly() {
32 | flyBehavior.fly();
33 | }
34 |
35 | /**
36 | * 通用执行方法,只要是 QuackBehavior 的实现类,都可以调用此方法
37 | */
38 | public void performQuack() {
39 | quackBehavior.quack();
40 | }
41 |
42 | /**
43 | * 动态设置鸭子的 FlyBehavior
44 | *
45 | * @param fb FlyBehavior 实现类
46 | */
47 | public void setFlyBehavior(FlyBehavior fb) {
48 | this.flyBehavior = fb;
49 | }
50 |
51 | /**
52 | * 动态设置鸭子的 QuackBehavior
53 | *
54 | * @param qb QuackBehavior 实现类
55 | */
56 | public void setQuackBehavior(QuackBehavior qb) {
57 | this.quackBehavior = qb;
58 | }
59 |
60 | public void swim() {
61 | System.out.println("All duck float, even decoys!");
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/observer/api/WeatherDataApi.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.observer.api;
2 |
3 | import java.util.Observable;
4 |
5 | /**
6 | * author:Charies Gavin
7 | * date:2017/10/18,23:09
8 | * https:github.com/guobinhit
9 | * description:观察者模式(继承了 Java 内置的 Observable 类)
10 | */
11 | public class WeatherDataApi extends Observable {
12 | private float temperature;
13 | private float humidity;
14 | private float pressure;
15 |
16 | /**
17 | * 默认构造器
18 | */
19 | public WeatherDataApi() {
20 | }
21 |
22 | public void measurementsChanged() {
23 | /**
24 | * 调用 setChanged() 标记状态已经改变的事实
25 | */
26 | setChanged();
27 |
28 | /**
29 | * 注意:Observable 内置的通知观察者方法有两个版本,分别为
30 | * 1)notifyObservers()
31 | * 2)notifyObservers(Object arg)
32 | * 当我们使用没有参数的 1)时,表示我们采取的获取数据的方式为"拉"
33 | */
34 | notifyObservers();
35 | }
36 |
37 | public void setMeasurements(float temperature, float humidity, float pressure) {
38 | this.temperature = temperature;
39 | this.humidity = humidity;
40 | this.pressure = pressure;
41 | measurementsChanged();
42 | }
43 |
44 | public float getTemperature() {
45 | return temperature;
46 | }
47 |
48 | public float getHumidity() {
49 | return humidity;
50 | }
51 |
52 | public float getPressure() {
53 | return pressure;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/observer/mime/CurrentConditionsDisplay.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.observer.mime;
2 |
3 | /**
4 | * author:Charies Gavin
5 | * date:2017/10/18,23:12
6 | * https:github.com/guobinhit
7 | * description:观察者模式(实现了观察者接口和展示接口)
8 | */
9 | public class CurrentConditionsDisplay implements Observer, DisplayElement {
10 | private float temperature;
11 | private float humidity;
12 | private float pressure;
13 |
14 | /**
15 | * 有参构造器,通过 Subject 类型的参数注册为观察者
16 | *
17 | * @param weatherData 主题数据
18 | */
19 | public CurrentConditionsDisplay(Subject weatherData) {
20 | weatherData.registerObserver(this);
21 | }
22 |
23 | /**
24 | * 覆盖 Observer 中的 update() 方法
25 | *
26 | * @param temperature
27 | * @param humidity
28 | * @param pressure
29 | */
30 | @Override
31 | public void update(float temperature, float humidity, float pressure) {
32 | this.temperature = temperature;
33 | this.humidity = humidity;
34 | this.pressure = pressure;
35 | display();
36 | }
37 |
38 | /**
39 | * 覆盖 DisplayElement 中的 display() 方法
40 | */
41 | @Override
42 | public void display() {
43 | System.out.println("Current conditions: " + temperature +
44 | "F degrees and " + humidity + "% humidity and " + pressure + "Pa Pressure!");
45 | }
46 |
47 | @Override
48 | public String toString() {
49 | return "CurrentConditionsDisplay";
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/demo/test/com/hit/math/pattern/SingletonTest.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.pattern;
2 |
3 | import com.hit.math.singleton.Singleton;
4 | import com.hit.math.singleton.SingletonDoubleCheck;
5 | import com.hit.math.singleton.SingletonSynchronized;
6 | import com.hit.math.singleton.SingletonVariant;
7 |
8 | /**
9 | * author:Charies Gavin
10 | * date:2020/8/4, 23:00
11 | * https://github.com/guobinhit
12 | * description:单例模式
13 | */
14 | public class SingletonTest {
15 | public static void main(String[] args) {
16 | // 经典单例模式(延迟实例化)
17 | Singleton singleton = Singleton.getInstance();
18 | Singleton singleton2 = Singleton.getInstance();
19 | System.out.println(singleton.equals(singleton2));
20 | // 单例模式(急切实例化)
21 | SingletonVariant singletonVariant = SingletonVariant.getInstance();
22 | SingletonVariant singletonVariant2 = SingletonVariant.getInstance();
23 | System.out.println(singletonVariant.equals(singletonVariant2));
24 | // 单例模式(增加 synchronized 同步关键字,可用于多线程)
25 | SingletonSynchronized singletonSynchronized = SingletonSynchronized.getInstance();
26 | SingletonSynchronized singletonSynchronized2 = SingletonSynchronized.getInstance();
27 | System.out.println(singletonSynchronized.equals(singletonSynchronized2));
28 | // 单例模式(多重检查加锁,可用于多线程)
29 | SingletonDoubleCheck singletonDoubleCheck = SingletonDoubleCheck.getInstance();
30 | SingletonDoubleCheck singletonDoubleCheck2 = SingletonDoubleCheck.getInstance();
31 | System.out.println(singletonDoubleCheck.equals(singletonDoubleCheck2));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/observer/api/CurrentConditionsDisplayApi.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.observer.api;
2 |
3 |
4 | import com.hit.math.observer.mime.DisplayElement;
5 |
6 | import java.util.Observable;
7 | import java.util.Observer;
8 |
9 | /**
10 | * author:Charies Gavin
11 | * date:2017/10/18,23:09
12 | * https:github.com/guobinhit
13 | * description:观察者模式(实现了 Java 内置的 Observer 接口以及我们自定义的展示接口)
14 | */
15 | public class CurrentConditionsDisplayApi implements Observer, DisplayElement {
16 | private float temperature;
17 | private float humidity;
18 | private float pressure;
19 |
20 | /**
21 | * 有参构造器,在构造器内部注册观察者
22 | *
23 | * @param observable
24 | */
25 | public CurrentConditionsDisplayApi(Observable observable) {
26 | observable.addObserver(this);
27 | }
28 |
29 | /**
30 | * 覆盖 Observer 接口中的 update() 方法
31 | * 其中 obs 表示实现了可观察者的类,arg 则为传递给观察者的数据对象,可以为 null
32 | *
33 | * @param obs 可观察者实现类
34 | * @param arg 传递给观察者的数据对象
35 | */
36 | @Override
37 | public void update(Observable obs, Object arg) {
38 | if (obs instanceof WeatherDataApi) {
39 | WeatherDataApi weatherDate = (WeatherDataApi) obs;
40 | this.temperature = weatherDate.getTemperature();
41 | this.humidity = weatherDate.getHumidity();
42 | this.pressure = weatherDate.getPressure();
43 | display();
44 | }
45 | }
46 |
47 | @Override
48 | public void display() {
49 | System.out.println("Current conditions: " + temperature +
50 | "F degrees and " + humidity + "% humidity and " + pressure + "Pa Pressure!");
51 | }
52 | }
--------------------------------------------------------------------------------
/demo/test/com/hit/math/pattern/StrategyTest.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.pattern;
2 |
3 | import com.hit.math.strategy.*;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | /**
9 | * author:Charies Gavin
10 | * date:2020/8/6, 22:30
11 | * https://github.com/guobinhit
12 | * description:策略模式
13 | */
14 | public class StrategyTest {
15 | public static void main(String[] args) {
16 | /**
17 | * 创建 Duck 实例
18 | */
19 | Duck mallarDuck = new MallarDuck();
20 | Duck muteDuck = new MuteDuck();
21 | Duck modelDuck = new ModelDuck();
22 | List duckList = new ArrayList<>();
23 | duckList.add(mallarDuck);
24 | duckList.add(muteDuck);
25 | duckList.add(modelDuck);
26 |
27 | /**
28 | * 循环打印鸭子行为
29 | */
30 | for (int i = 0; i < duckList.size(); i++) {
31 | StrategyTest.duckGoGO(duckList.get(i));
32 | if (i != duckList.size() - 1) {
33 | System.out.println(" --- --- --- ");
34 | }
35 | }
36 |
37 | System.out.println("----- 动态修改 Duck 的行为 -----");
38 |
39 | /**
40 | * 创建 ModelDuck,动态修改 ModelDuck 的行为
41 | */
42 | Duck modelDuck2 = new ModelDuck();
43 | modelDuck2.performFly();
44 | modelDuck2.setFlyBehavior(new FlyWithWings());
45 | modelDuck2.performFly();
46 | }
47 |
48 | /**
49 | * 封装 Duck 行为
50 | *
51 | * @param duck
52 | */
53 | private static void duckGoGO(Duck duck) {
54 | duck.performQuack();
55 | duck.performFly();
56 | duck.swim();
57 | duck.display();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/observer/mime/PredictConditionsDisplay.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.observer.mime;
2 |
3 | import java.util.Random;
4 |
5 | /**
6 | * author:Charies Gavin
7 | * date:2020/12/24,23:12
8 | * https:github.com/guobinhit
9 | * description:观察者模式(实现了观察者接口和展示接口)
10 | */
11 | public class PredictConditionsDisplay implements Observer, DisplayElement {
12 | private float temperature;
13 | private float humidity;
14 | private float pressure;
15 |
16 | // 随机数
17 | private Random random;
18 |
19 | /**
20 | * 有参构造器,通过 Subject 类型的参数注册为观察者
21 | *
22 | * @param weatherData 主题数据
23 | */
24 | public PredictConditionsDisplay(Subject weatherData) {
25 | weatherData.registerObserver(this);
26 | random = new Random(47);
27 | }
28 |
29 | /**
30 | * 覆盖 Observer 中的 update() 方法
31 | *
32 | * @param temperature
33 | * @param humidity
34 | * @param pressure
35 | */
36 | @Override
37 | public void update(float temperature, float humidity, float pressure) {
38 | this.temperature = temperature + random.nextInt(10);
39 | this.humidity = humidity + random.nextInt(10);
40 | this.pressure = pressure + random.nextInt(10);
41 | display();
42 | }
43 |
44 | /**
45 | * 覆盖 DisplayElement 中的 display() 方法
46 | */
47 | @Override
48 | public void display() {
49 | System.out.println("Predict conditions: " + temperature +
50 | "F degrees and " + humidity + "% humidity and " + pressure + "Pa Pressure!");
51 | }
52 |
53 | @Override
54 | public String toString() {
55 | return "PredictConditionsDisplay";
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/demo/src/com/hit/math/observer/mime/WeatherData.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.observer.mime;
2 |
3 | import java.util.ArrayList;
4 |
5 | /**
6 | * author:Charies Gavin
7 | * date:2017/10/18,23:13
8 | * https:github.com/guobinhit
9 | * description:观察者模式(实现了主题接口)
10 | */
11 | public class WeatherData implements Subject {
12 | private ArrayList observers;
13 | private float temperature;
14 | private float humidity;
15 | private float pressure;
16 |
17 | /**
18 | * 默认构造器
19 | */
20 | public WeatherData() {
21 | /**
22 | * 创建观察者列表
23 | */
24 | observers = new ArrayList<>();
25 | }
26 |
27 | @Override
28 | public void registerObserver(Observer o) {
29 | observers.add(o);
30 | }
31 |
32 | @Override
33 | public void removeObserver(Observer o) {
34 | int i = observers.indexOf(o);
35 | if (i >= 0) {
36 | observers.remove(o);
37 | }
38 | }
39 |
40 | @Override
41 | public void notifyObservers() {
42 | for (Observer observer : observers) {
43 | observer.update(temperature, humidity, pressure);
44 | System.out.println("observer of " + observer + " be updated.");
45 | }
46 | }
47 |
48 | /**
49 | * 调用通知观察者方法,通知所有观察者
50 | */
51 | public void measurementsChanged() {
52 | notifyObservers();
53 | }
54 |
55 | /**
56 | * 设置气象观测数据
57 | *
58 | * @param temperature
59 | * @param humidity
60 | * @param pressure
61 | */
62 | public void setMeasurements(float temperature, float humidity, float pressure) {
63 | this.temperature = temperature;
64 | this.humidity = humidity;
65 | this.pressure = pressure;
66 | measurementsChanged();
67 | }
68 |
69 | public float getTemperature() {
70 | return temperature;
71 | }
72 |
73 | public float getHumidity() {
74 | return humidity;
75 | }
76 |
77 | public float getPressure() {
78 | return pressure;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/README_CH.md:
--------------------------------------------------------------------------------
1 | > **注意**:如果你想要阅读英文版`README`, 请点击 [这里](https://github.com/guobinhit/design-pattern/blob/master/README.md).
2 |
3 | # 设计模式
4 |
5 | 详细介绍了设计模式,并给出了大量的 Java 示例。
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 | 装饰模式(也称为`Wrapper`,与适配器模式共享的另一种命名)是一种设计模式,允许将行为静态或动态地添加到单个对象中,而不会影响来自同一类的其他对象的行为。装饰模式对于坚持“单一责任原则”通常很有用,因为它允许在具有独特关注区域的类之间划分功能。
62 |
63 | > 装饰设计模式能解决什么问题?
64 |
65 | - 职责应该在运行时动态地添加(或者删除)到对象。
66 | - 应该为扩展功能提供一个灵活的子类化替代方法。
67 |
68 |
69 | ## 观察者模式
70 |
71 | 观察者模式是一种软件设计模式,在这种模式中,一个称为主题的对象维护其从属对象(称为观察者)的列表,并通过调用其方法,使其自动通知观察者更改其状态。
72 |
73 | > 观察者设计模式解决了以下问题:
74 |
75 | - 如何在不使对象紧密耦合的情况下,定义对象之间的一对多依赖关系?
76 | - 如何确保当一个对象改变状态时,会自动更新(同步)开放数量的观察者对象?
77 | - 一个对象如何通知一个开放数量的其他对象?
78 |
79 |
80 |
--------------------------------------------------------------------------------
/demo/test/com/hit/math/pattern/ObserverTest.java:
--------------------------------------------------------------------------------
1 | package com.hit.math.pattern;
2 |
3 | import com.hit.math.observer.api.CurrentConditionsDisplayApi;
4 | import com.hit.math.observer.api.WeatherDataApi;
5 | import com.hit.math.observer.mime.CurrentConditionsDisplay;
6 | import com.hit.math.observer.mime.WeatherData;
7 |
8 | /**
9 | * author:Charies Gavin
10 | * date:2020/8/6, 22:50
11 | * https://github.com/guobinhit
12 | * description:观察者模式
13 | */
14 | public class ObserverTest {
15 | public static void main(String[] args) {
16 | ObserverTest.testObserverMime();
17 | System.out.println(" --- 以上是自己实现 & 以下是内置实现 --- ");
18 | ObserverTest.testObserverApi();
19 | }
20 |
21 | /**
22 | * 测试自己实现的观察者模式
23 | */
24 | private static void testObserverMime() {
25 | // 创建 WeatherData 对象,用于传递给 CurrentConditionsDisplay 的构造器
26 | WeatherData weatherData = new WeatherData();
27 | CurrentConditionsDisplay conditionsDisplay = new CurrentConditionsDisplay(weatherData);
28 | // 展示初始化布告板
29 | conditionsDisplay.display();
30 | // 更新布告板
31 | conditionsDisplay.update(88, 78, 32.4f);
32 | // 修改布告板数据
33 | weatherData.setMeasurements(80, 65, 30.4f);
34 |
35 | System.out.println(" --- --- --- ");
36 |
37 | CurrentConditionsDisplay conditionsDisplay2 = new CurrentConditionsDisplay(weatherData);
38 | // 展示初始化布告板
39 | conditionsDisplay2.display();
40 | // 更新布告板
41 | conditionsDisplay2.update(92, 68, 35.4f);
42 | // 修改布告板数据
43 | weatherData.setMeasurements(110, 119, 12.0f);
44 | }
45 |
46 | /**
47 | * 测试通过 Java 内置 API 实现的观察者模式
48 | */
49 | private static void testObserverApi() {
50 | WeatherDataApi weatherData = new WeatherDataApi();
51 | CurrentConditionsDisplayApi conditionsDisplay = new CurrentConditionsDisplayApi(weatherData);
52 | // 展示初始化布告板
53 | conditionsDisplay.display();
54 | // 更新布告板,仍然皆为初始化值
55 | conditionsDisplay.update(weatherData, null);
56 | // 修改布告板数据
57 | weatherData.setMeasurements(80, 65, 30.4f);
58 |
59 | System.out.println(" --- --- --- ");
60 |
61 | CurrentConditionsDisplayApi conditionsDisplay2 = new CurrentConditionsDisplayApi(weatherData);
62 | // 展示初始化布告板
63 | conditionsDisplay2.display();
64 | // 更新布告板,仍然皆为初始化值
65 | conditionsDisplay2.update(weatherData, null);
66 | // 修改布告板数据
67 | weatherData.setMeasurements(110, 119, 12.0f);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > **Notices**:If you want to read chinese `README`, please onclick [THERE](https://github.com/guobinhit/design-pattern/blob/master/README_CH.md).
2 |
3 | # Design Pattern
4 |
5 | Detail design pattern and give many demos of Java.
6 |
7 | 
8 |
9 |
10 | ## Index
11 |
12 | - [Singleton](#singleton)
13 | - [Strategy](#strategy)
14 | - [Decorator](#decorator)
15 | - [Observer](#observer)
16 | - [Adapter](#adapter)
17 | - [Facade](#facade)
18 | - [Builder](#builder)
19 | - [Iterator](#iterator)
20 |
21 |
22 | ## Singleton
23 |
24 | The singleton pattern is a software design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects. The term comes from the mathematical concept of a singleton. An implementation of the singleton pattern must:
25 |
26 | - ensure that only one instance of the singleton class ever exists; and
27 | - provide global access to that instance.
28 |
29 | > The Singleton design pattern solves problems like:
30 |
31 | - How can it be ensured that a class has only one instance?
32 | - How can the sole instance of a class be accessed easily?
33 | - How can a class control its instantiation?
34 | - How can the number of instances of a class be restricted?
35 |
36 | Typically, this is done by:
37 |
38 | - declaring all constructors of the class to be private; and
39 | - providing a static method that returns a reference to the instance.
40 |
41 | The instance is usually stored as a private static variable; the instance is created when the variable is initialized, at some point before the static method is first called.
42 |
43 |
44 | ## Strategy
45 |
46 | The strategy pattern (also known as the policy pattern) is a behavioural software design pattern that enables selecting an algorithm at runtime. The strategy pattern
47 |
48 | - defines a family of algorithms,
49 | - encapsulates each algorithm, and
50 | - makes the algorithms interchangeable within that family.
51 |
52 | For instance, a class that performs validation on incoming data may use the Strategy pattern to select a validation algorithm depending on the type of data, the source of the data, user choice, or other discriminating factors. These factors are not known until run-time and may require radically different validation to be performed. The validation algorithms (strategies), encapsulated separately from the validating object, may be used by other validating objects in different areas of the system (or even different systems) without code duplication.
53 |
54 | > The Strategy design pattern solves problems like:
55 |
56 | - How can a class use different algorithms?
57 | - How can a class be configured with an algorithm?
58 | - How can an algorithm be selected and exchanged at run-time?
59 |
60 |
61 | ## Decorator
62 |
63 | The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern.
64 |
65 | > What problems can the Decorator design pattern solve?
66 |
67 | - Responsibilities should be added to (and removed from) an object dynamically at run-time.
68 | - A flexible alternative to subclassing for extending functionality should be provided.
69 |
70 |
71 | ## Observer
72 |
73 | The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
74 |
75 | > The Observer design pattern solves problems like:
76 |
77 | - How can a one-to-many dependency between objects be defined without making the objects tightly coupled?
78 | - How can one be ensured that when one object changes state an open-ended number of dependent objects are updated (synchronized) automatically?
79 | - How can an object notify an open-ended number of other objects?
80 |
81 |
82 | ## Adapter
83 |
84 | The adapter pattern is a software design pattern (also known as Wrapper, an alternative naming shared with the Decorator pattern) that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code. An example is an adapter that converts the interface of a Document Object Model of an XML document into a tree structure that can be displayed.
85 |
86 | > The Adapter design pattern solves problems like:
87 |
88 | - How can a class be reused that does not have an interface that a client requires?
89 | - How can classes that have incompatible interfaces work together?
90 | - How can an alternative interface be provided for a class?
91 |
92 | Often an (already existing) class can't be reused only because its interface doesn't conform to the interface clients require.
93 |
94 | > The Adapter design pattern describes how to solve such problems:
95 |
96 | - Define a separate `Adapter` class that converts the (incompatible) interface of a class (`Adaptee`) into another interface (`Target`) clients require.
97 | - Work through an `Adapter` to work with (reuse) classes that do not have the required interface.
98 |
99 | The key idea in this pattern is to work through a separate Adapter that adapts the interface of an (already existing) class without changing it. Clients don't know whether they work with a `Target` class directly or through an `Adapter` with a class that has not the `Target` interface.
100 |
101 |
102 | ## Facade
103 |
104 | The facade pattern (also spelled façade) is a software design pattern commonly used with object-oriented programming. The name is an analogy to an architectural façade. A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can
105 |
106 | - make a software library easier to use, understand, and test, since the facade has convenient methods for common tasks,
107 | - make the library more readable, for the same reason,
108 | - reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system,
109 | - wrap a poorly designed collection of APIs with a single well-designed API.
110 |
111 | The Facade design pattern is often used when a system is very complex or difficult to understand because the system has a large number of interdependent classes or its source code is unavailable. This pattern hides the complexities of the larger system and provides a simpler interface to the client. It typically involves a single wrapper class that contains a set of members required by client. These members access the system on behalf of the facade client and hide the implementation details.
112 |
113 | > What problems can the Facade design pattern solve?
114 |
115 | - To make a complex subsystem easier to use, a simple interface should be provided for a set of interfaces in the subsystem.
116 | The dependencies on a subsystem should be minimized.
117 | - Clients that access a complex subsystem directly refer to (depend on) many different objects having different interfaces (tight coupling), which makes the clients hard to implement, change, test, and reuse.
118 |
119 | > What solution does the Facade design pattern describe?
120 |
121 | Define a Facade object that
122 |
123 | - implements a simple interface in terms of (by delegating to) the interfaces in the subsystem and
124 | - may perform additional functionality before/after forwarding a request.
125 |
126 | This enables to work through a Facade object to minimize the dependencies on a subsystem.
127 |
128 |
129 | ## Builder
130 |
131 | The builder pattern is an object creation software design pattern. Unlike the abstract factory pattern and the factory method pattern whose intention is to enable polymorphism, the intention of the builder pattern is to find a solution to the telescoping constructor anti-pattern that occurs when the increase of object constructor parameter combination leads to an exponential list of constructors. Instead of using numerous constructors, the builder pattern uses another object, a builder, that receives each initialization parameter step by step and then returns the resulting constructed object at once.
132 |
133 | > The Builder design pattern solves problems like:
134 |
135 | - How can a class (the same construction process) create different representations of a complex object?
136 | - How can a class that includes creating a complex object be simplified?
137 |
138 | Creating and assembling the parts of a complex object directly within a class is inflexible. It commits the class to creating a particular representation of the complex object and makes it impossible to change the representation later independently from (without having to change) the class.
139 |
140 | > The Builder design pattern describes how to solve such problems:
141 |
142 | - Encapsulate creating and assembling the parts of a complex object in a separate `Builder` object.
143 | - A class delegates object creation to a `Builder` object instead of creating the objects directly.
144 |
145 | A class (the same construction process) can delegate to different `Builder` objects to create different representations of a complex object.
146 |
147 |
148 | ## Iterator
149 |
150 | The iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container's elements. The iterator pattern decouples algorithms from containers; in some cases, algorithms are necessarily container-specific and thus cannot be decoupled.
151 |
152 | > What problems can the Iterator design pattern solve?
153 |
154 | - The elements of an aggregate object should be accessed and traversed without exposing its representation (data structures).
155 | - New traversal operations should be defined for an aggregate object without changing its interface.
156 |
157 | Defining access and traversal operations in the aggregate interface is inflexible because it commits the aggregate to particular access and traversal operations and makes it impossible to add new operations later without having to change the aggregate interface.
158 |
159 | > What solution does the Iterator design pattern describe?
160 |
161 | - Define a separate (iterator) object that encapsulates accessing and traversing an aggregate object.
162 | - Clients use an iterator to access and traverse an aggregate without knowing its representation (data structures).
163 |
164 | Different iterators can be used to access and traverse an aggregate in different ways.
165 |
166 |
167 | ----------
168 |
169 | **Reference**: The content of above comes from [Wikipedia](https://en.wikipedia.org/wiki/Design_pattern).
170 |
--------------------------------------------------------------------------------