├── 001_SimpleFactory.md
├── 002_StrategyPattern.md
├── 003_SRP.md
├── 004_OCP.md
├── 005_DIP.md
├── 005_DRY.md
├── 005_ISP.md
├── 005_LSP.md
├── 006_DecoratorPattern.md
├── 007_ProxyPattern.md
├── 008_FactoryMethodPattern.md
├── 009_PrototypePattern.md
├── 010_TemplateMethodPattern.md
├── 012_FacadePattern.md
├── 013_BuilderPattern.md
├── 014_ObserverPattern.md
├── 015_AbstractPattern.md
├── 016_StatePattern.md
├── 017_AdapterPattern.md
├── 018_MementoPattern.md
├── 019_CompositePattern.md
├── 020_IteratorPattern.md
├── 021_SingletonPattern.md
├── 022_BrigePattern.md
├── 023_CommandPattern.md
├── 024_ChainOfResponsibility.md
├── 025_MediatorPattern.md
├── 026_FlyweightPattern.md
├── 027_InterpreterPattern.md
├── 028_VisitorPattern.md
├── 029_Summary.md
├── README.md
├── code
├── geekbang
│ └── u020
│ │ └── Test.java
├── incomplete
│ └── ideas
│ │ ├── Client.java
│ │ ├── ILog.java
│ │ └── TestBufferdInputStream.java
├── u001
│ ├── AbstractOperation.java
│ ├── Operation.java
│ ├── OperationClient.java
│ └── OperationFactory.java
├── u002
│ ├── v1
│ │ ├── Casher.java
│ │ └── Client.java
│ ├── v2
│ │ ├── Casher.java
│ │ └── Client.java
│ ├── v3
│ │ ├── CashSuper.java
│ │ └── Client.java
│ └── v4
│ │ ├── CashContext.java
│ │ ├── CashSuper.java
│ │ └── Client.java
├── u004
│ └── MessageQueue.java
├── u005
│ └── dip
│ │ ├── Person.java
│ │ └── Phone.java
├── u006
│ ├── Client.java
│ └── ICar.java
├── u007
│ ├── Client.java
│ └── ISendPresents.java
├── u008
│ ├── factorymethod
│ │ ├── Client.java
│ │ ├── IOperationFactory.java
│ │ └── Operation.java
│ └── simplefactory
│ │ ├── Client.java
│ │ └── Operate.java
├── u009
│ ├── Client.java
│ ├── IResume.java
│ ├── Resume_deep.java
│ └── Resume_shallow.java
├── u010
│ ├── Client.java
│ └── CrossCompiler.java
├── u012
│ ├── Client.java
│ ├── Fund.java
│ └── IInvestment.java
├── u013
│ ├── Client.java
│ ├── PersonBuilder.java
│ └── PersonDirector.java
├── u014
│ ├── v1
│ │ ├── Client.java
│ │ ├── Secretary.java
│ │ └── StockObserver.java
│ ├── v2
│ │ ├── Client.java
│ │ ├── NBAObserver.java
│ │ ├── Observer.java
│ │ ├── Secretary.java
│ │ └── StockObserver.java
│ ├── v3
│ │ ├── Client.java
│ │ ├── NBAObserver.java
│ │ ├── Observer.java
│ │ ├── Secretary.java
│ │ ├── StockObserver.java
│ │ └── Subject.java
│ └── v4
│ │ ├── Client.java
│ │ ├── ConcreteObserver.java
│ │ ├── ConcreteSubject.java
│ │ ├── Observer.java
│ │ └── Subject.java
├── u015
│ ├── v1
│ │ ├── Client.java
│ │ └── User.java
│ ├── v2
│ │ ├── Client.java
│ │ ├── IFactory.java
│ │ └── IUser.java
│ └── v3
│ │ ├── Client.java
│ │ ├── Department.java
│ │ ├── IDepartment.java
│ │ ├── IFactory.java
│ │ └── IUser.java
├── u016
│ ├── v1
│ │ ├── Client.java
│ │ └── WriteProgram.java
│ ├── v2
│ │ ├── ConcreteStateA.java
│ │ ├── ConcreteStateB.java
│ │ ├── Context.java
│ │ └── State.java
│ └── v3
│ │ ├── Client.java
│ │ ├── ForenoonState.java
│ │ ├── NoonState.java
│ │ ├── State.java
│ │ └── Work.java
├── u017
│ ├── v1
│ │ ├── Adaptee.java
│ │ ├── Adapter.java
│ │ ├── Client.java
│ │ └── Target.java
│ └── v2
│ │ └── TestInputStream.java
├── u018
│ ├── v1
│ │ ├── Client.java
│ │ └── GameRole.java
│ └── v2
│ │ ├── Caretaker.java
│ │ ├── Client.java
│ │ ├── Memento.java
│ │ └── Originator.java
├── u019
│ └── v1
│ │ ├── Client.java
│ │ ├── Component.java
│ │ ├── Composite.java
│ │ └── Leaf.java
├── u020
│ └── TestIterator.java
├── u021
│ ├── bestpractice
│ │ └── DemoSingleton.java
│ ├── bill
│ │ ├── BillPughSingleton.java
│ │ └── BillPughSingletonTest.java
│ ├── eager
│ │ ├── Client.java
│ │ └── EagerSingleton.java
│ ├── lazy
│ │ ├── LazySingleton.java
│ │ ├── LazySingletonClient.java
│ │ ├── LazySingletonMultiThreadClient.java
│ │ ├── LazySingletonV2.java
│ │ └── LazySingletonV2Client.java
│ ├── seri
│ │ ├── Client.java
│ │ └── DemoSingleton.java
│ ├── st
│ │ ├── StaticBlockSingleton.java
│ │ └── StaticBlockSingletonTest.java
│ └── v1
│ │ ├── FooV1.java
│ │ ├── FooV2.java
│ │ └── TestPerformance.java
├── u022
│ ├── v1
│ │ └── Shape.java
│ ├── v2
│ │ ├── Client.java
│ │ ├── Color.java
│ │ └── Shape.java
│ └── v3
│ │ ├── Client.java
│ │ ├── FileDownloaderAbstraction.java
│ │ ├── FileDownloaderAbstractionImpl.java
│ │ ├── FileDownloaderImplementor.java
│ │ ├── LinuxFileDownloaderImplProvider.java
│ │ └── WindowsFileDownloaderImplProvider.java
├── u023
│ ├── v1
│ │ ├── Client.java
│ │ ├── Command.java
│ │ ├── ConcreteCommand.java
│ │ ├── Invoker.java
│ │ └── Receiver.java
│ └── v2
│ │ ├── Client.java
│ │ ├── ICommand.java
│ │ ├── Light.java
│ │ ├── RemoteController.java
│ │ ├── TurnOffLightCommand.java
│ │ └── TurnOnLightCommand.java
├── u024
│ ├── v1
│ │ ├── APPLY_TYPE.java
│ │ ├── Apply.java
│ │ ├── Client.java
│ │ ├── LEVEL.java
│ │ └── Manager.java
│ └── v2
│ │ ├── Client.java
│ │ ├── CommonManager.java
│ │ ├── GeneralManager.java
│ │ └── Manager.java
├── u025
│ ├── ChatRoom.java
│ ├── ChatUser.java
│ ├── Client.java
│ ├── IChatRoom.java
│ └── User.java
├── u026
│ └── v1
│ │ └── WebSite.java
├── u027
│ ├── Context.java
│ ├── Expression.java
│ ├── From.java
│ ├── InterpreterDemo.java
│ ├── Row.java
│ ├── Select.java
│ └── Where.java
├── u028
│ ├── v1
│ │ └── Person.java
│ ├── v2
│ │ ├── Client.java
│ │ ├── Man.java
│ │ ├── Person.java
│ │ └── Woman.java
│ ├── v3
│ │ ├── Action.java
│ │ ├── Client.java
│ │ ├── Man.java
│ │ ├── ObjectStructure.java
│ │ ├── Person.java
│ │ ├── Success.java
│ │ └── Woman.java
│ └── visitor
│ │ ├── Client.java
│ │ ├── ConcreteElementA.java
│ │ ├── ConcreteElementB.java
│ │ ├── ConcreteVisitorA.java
│ │ ├── Element.java
│ │ ├── ObjectStructure.java
│ │ └── Visitor.java
└── util
│ └── _Stopwatch.java
├── filename.ser
├── incompleteideas
└── 013_ReplayAttack.md
├── pdf
├── DDD 101 — The 5-Minute Tour - The Coding Matrix - Medium.pdf
└── The_Pragmatic_Programmer_YourJourneytoMastery_20thAnniversaryEdition(2019).pdf
└── template.md
/001_SimpleFactory.md:
--------------------------------------------------------------------------------
1 |
2 | # 简单工厂模式(Simple Factory Method)
3 |
4 | ## 定义
5 |
6 | 简单工厂模式根据提供的参数返回某个子类实例。返回的通常是父类的类型,并且有暴露的方法。
7 |
8 | Simple Factory Pattern, which software design pattern which
9 | returns an instance of one of several possible classes depending
10 | on the type of data provided. It is quite common to
11 | return a common parent class and common methods,
12 | but each may perform a task differently or optimise for different data or behaviours.
13 |
14 | ## 类图
15 |
16 | 
17 |
18 | ## 用例
19 |
20 | 比较简单。《大话设计模式》中讲的是计算器的例子。
21 |
22 | [code example](./code/u001)
23 |
24 | ## 实际应用
25 |
26 | - JDK类库中广泛使用了简单工厂模式,如工具类java.text.DateFormat,它用于格式化一个本地日期或者时间。
27 |
28 | ```java
29 | public final static DateFormat getDateInstance();
30 | public final static DateFormat getDateInstance(int style);
31 | public final static DateFormat getDateInstance(int style,Locale locale);
32 | ```
33 |
34 | - Java加密技术
35 |
36 | 获取不同加密算法的密钥生成器:
37 |
38 | `KeyGenerator keyGen=KeyGenerator.getInstance("DESede");`
39 |
40 | - 创建密码器:
41 |
42 | `Cipher cp=Cipher.getInstance("DESede");`
43 |
44 | ## 注意
45 |
46 | 简单工厂模式优点在于,当你需要什么,仅仅需要输入一个参数。就可以获得所需的对象,无需知道创建对象的细节。
47 |
48 | 将对象创建和使用分离。
49 |
50 | ## 参考
51 |
52 | [ref-1](https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/simple_factory.html)
--------------------------------------------------------------------------------
/002_StrategyPattern.md:
--------------------------------------------------------------------------------
1 |
2 | # 策略模式(Strategy Pattern)
3 |
4 | ## 定义
5 |
6 | 定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不影响到使用算法的客户。
7 |
8 | ## 类图
9 |
10 | 
11 |
12 | ## 用例
13 |
14 | 《大话设计模式》中举了商场促销的例子。
15 |
16 | 具体见代码 [code example](./code/u002)
17 |
18 | ## 实际应用
19 |
20 | Java `Collections.sort(list, comparator)` method where client actually passes suitable
21 | comparator based on the requirement in runtime to the method and the method is generic to accept any comparator type.
22 | Based on the comparator being passed, same collection can be sorted differently.
23 |
24 | ## 参考
25 |
26 | [howtodo-strategy-pattern](https://howtodoinjava.com/design-patterns/behavioral/strategy-design-pattern/)
--------------------------------------------------------------------------------
/003_SRP.md:
--------------------------------------------------------------------------------
1 |
2 | # 单一职责原则
3 |
4 | ## 定义
5 |
6 | 单一职责原则的英文是 Single Responsibility Principle,缩写为 SRP。这个原则的英文描述是这样的:A class or
7 | module should have a single responsibility。如果我们把它翻译成中文,那就是:一个类或者模块只负责完成一个职责(或者功能)。
8 |
9 | ## 实际应用
10 |
11 | > 设计你的系统,使得每个模块负责(响应)只满足一个业务功能需求。
12 |
13 | > Design your systems such that each module is responsible (responds to) the needs of just that one business function. (Robert C. Martin)
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 | [uncle bob](https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html)
42 |
43 | [geekbang](https://time.geekbang.org/column/article/171771)
--------------------------------------------------------------------------------
/004_OCP.md:
--------------------------------------------------------------------------------
1 |
2 | # 开闭原则 OCP
3 |
4 | ## 定义
5 |
6 | open close principle
7 |
8 | 定义:软件实体(类、模块、函数等)应该可以扩展,但是不能修改。
9 |
10 | 这个定义包含两个特征:
11 |
12 | - 对于扩展是开放的(open for extension)
13 |
14 | - 对于更改是封闭的(close for modification)
15 |
16 | ## 实际应用
17 |
18 |
19 | 开发人员应该仅对程序中出现频繁变化的那部分做出抽象。
20 |
21 | 开闭原则:基于接口或抽象实现“封闭”,基于实现接口或继承实现“开放”(拓展)。
22 |
23 | 争哥的第一个例子,AlertHandler为抽象,一般是固定不变的。
24 | 子类TpsAlertHandler为继承;
25 |
26 | 再看第二个例子,MessageQueue,MessageFormatter为接口,具体实现为KafkaMessageQueue和JsonMessageFormatter等。
27 |
28 | ```java
29 | public interface MessageQueue {
30 |
31 | void put();
32 | }
33 |
34 | interface MessageFormatter {
35 |
36 | void format();
37 | }
38 |
39 | class KafkaMessageQueue implements MessageQueue {
40 |
41 | @Override
42 | public void put() {
43 |
44 | }
45 | }
46 |
47 | class RocketMessageQueue implements MessageQueue {
48 |
49 | @Override
50 | public void put() {
51 |
52 | }
53 | }
54 |
55 | class JsonMessageFormatter implements MessageFormatter {
56 |
57 | @Override
58 | public void format() {
59 |
60 | }
61 | }
62 |
63 | class Demo {
64 |
65 | MessageQueue queue;
66 |
67 | Demo(MessageQueue queue) {
68 | this.queue = queue;
69 | }
70 |
71 | void setNotification(MessageFormatter formatter) {
72 | formatter.format();
73 | }
74 |
75 | public static void main(String[] args) {
76 |
77 | }
78 | }
79 | ```
80 |
81 | 以后替换或者增加其他的AlertHandler和message queue很容易。
82 |
83 | 两个例子中的抽象类和接口是固定的(封闭),继承或实现是可扩展的。通过“抽象-具体”体现了开闭原则,增加了软件的可维护性。
84 |
85 | 开闭原则具体应用,需要慢慢积累经验。争哥也说了,首先需要有对业务深刻的理解。其次就是学习一些设计原则和模式了。
86 |
87 | ## 补充
88 | 1、Bertrand Meyer 1988 年提出open-closed principle。
89 | 2、再推荐一篇经典文章 Robert C. Martin 2006年写的The Open-Closed Principle。不方便下载的话,我放到github上了:https://github.com/gdhucoder/Algorithms4/tree/master/designpattern/pdf
90 |
--------------------------------------------------------------------------------
/005_DIP.md:
--------------------------------------------------------------------------------
1 |
2 | # 依赖倒转原则
3 |
4 | ## 定义
5 |
6 | 抽象不应该依赖细节,细节应该依赖于抽象。
7 |
8 | 高层模块不应该依赖于低层模块,两个都应该依赖于抽象。
9 |
10 | 说白了就是针对接口编程,不要对实现编程。
11 |
12 | ## 类图
13 |
14 | 
15 |
16 | ## 用例
17 |
18 | 具体见代码 [code example](./code/u005)
19 |
20 | ## 注意
21 |
22 | ### 什么是控制反转 Inversion Of Control
23 |
24 | 把程序控制权交给第三方。
25 |
26 | ### 什么是依赖注入 Dependency Injection
27 |
28 | 不通过 new() 的方式在类内部创建依赖类对象,
29 | 而是将依赖的类对象在外部创建好之后,通过构造函数、函数参数等方式传递(或注入)给类使用。
30 |
31 | ### 依赖注入框架 和 控制反转容器
32 |
33 | 例如 Spring 框架
34 |
35 | ### 小结
36 |
37 | - 控制反转是一种编程思想,把控制权交给第三方。依赖注入是实现控制反转最典型的方法。
38 |
39 | - 依赖注入(对象)的方式要采用“基于接口而非实现编程”的原则,说白了就是依赖倒转。
40 |
41 | - 底层的实现要符合里氏替换原则。子类的可替换性,使得父类模块或依赖于抽象的高层模块无需修改,实现程序的可扩展性。
42 |
43 | ## 参考
44 |
45 | 《大话设计模式》
46 |
47 | https://time.geekbang.org/column/article/177444
--------------------------------------------------------------------------------
/005_DRY.md:
--------------------------------------------------------------------------------
1 |
2 | # 关于DRY原则
3 |
4 | Don't repeat yourself.
5 |
6 | ## 违反DRY的情况
7 |
8 | - 代码重复
9 | - 注释或者文档违反DRY
10 | - 数据对象违反DRY
11 |
12 | 例如一个方法。写了好多的注释解释代码的执行逻辑,后续修改的这个方法的时候可能忘记修改注释,
13 | 造成对代码理解的困难。实际应用应该使用KISS原则,将方法写的见名知意,尽量容易阅读。注释不必过多。
14 |
15 | 例如类:
16 |
17 | ```java
18 | class User{
19 | String id;
20 | Date registerDate;
21 | int age;
22 | int registeredDays;
23 | }
24 | ```
25 |
26 | 其中 age可以由身份证号码算出来,而且每年都会递增。
27 | 注册会员多少天了,也可以算出来。所以是不是可以考虑数据字段只存储id和注册时间。其余两个字段可以算出来。
28 |
29 | ```java
30 | class User{
31 | String id;
32 | Date registerDate;
33 | int age;
34 | int registeredDays;
35 | User(String id, Date registerDate){
36 | this.id = id;
37 | this.registerDate = registerDate;
38 | // age = calcAge();
39 | // registerDate = calcRegisteredDays;
40 | }
41 | }
42 | ```
43 |
44 | ## 注意:
45 |
46 | DRY不是只代码重复,而是“知识”的重复,意思是指业务逻辑。例如由于沟通不足,两个程序员用两种不同的方法实现同样功能的校验。
47 | DRY is about the duplication of knowledge, of intent. It’s about expressing the same thing in two different places, possibly in two totally different ways.
48 |
49 | 当代码的某些地方必须更改时,你是否发现自己在多个位置以多种不同格式进行了更改? 你是否需要更改代码和文档,或更改包含其的数据库架构和结构,或者…? 如果是这样,则您的代码不是DRY。
50 |
51 | when some single facet of the code has to change, do you find yourself making that change in multiple places, and in multiple different formats? Do you have to change code and documentation, or a database schema and a structure that holds it, or…? If so, your code isn’t DRY.
52 |
53 | ## 参考
54 | The Pragmatic Programmer: your journey to mastery, 20th Anniversary Edition (2nd Edition)
55 |
56 | TODO: 2019年9月份出的书,目前中文版还没有。找到英文版后放上来。
--------------------------------------------------------------------------------
/005_ISP.md:
--------------------------------------------------------------------------------
1 |
2 | # 接口隔离原则 ISP
3 |
4 | ## 什么是接口隔离
5 |
6 | Clients should not be forced to depend upon **interfaces** that they do not use.
7 |
8 |
9 | 理解接口隔离原则的关键,就是理解其中的“接口”二字。
10 | 在这条原则中,我们可以把“接口”理解为下面三种东西:
11 |
12 | - 一组 API 接口集合
13 | - 单个 API 接口或函数
14 | - OOP 中的接口概念
15 |
16 | 主要从使用者的角度看,有没有用到没有用的功能或者接口,如果有,就要要没有用的接口给隔离起来。
17 |
18 | ## 如何使用接口隔离原则
19 |
20 | 接口隔离原则提供了一种判断接口的职责是否单一的标准:
21 | 通过调用者如何使用接口来间接地判定。如果调用者只使用部分接口或接口的部分功能,那接口的设计就不够职责单一。
--------------------------------------------------------------------------------
/005_LSP.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdhucoder/DesignPattern/0611d81a924ea6ca7ad904c957133e64c1cc6eec/005_LSP.md
--------------------------------------------------------------------------------
/006_DecoratorPattern.md:
--------------------------------------------------------------------------------
1 | 装饰模式(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
2 |
3 | ## 场景
4 |
5 | 假设有个4S店,卖车。卖的🚗有宝马BMW和特斯拉的ModelX。
6 | 车分基本款和在此基础上的定制款。客户可以定制自己的爱车🚗,例如定制真皮座椅💺,和定制音响设备。
7 |
8 | 赵四买了个ModelX,改装了音响系统。
9 |
10 | 刘能看赵四买了ModelX,他想我也得整一个呀!
11 | 他买了的BMW,要装真皮座椅,和更牛的音响系统,让全村人都知道他刘能🐂🍺。
12 |
13 | 以上就是装饰模式的意思。
14 |
15 | ## 装饰模式
16 |
17 | 
18 |
19 | ## 代码
20 |
21 | [code example](./code/u006)
22 |
23 | Client
24 |
25 | ```java
26 | public class Client {
27 |
28 | public static void main(String[] args) {
29 | ICar bmw = new BMW();
30 | bmw.makeOrder();
31 | // A new order has been made.Car: u006.BMW
32 |
33 | // decorate
34 | ICar bmw_leather = new LeatherSeats(bmw);
35 | ICar bmw_addAudio = new AudioDecorator(bmw_leather);
36 | bmw_addAudio.makeOrder();
37 | // A new order has been made.Car: u006.BMW
38 | // Leather seats have been added.
39 | // Audio devices are awesome.
40 |
41 | ICar modelX = new ModelX();
42 | modelX.makeOrder();
43 | // A new order has been made. Car: u006.ModelX
44 |
45 | // decorate
46 | ICar modelX_audio = new AudioDecorator(modelX);
47 | modelX_audio.makeOrder();
48 | // A new order has been made. Car: u006.ModelX
49 | // Audio devices are awesome.
50 |
51 | }
52 | }
53 | ```
54 |
55 |
56 |
57 | ```java
58 | package u006;
59 |
60 | /**
61 | * Created by HuGuodong on 11/20/19.
62 | */
63 | public interface ICar {
64 |
65 | void makeOrder();
66 | }
67 |
68 | class ModelX implements ICar {
69 |
70 | @Override
71 | public void makeOrder() {
72 | System.out.println("A new order has been made. Car: " + this.getClass().getName());
73 | }
74 | }
75 |
76 | class BMW implements ICar {
77 |
78 | @Override
79 | public void makeOrder() {
80 | System.out.println("A new order has been made.Car: " + this.getClass().getName());
81 | }
82 | }
83 |
84 | abstract class CarDecorator implements ICar{
85 |
86 | protected ICar car;
87 |
88 | public CarDecorator(ICar car) {
89 | this.car = car;
90 | }
91 |
92 | public abstract void makeOrder();
93 |
94 | }
95 |
96 | class AudioDecorator extends CarDecorator {
97 |
98 | public AudioDecorator(ICar car) {
99 | super(car);
100 | }
101 |
102 | @Override
103 | public void makeOrder() {
104 | car.makeOrder();
105 | showAudioDevices();
106 | }
107 |
108 | public void showAudioDevices(){
109 | System.out.println("Audio devices are awesome.");
110 | }
111 |
112 | }
113 |
114 | class LeatherSeats extends CarDecorator {
115 |
116 | public LeatherSeats(ICar car) {
117 | super(car);
118 | }
119 |
120 | @Override
121 | public void makeOrder() {
122 | car.makeOrder();
123 | addLeatherSeats();
124 | }
125 |
126 | private void addLeatherSeats(){
127 | System.out.println("Leather seats have been added.");
128 | }
129 | }
130 | ```
131 |
132 | 2019-11-19
--------------------------------------------------------------------------------
/007_ProxyPattern.md:
--------------------------------------------------------------------------------
1 | # Proxy Pattern
2 |
3 | ## 代理模式:
4 |
5 | 定义:为其他对象提供一种代理以控制对这个对象的访问。
6 |
7 | ## 场景:
8 |
9 | 小明喜欢小红,却不敢向小红献殷勤。小明找他的好朋友小刚(代理)帮忙,给小红送洋娃娃、送花、送巧克力。
10 |
11 | 故事的结局是:来来去去日久生情,代送礼物的小刚(代理)和小红好上了,小明还是单身狗🐶。
12 |
13 | 
14 |
15 | ## 代理模式(Proxy)和装饰器模式(Decorator)模式有啥区别呢?
16 |
17 | 代理模型是控制Client对真实对象的访问,而装饰器模式是给原有的类增加功能。
18 |
19 | ## 代码
20 |
21 | [code example](./code/u007)
22 |
23 | ```java
24 | public class Client {
25 |
26 | public static void main(String[] args) {
27 | Proxy xiao_gang = new Proxy(new Pursuit("Lovely Girl"));
28 | xiao_gang.sendFlower();
29 | xiao_gang.sendChocolate();
30 | xiao_gang.sendDoll();
31 | // Lovely Girl, here is your flower.
32 | // Lovely Girl, here is your chocolate.
33 | // Lovely Girl, here is your doll.
34 | }
35 | }
36 | ```
37 |
38 | ```java
39 | public interface ISendPresents {
40 |
41 | void sendFlower();
42 |
43 | void sendDoll();
44 |
45 | void sendChocolate();
46 | }
47 |
48 | class Pursuit implements ISendPresents {
49 |
50 | private String girlName;
51 |
52 | public Pursuit(String name) {
53 | this.girlName = name;
54 | }
55 |
56 | @Override
57 | public void sendFlower() {
58 | System.out.printf("%s, here is your flower.\n", girlName);
59 | }
60 |
61 | @Override
62 | public void sendDoll() {
63 | System.out.printf("%s, here is your doll.\n", girlName);
64 | }
65 |
66 | @Override
67 | public void sendChocolate() {
68 | System.out.printf("%s, here is your.\n", girlName);
69 | }
70 | }
71 |
72 | class Proxy implements ISendPresents {
73 |
74 | private Pursuit p;
75 |
76 | public Proxy(Pursuit p) {
77 | this.p = p;
78 | }
79 |
80 | @Override
81 | public void sendFlower() {
82 | p.sendFlower();
83 | }
84 |
85 | @Override
86 | public void sendDoll() {
87 | p.sendDoll();
88 | }
89 |
90 | @Override
91 | public void sendChocolate() {
92 | p.sendFlower();
93 | }
94 | }
95 | ```
96 |
97 | 2019-11-20
--------------------------------------------------------------------------------
/008_FactoryMethodPattern.md:
--------------------------------------------------------------------------------
1 | # 工厂方法模式(Factory Method)
2 |
3 |
4 |
5 | 今天写个计算器🧮吧!
6 |
7 | ## 使用简单工厂模式设计一个计算器
8 |
9 | 类图如下:
10 |
11 | 
12 |
13 | 简单工厂模式当需要添加新的操作类时,如除法,我们需要修改OperateFactory的判断逻辑(***缺点:此处违反了开放-封闭原则***)并且添加新的操作类DivOper。不需要修改客户端。
14 |
15 | 针对上面的简单工厂模式的不足,对工厂模式进一步抽象,提出工厂方法模式。
16 |
17 | ## 使用工厂方法模式设计该计算器
18 |
19 | 类图如下:
20 |
21 | 
22 |
23 | 如果使用工厂方法模式,能克服简单工厂模式的缺点(违反开放-封闭原则)。
24 |
25 | [code example](./code/u008)
26 |
27 | 工厂方法模式在添加新的操作类时,需要添加新的操作类DivOper和DivFactory。客户端需要修改一行代码:
28 | `IOperationFactory operationFactory = new AddFactory();`。
29 |
30 | 工厂模式就完全没有问题了吗?不是的,工厂方法模式的不足:
31 |
32 | - 添加新的操作类时,需要添加对应的产品工厂类,增加了代码量。
33 | - 不可避免的修改了客户端的代码。
34 |
35 | 如何避免修改客户端代码呢?这个问题先留着,稍后我们解决它!
36 |
37 | 2019-11-21
38 |
39 |
--------------------------------------------------------------------------------
/009_PrototypePattern.md:
--------------------------------------------------------------------------------
1 | ## 原型模式
2 |
3 | *Create objects based on a template of an existing object through cloning.* 使用克隆在已有对象的基础上创建对象。
4 |
5 | ## 类图
6 |
7 | 
8 |
9 | 注意事项:引用类型需要深拷贝。
10 |
11 | [code example](./code/u009)
12 |
13 | 2019-11-22
--------------------------------------------------------------------------------
/010_TemplateMethodPattern.md:
--------------------------------------------------------------------------------
1 | # 模板方法模式
2 |
3 | ## 定义
4 |
5 | Defines the skeleton of an algorithm in a method,
6 | deferring some steps to subclasses.
7 | Template Method lets subclasses redefine certain steps of
8 | an algorithm without changing the algorithms structure.
9 |
10 | 定义算法骨架,将一些步骤推迟到子类中。模版方法可以不改变算法结构,重新定义一个算法的某些特定步骤。
11 |
12 | 
13 |
14 | ## 注意的地方
15 |
16 | - 将模版方法标记为final
17 | - 子类相同的逻辑、代码方法,在抽象类中提供实现
18 | - 子类不同具体实现的方法,定义为abstract方法
19 |
20 | ## 例子
21 |
22 | 一个跨平台的编译器,详见代码。
23 |
24 | [code example](./code/u010)
25 |
26 | ## 应用
27 |
28 | Java InputStream中的read()方法
--------------------------------------------------------------------------------
/012_FacadePattern.md:
--------------------------------------------------------------------------------
1 | ## 外观模式(Facade Pattern)
2 |
3 | ## 定义
4 |
5 | 外观模式(Facade Pattern)
6 |
7 | *Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use.*
8 |
9 | 为子系统的一组接口提供一个同一的接口。外观模式定义一个高层接口,这个接口使得子系统更容易使用。
10 |
11 | ## 结构图
12 |
13 | 
14 |
15 | ## 用例
16 |
17 | [code example](./code/u012)
18 |
19 | 投资买基金的例子。我们都想理财,很多小白不懂股票,也不知道如何选择,导致赔了不少钱💰。买基金是个不错的选择,它是一组股票的组合。有专业的管理人进行操作。我们只需要找对应的基金管理公司买基金即可。
20 |
21 | 详细实现见代码。
22 |
23 | 上面的例子中基金Fund类作为外观(Facade),Client只需要调用Fund的buy和sell方法即可,不需要知道子系统(各种股票、实体投资、国债)。
24 |
25 | ## 何时使用外观模式
26 |
27 | - 设计初期,使得几个层隔离
28 | - 开发阶段:系统需要重构演化,外观模式可以提供简单的接口,减少彼此依赖
29 | - 遗留大型系统:新系统与Facade对象交互,Facade与旧系统交互。
30 |
31 | ## 参考资料
32 |
33 | - 大话设计模式
34 |
35 | - [Facade Pattern Ref-1](https://dzone.com/articles/design-patterns-uncovered-1)
36 |
37 | - [Facade Pattern Ref-2](https://www.tutorialspoint.com/design_pattern/facade_pattern.htm)
38 |
39 | - [Facade Pattern Ref-3](https://howtodoinjava.com/design-patterns/structural/facade-design-pattern/)
40 |
41 |
--------------------------------------------------------------------------------
/013_BuilderPattern.md:
--------------------------------------------------------------------------------
1 | ## 建造者模式(Builder Pattern)
2 |
3 | ## 定义
4 |
5 | The builder pattern is a design pattern that allows for the step-by-step creation of complex objects using the correct sequence of actions. The construction is controlled by a director object that only needs to know the type of object it is to create.
6 |
7 | 建造者模式使用一些列动作一步步创建复杂对象。指挥者控制对象的创建,只需要知道它要创建对象的类型即可。
8 |
9 | ## 类图
10 |
11 | 
12 |
13 | ## 用例
14 |
15 | 《大话设计模式》中举了一个画小人的例子。意思是说小人分胖子瘦子,但画的流程是一样的:脑袋、身子、胳膊和腿。所以可以使用Builder Pattern。
16 |
17 | 具体实现见代码。
18 |
19 | [code example](./code/u013)
20 |
21 | ## 实际应用
22 |
23 | 建造者模式实际应用中往往不这么用:
24 |
25 | ```java
26 | public class User
27 | {
28 | //All final attributes
29 | private final String firstName; // required
30 | private final String lastName; // required
31 | private final int age; // optional
32 | private final String phone; // optional
33 | private final String address; // optional
34 |
35 | private User(UserBuilder builder) {
36 | this.firstName = builder.firstName;
37 | this.lastName = builder.lastName;
38 | this.age = builder.age;
39 | this.phone = builder.phone;
40 | this.address = builder.address;
41 | }
42 |
43 | //All getter, and NO setter to provde immutability
44 | public String getFirstName() {
45 | return firstName;
46 | }
47 | public String getLastName() {
48 | return lastName;
49 | }
50 | public int getAge() {
51 | return age;
52 | }
53 | public String getPhone() {
54 | return phone;
55 | }
56 | public String getAddress() {
57 | return address;
58 | }
59 |
60 | @Override
61 | public String toString() {
62 | return "User: "+this.firstName+", "+this.lastName+", "+this.age+", "+this.phone+", "+this.address;
63 | }
64 |
65 | public static class UserBuilder
66 | {
67 | private final String firstName;
68 | private final String lastName;
69 | private int age;
70 | private String phone;
71 | private String address;
72 |
73 | public UserBuilder(String firstName, String lastName) {
74 | this.firstName = firstName;
75 | this.lastName = lastName;
76 | }
77 | public UserBuilder age(int age) {
78 | this.age = age;
79 | return this;
80 | }
81 | public UserBuilder phone(String phone) {
82 | this.phone = phone;
83 | return this;
84 | }
85 | public UserBuilder address(String address) {
86 | this.address = address;
87 | return this;
88 | }
89 | //Return the finally consrcuted User object
90 | public User build() {
91 | User user = new User(this);
92 | validateUserObject(user);
93 | return user;
94 | }
95 | private void validateUserObject(User user) {
96 | //Do some basic validations to check
97 | //if user object does not break any assumption of system
98 | }
99 | }
100 | }
101 | And below is the way, we will use the UserBuilder in our code:
102 |
103 | public static void main(String[] args) {
104 | User user1 = new User.UserBuilder("Lokesh", "Gupta")
105 | .age(30)
106 | .phone("1234567")
107 | .address("Fake address 1234")
108 | .build();
109 |
110 | System.out.println(user1);
111 |
112 | User user2 = new User.UserBuilder("Jack", "Reacher")
113 | .age(40)
114 | .phone("5655")
115 | //no address
116 | .build();
117 |
118 | System.out.println(user2);
119 |
120 | User user3 = new User.UserBuilder("Super", "Man")
121 | //No age
122 | //No phone
123 | //no address
124 | .build();
125 |
126 | System.out.println(user3);
127 | }
128 |
129 | Output:
130 |
131 | User: Lokesh, Gupta, 30, 1234567, Fake address 1234
132 | User: Jack, Reacher, 40, 5655, null
133 | User: Super, Man, 0, null, null
134 | ```
135 |
136 | 例如Java的线程不安全的StringBuilder.append 和 线程安全的StringBurffer.append,实现了java.lang.Appendable接口。 代码中有类似的结构:
137 |
138 | ```java
139 | @Override
140 | public StringBuilder append(boolean b) {
141 | super.append(b);
142 | return this;
143 | }
144 | ```
145 |
146 | ## 使用中注意的地方
147 |
148 | 建造者模式用于创建一些复杂对象,对象内部的构建过程顺序通常是稳定的,但内部的构建往往面临的变化。
149 |
150 | ## 好处
151 |
152 | 代码易读
153 |
154 | 构造方法参数比较少
155 |
156 | 可以创建不可变类
157 |
158 | ## 参考
159 |
160 | - 大话设计模式
161 | - [dzone-builder](https://dzone.com/articles/design-patterns-builder)
162 | - [howtodoinjava-builder](https://howtodoinjava.com/design-patterns/creational/builder-pattern-in-java/)
163 | - [turotialspoint-builder](https://www.tutorialspoint.com/design_pattern/builder_pattern.htm)
164 | - [wiki-fluent_interface](https://en.wikipedia.org/wiki/Fluent_interface)
--------------------------------------------------------------------------------
/014_ObserverPattern.md:
--------------------------------------------------------------------------------
1 |
2 | ## 观察者模式(发布-订阅模式)
3 |
4 | ## 定义
5 |
6 | Define a one-to-many dependency between objects so that when one object changes state,
7 | all its dependents are notified and updated automatically.
8 |
9 | 定义一种一对多的依赖关系,一个对象发生改变时,所有依赖于它的都会自动通知和更新。
10 |
11 | 类图:
12 |
13 | 
14 |
15 | [youtube-observer-pattern](https://www.youtube.com/watch?v=WRkw0l72BL4)
16 |
17 | ## 用例
18 |
19 | 前台通知办公室的小伙伴们老板要回来啦!
20 |
21 | [code example](./code/u014)
22 |
23 | ## 实际应用
24 |
25 | 当一个对象的状态改变需要通知其他对象的时候考虑使用观察者模式。让双方都依赖于抽象。
26 |
27 | ## 观察者模式的不足
28 |
29 | 可能没有办法让每个类都实现Observer接口。实际使用事件委托机制EventHandler。下篇文章讲EventHandler。
30 |
31 | 埋下一个坑,什么是事件委托机制? 2019-12-27
32 |
33 | 2019-11-26
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/015_AbstractPattern.md:
--------------------------------------------------------------------------------
1 | # 抽象工厂模式
2 |
3 | ## 定义
4 |
5 | Provides an interface for creating families of related or dependent objects without specifying their concrete classes.
6 |
7 | 提供一个创建一系列相关或者相互依赖对象的接口,而无需制定它们具体的类。
8 |
9 |
10 | ## 类图
11 |
12 | 
13 |
14 | ## 用例
15 |
16 | 《大话设计模式》中提到了一个换数据库的例子。具体实现见代码。
17 |
18 | [code example](./code/u015)
19 |
20 | ## 实际应用
21 |
22 | java 中 `DocumentBuilderFactor`
23 |
24 | >whenever you need another level of abstraction over a group of factories, you should consider using the abstract factory pattern.
25 |
26 | ## 注意
27 |
28 | 新增代码时需要增加的代码量变多。
29 |
30 | ## 参考
31 |
32 | [abstract-factory-pattern](https://howtodoinjava.com/design-patterns/creational/abstract-factory-pattern-in-java/)
33 |
34 | [dzone-abstract-factory-pattern](https://dzone.com/articles/design-patterns-abstract-factory)
--------------------------------------------------------------------------------
/016_StatePattern.md:
--------------------------------------------------------------------------------
1 |
2 | # 状态模式(State Pattern)
3 |
4 | ## 定义
5 |
6 | Allows an object to alter its behaviour when its internal state changes. The object will appear to change its class.
7 |
8 | 允许对象内部状态改变时,改变其行为。对象看起来像改变了其类。
9 |
10 |
11 | ## 类图
12 |
13 | 
14 |
15 | ## 用例
16 |
17 | 小菜加班的例子。详细见代码。
18 |
19 | 实际更好的例子是:网购。物品的状态依次是:下单,发货,物流公司收件,派件,签收。包裹的状态每个步骤都在改变。每个状态对应两个动作:处理包裹和改状态。
20 |
21 | [code example](./code/u016)
22 |
23 | ## 实际应用
24 |
25 | 消除庞大的分支语句。
26 |
27 | 有点像状态机。
28 |
29 | ## 注意
30 |
31 | 具体状态类中的状态变量可以设置为单例。
32 |
33 | ## 参考
34 |
35 | [how-to-do-state-pattern](https://howtodoinjava.com/design-patterns/behavioral/state-design-pattern/)
--------------------------------------------------------------------------------
/017_AdapterPattern.md:
--------------------------------------------------------------------------------
1 |
2 | ## 定义
3 |
4 | Convert the interface of a class into another interface clients expect.
5 | Adapter lets classes work together that couldn't otherwise because of
6 | incompatible interfaces.
7 |
8 | 把一个类的接口转换为客户需要的另外一个接口。使得因不兼容接口而不能一起工作的类一起工作。
9 |
10 | ## 类图
11 |
12 | 
13 |
14 | ## 用例
15 |
16 | 《大话设计模式》中讲了姚明刚到美国打球🏀需要翻译的例子。翻译就是适配器,姚明就是需要适配的对象。详细请看代码。
17 |
18 | [code example](./code/u017)
19 |
20 | ## 实际应用
21 |
22 | 生活中的例子:电源转换插头,就是适配器。
23 |
24 | ```java
25 | // System.in inputstream
26 | // BufferedReader <--> character
27 | // InputStream <--> bytes stream
28 | // InputStreamReader: Adapter (bytes stream to character)
29 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
30 | ```
31 |
32 |
33 |
34 | ## 注意
35 |
36 | Adapter Pattern只是一个妥协,应当提前在设计方面避免使用adapter pattern。
37 |
38 | ## 参考
39 |
40 | [howtodo-adapter-pattern](https://howtodoinjava.com/design-patterns/structural/adapter-design-pattern-in-java/)
--------------------------------------------------------------------------------
/018_MementoPattern.md:
--------------------------------------------------------------------------------
1 |
2 | # 备忘录模式(Memento Pattern)
3 |
4 | ## 定义
5 |
6 | 在不破坏封装性的前提下,捕获一个对象的内部状态,并在这个对象之外保存这个状态。
7 | 这样可以将对象恢复到原先保存的状态。
8 |
9 | The intent of memento pattern is to capture the internal state of an object
10 | without violating encapsulation and thus providing a mean for restoring the object
11 | into initial state when needed.
12 |
13 | ## 类图
14 |
15 | 
16 |
17 | ## 用例
18 |
19 | 大鸟🐦和小菜讨论了游戏保存进度的例子。具体见代码。
20 |
21 | [code example](./code/u018)
22 |
23 | ## 实际应用
24 |
25 | 备忘录模式用于需要"撤销","恢复"或者"回滚"的情形。
26 |
27 | - 我们的编辑器`Ctrl-Z`的功能
28 | - IDE关闭后的打开恢复状态
29 | - 等等
30 |
31 | ## 注意
32 |
33 | - 广义的讲:memento pattern,目的是保存状态、恢复状态,没有固定的实现规则。
34 | - 考虑对性能的影响
35 | - 多次回滚是否考虑用stack实现
36 | - `Ctrl-Y`的功能要如何实现呢?可以考虑再家一个stack
37 |
38 | ## 参考
39 |
40 | [howtodo-memento-pattern](https://howtodoinjava.com/design-patterns/behavioral/memento-design-pattern/)
--------------------------------------------------------------------------------
/019_CompositePattern.md:
--------------------------------------------------------------------------------
1 |
2 | # 组合模式(Composite Pattern)
3 |
4 | ## 定义
5 |
6 | Composite design pattern compose objects into tree structures to represent whole-part hierarchies.
7 | Composite lets clients treat individual objects and compositions of objects uniformly.
8 |
9 | 将对象组合成树状结构以表示整体的层次结构。
10 | 使得用户对单个对象和组合对象的使用,具有一致性。
11 |
12 | ## 类图
13 |
14 | 
15 |
16 | ## 用例
17 |
18 | 举的例子是小菜写公司OA系统遇到的困难。详细见代码。
19 |
20 | [code example](./code/u019)
21 |
22 | ## 实际应用
23 |
24 | - 公司员工之间的上下级关系。
25 | - GUI
26 | - 文件系统
27 |
28 | ## 什么时候使用
29 |
30 | 层级结构,组件功能类似,可以很容易新增组件,组件间可以组合。
31 |
32 | ## 参考
33 |
34 | [howtodo-composite-patterns](https://howtodoinjava.com/design-patterns/structural/composite-design-pattern/)
--------------------------------------------------------------------------------
/020_IteratorPattern.md:
--------------------------------------------------------------------------------
1 |
2 | # 迭代器模式
3 |
4 | ## 定义
5 |
6 | 迭代器模式提供一种方法顺序访问聚合对象中各个元素,而又不暴露该对象的内部表示。
7 |
8 | ## 类图
9 |
10 | 
11 |
12 | ## 用例
13 |
14 | 迭代器模式已经在编程语言内部中实现了。
15 |
16 | 样例见代码。[code example](./code/u020)
17 |
18 | ## 实际应用
19 |
20 | 例如我们听音乐的app中的播放列表。我们可以选择顺序播放,或者随机播放。
21 |
22 | ## 注意
23 |
24 | >A collection is only useful when it’s provides a way to access its elements without exposing its internal structure. The iterators bear this responsibility.
25 |
26 | >So any time, we have collection of objects and clients need a way to iterate over each collection elements in some proper sequence, we must use iterator pattern to design the solution.
27 |
28 | 当要遍历集合内部对象的时候就可以使用迭代器模式。
29 |
30 | 实现可以参考Java中的`List`抽象类中会创建一个`Iterator`, `Iterator`接口中有抽象方法例如`hasNext()`,`next()`,`remove`.
31 | `ArrayList`继承`List`,其中会创建一个`ArrayItr`.
32 |
33 | ```java
34 | private static class ArrayItr implements Iterator {
35 | private int cursor;
36 | private final E[] a;
37 |
38 | ArrayItr(E[] a) {
39 | this.a = a;
40 | }
41 |
42 | @Override
43 | public boolean hasNext() {
44 | return cursor < a.length;
45 | }
46 |
47 | @Override
48 | public E next() {
49 | int i = cursor;
50 | if (i >= a.length) {
51 | throw new NoSuchElementException();
52 | }
53 | cursor = i + 1;
54 | return a[i];
55 | }
56 | }
57 | ```
58 |
59 | ## 参考
60 |
61 | [howtodo-iterator-pattern](https://howtodoinjava.com/design-patterns/behavioral/iterator-design-pattern/)
--------------------------------------------------------------------------------
/021_SingletonPattern.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 单例模式
4 |
5 | ## 定义
6 |
7 | 单例模式讨论的是一个应用中,一个类有且仅有一个实例的情况。
8 | 在Java中要讨论的是在每个JVM(java虚拟机)中,仅有一个实例。
9 |
10 | 注意两个词:**每个JVM**,**一个实例**。
11 |
12 | 接下来,让我们讨论一下在Java中如何实现单例模式。
13 |
14 | 代码量比较多。[code example](./code/u021)
15 |
16 | ## 饿汉模式(Eager Initialization)
17 |
18 | 不管有没有其他类调用这个实例,单例在系统类加载时就会被创建。
19 |
20 | ```java
21 | public class EagerSingleton {
22 |
23 | private static volatile EagerSingleton instance = new EagerSingleton();
24 |
25 | public static EagerSingleton getInstance() {
26 | return instance;
27 | }
28 |
29 | private EagerSingleton() {
30 | System.out.printf("%s Instance Created!\n", this.getClass().getSimpleName());
31 | }
32 | }
33 | ```
34 |
35 | 这种方法仅有一个缺点,对象大时,占用系统资源较多。
36 | 如果对象不大,占用系统资源较少,这是一个实现单例的好方法。
37 |
38 | ## 懒汉模式(Lazy Initialization)
39 |
40 | 在编程中,延迟初始化是一种编程技巧。在第一次需要时,才创建对象、计算值或者执行其他耗时的过程。
41 |
42 | ```java
43 | public final class LazySingleton {
44 |
45 | private static volatile LazySingleton instance = null;
46 |
47 | private LazySingleton() {}
48 |
49 | public static LazySingleton getInstance() {
50 | if(instance == null){
51 | synchronized (LazySingleton.class){
52 | instance = new LazySingleton();
53 | }
54 | }
55 | return instance;
56 | }
57 | }
58 | ```
59 |
60 | Double Check:
61 |
62 | ```java
63 | public static LazySingletonV2 getInstance() {
64 | if (instance == null) {
65 | synchronized (LazySingletonV2.class) {
66 | if (instance == null) {
67 | instance = new LazySingletonV2();
68 | // multi thread will generate two or more instances.
69 | System.out.println("instance address: " + instance);
70 | }
71 | }
72 | }
73 | return instance;
74 | }
75 | ```
76 |
77 | ## 静态块初始化 Singleton with static block initialization
78 |
79 | 这种方法在类加载的时候创建实例。有一个缺点:就是假设这个类里有5个静态变量,代码仅需要访问2-3个变量,这时创建
80 | instance就没有什么用。
81 |
82 | ```java
83 | public class StaticBlockSingleton {
84 |
85 | private static final StaticBlockSingleton instance;
86 |
87 | static {
88 | instance = new StaticBlockSingleton();
89 | }
90 |
91 | private StaticBlockSingleton() {}
92 |
93 | public static StaticBlockSingleton getInstance() {
94 | return instance;
95 | }
96 |
97 | }
98 | ```
99 |
100 | ## Bill Pugh 单例
101 |
102 | LazyHolder类在需要时才创建。同时我们还可以访问其他静态变量。
103 |
104 |
105 | ```java
106 | public class BillPughSingleton {
107 |
108 | public static int NUM = 10;
109 |
110 | private BillPughSingleton() {
111 | System.out.println("create singleton.");
112 | }
113 |
114 | private static class LazyHolder {
115 |
116 | static {
117 | System.out.println("create class LazyHolder...");
118 | }
119 |
120 | private static final BillPughSingleton instance = new BillPughSingleton();
121 | }
122 |
123 | public static BillPughSingleton getInstance() {
124 | return LazyHolder.instance;
125 | }
126 | }
127 | ```
128 |
129 | ## 单例序列化
130 |
131 | 反序列化时会重新生成实例。在类中加入`readResolve`方法。返回当前实例。
132 |
133 | >This method will be invoked when you will de-serialize the object. Inside of this method, you must return the existing instance to ensure a single instance application wide.
134 |
135 | ```java
136 | public class DemoSingleton implements Serializable {
137 |
138 | private static volatile DemoSingleton instance = null;
139 |
140 | public static DemoSingleton getInstance() {
141 | if (instance == null) {
142 | instance = new DemoSingleton();
143 | }
144 | return instance;
145 | }
146 |
147 | private int i = 10;
148 |
149 | // return existing instance.
150 | // protected Object readResolve(){
151 | // return instance;
152 | // }
153 |
154 | public int getI() {
155 | return i;
156 | }
157 |
158 | public void setI(int i) {
159 | this.i = i;
160 | }
161 | }
162 | ```
163 |
164 | ## 关于序列号
165 |
166 | 序列化要加上序列号。若不加,这个了类如果修改的话,再次反序列化此前的类,会报 `local class incompatible`
167 |
168 | ```java
169 | Exception in thread "main" java.io.InvalidClassException: u021.seri.DemoSingleton; local class incompatible: stream classdesc serialVersionUID = -6928200329713978600, local class serialVersionUID = 2784835485903072265
170 | at java.base/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:689)
171 | at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1903)
172 | at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1772)
173 | at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2060)
174 | at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
175 | at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430)
176 | at u021.seri.Client.main(Client.java:21)
177 | ```
178 |
179 | >This problem can be solved only by adding a unique serial version id to the class. It will prevent the compiler from throwing the exception by telling it that both classes are same, and will load the available instance variables only.
180 |
181 | ## 总结
182 |
183 | 经过上面的讨论,那么一个推荐的单例模式该如何写呢?
184 |
185 | ```java
186 | public class DemoSingleton implements Serializable {
187 |
188 | private static final long serialVersionUID = 1L;
189 |
190 | private DemoSingleton() {}
191 |
192 | private static class DemoSingletonHolder {
193 |
194 | private static final DemoSingleton instance = new DemoSingleton();
195 | }
196 |
197 | public static DemoSingleton getInstance() {
198 | return DemoSingletonHolder.instance;
199 | }
200 |
201 | protected Object readResolve() {
202 | return getInstance();
203 | }
204 | }
205 | ```
206 |
207 | ## 参考
208 |
209 | [双重检查锁🔒double-checked_locking](https://en.wikipedia.org/wiki/Double-checked_locking)
210 |
211 | ## 问题
212 |
213 | ### 分布式系统的单例有几个?
214 |
215 | Singleton is “one instance per JVM”, so each node will have its own copy of singleton.
216 |
217 |
218 | ### 关于BillPughSingleton
219 |
220 | 类初始化在JVM层面是线程安全的。
221 |
222 | ```java
223 | public class BillPughSingleton {
224 | private BillPughSingleton() {
225 | }
226 |
227 | private static class LazyHolder {
228 | private static final BillPughSingleton INSTANCE = new BillPughSingleton();
229 | }
230 |
231 | public static BillPughSingleton getInstance() {
232 | return LazyHolder.INSTANCE;
233 | }
234 | }
235 | ```
236 |
237 | As per you recommend above code template to design singleton class.
238 | But how Thread safety achieve in above code ??
239 |
240 | It’s already threadsafe because java static field/class
241 | initialization is thread safe – at JVM level.
242 | Static initialization is performed once per class-loader and JVM
243 | ensures the single copy of static fields. So even if two threads access above code,
244 | only one instance of class will be created by JVM.
245 |
246 |
--------------------------------------------------------------------------------
/022_BrigePattern.md:
--------------------------------------------------------------------------------
1 |
2 | # 桥接模式(Bridge Pattern)
3 |
4 | 合成(组合)/ 聚合复用原则,尽量使用组成/聚合,尽量不用类继承。
5 |
6 | ## 定义
7 |
8 | 桥接模式(Bridge):将抽象部分与它的实现部分分离,都可以使它们独立变化。
9 |
10 | ## 类图
11 |
12 | 
13 |
14 | ## 用例
15 |
16 | [code example](./code/u022)
17 |
18 | ## 实际应用
19 |
20 | - 桥接模式将抽象与实现解耦,二者可以独立变化。
21 | - 它主要用于实现平台独立的功能。
22 | - 方法重定向实现功能
23 | - 接口抽象发布在单独的继承体系中,将其实现在自己的继承结构中。
24 | - 使用桥接模式实现运行是绑定(确定类)。
25 | - 使用桥接模式映射正交类层次结构(不相关的类)
26 | - 预先设计,使得抽象和实现独立变化。
27 |
28 | 另一中解释,体会体会。实现系统可能多角度分类,每一种分类都有可能变化,那么就把这种多角度分类出来让他们独立变化,减少他们之间的耦合。
29 |
30 | ## 参考
31 |
32 | [howtodo-bridge-pattern](https://howtodoinjava.com/design-patterns/structural/bridge-design-pattern/)
--------------------------------------------------------------------------------
/023_CommandPattern.md:
--------------------------------------------------------------------------------
1 |
2 | # 命令模式(Command)
3 |
4 | ## 定义
5 |
6 | Encapsulate a request as an object,
7 | thereby letting you parameterize clients with different requests,
8 | queue or log requests, and support undoable operations.
9 |
10 | 将请求封装成对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
11 |
12 | ## 类图
13 |
14 | 
15 |
16 | ## 用例
17 |
18 | 
19 |
20 | 《大话设计模式》中举的小菜和大鸟去吃羊肉串的例子。
21 | 去串肉吃烧烤,和服务员下单,服务员告诉烤串师傅烤串。
22 | 而不是自己去后厨告诉师傅说你要点啥。
23 |
24 | 理解了这个例子就比较好理解命令模式。
25 |
26 | [code example](./code/u023)
27 |
28 | ## 实际应用
29 |
30 | Java的Runnable接口是一种命令模式。
31 |
32 | ## 注意
33 |
34 | - 每个command都有指向receiver的引用
35 | - command中的execute调用receiver中的具体逻辑方法
36 | - receiver执行具体的业务逻辑
37 |
38 | ## 参考
39 |
40 | [howtodo-command-pattern](https://howtodoinjava.com/design-patterns/behavioral/command-pattern/)
--------------------------------------------------------------------------------
/024_ChainOfResponsibility.md:
--------------------------------------------------------------------------------
1 |
2 | # 职责链模式(Chain of Responsibility Pattern)
3 |
4 | ## 定义
5 |
6 | 将发送请求的处理连成一条链,沿着这条链传递请求,直到处理完成为止。
7 |
8 | ## 类图
9 |
10 | 
11 |
12 | ## 用例
13 |
14 | 《大话设计模式》中讲了小菜申请加薪的例子。加薪需要总经理审批。
15 |
16 | 生活中的例子是出去度假,可能要请10天假,这是就需要总监或者经理审批了。
17 |
18 | [code example](./code/u024)
19 |
20 | ## 实际应用
21 |
22 | `javax.servlet.Filter#doFilter()`
23 |
24 | `java.util.logging.Logger#log`
25 |
26 | If the logger is currently enabled for the given message level
27 | then the given message is forwarded to all the registered output Handler objects.
28 |
29 | ## 参考
30 |
31 | [chain-of-responsibility](https://howtodoinjava.com/design-patterns/behavioral/chain-of-responsibility-design-pattern/)
--------------------------------------------------------------------------------
/025_MediatorPattern.md:
--------------------------------------------------------------------------------
1 |
2 | # 中介者模式(Mediator Pattern)
3 |
4 | ## 定义
5 |
6 | 中介者模式一系列对象的对象的交互。使得对象间不需要显示的引用,使得耦合松散。
7 | 可以独立改变他们之间的交互。
8 |
9 | mediator pattern defines an object that encapsulates
10 | how a set of objects interact. Mediator promotes loose
11 | coupling by keeping objects from referring to each other explicitly,
12 | and it lets us vary their interaction independently.
13 |
14 | Allows loose coupling by encapsulating the way disparate sets of objects
15 | interact and communicate with each other.
16 | Allows for the actions of each object set to vary independently of one another.
17 |
18 | ## 类图
19 |
20 | 
21 |
22 | ## 用例
23 |
24 | 《大话设计模式》中举的例子是联合国安理会做为中介者,调节各国之间的关系。
25 |
26 | 代码中的示例是聊天室的例子。
27 |
28 | [code example](./code/u025)
29 |
30 | ## 实际应用
31 |
32 | - 现实生活中机场的航空管制。
33 | - 聊天室
34 |
35 | The following are the usages of the Mediator Pattern in JDK.
36 |
37 | ```java
38 | java.util.concurrent.ScheduledExecutorService (all scheduleXXX() methods)
39 | java.util.concurrent.ExecutorService (the invokeXXX() and submit() methods)
40 | java.util.concurrent.Executor#execute()
41 | java.util.Timer (all scheduleXXX() methods)
42 | java.lang.reflect.Method#invoke()
43 | ```
44 |
45 | ## 参考
46 |
47 | [mediator used in java](https://www.javacodegeeks.com/2015/09/mediator-design-pattern.html)
--------------------------------------------------------------------------------
/026_FlyweightPattern.md:
--------------------------------------------------------------------------------
1 |
2 | # 享元模式(Flyweight Pattern)
3 |
4 | ## 定义
5 |
6 | 享元模式运用共享技术有效地支持大量细粒度的对象。
7 |
8 | flyweight design pattern enables use sharing of
9 | objects to support large numbers of fine-grained objects efficiently.
10 |
11 | A flyweight is a shared object that can be used in multiple contexts
12 | simultaneously. The flyweight acts as an independent object in each context.
13 |
14 | ## 类图
15 |
16 | 
17 |
18 | ## 用例
19 |
20 | 《大话设计模式》中的例子不怎么好,就不放了。
21 |
22 | ## 实际应用
23 |
24 | 享元模式可以避免大量相似类的开销。在程序设计时,有时需要生成大量细粒度的类实例来表示数据。
25 | 如果能发现这些实例除了几个参数外基本上都是相同的,有时就能够大幅度减少需要实例化的类的创建。
26 | 如果能把那些参数移到实例的外面,在方法调用时将它们传递过来,就可以通过共享大幅度的减少单个实例的个数。
27 |
28 | 意思是说:外部状态传递给Flyweight对象。
29 |
30 | `java String的实现就是享元模式。维护一个常量池`
31 |
32 | ## 注意
33 |
34 | 多线程环境下使用Lock。
35 |
36 | ## 参考
37 |
38 | [howtodo-flyweight](https://howtodoinjava.com/design-patterns/structural/flyweight-design-pattern/)
39 |
--------------------------------------------------------------------------------
/027_InterpreterPattern.md:
--------------------------------------------------------------------------------
1 |
2 | # 解释器模式(Interpreter Pattern)
3 |
4 | ## 定义
5 |
6 | 使用面向对象的方式定义一种语言和语法,并定一个解释器,这个解释器用来计算表达式的值。
7 |
8 | In short, the pattern defines the grammar of a particular language i
9 | n an object-oriented way which can be evaluated by the interpreter itself.
10 |
11 | 构建抽象语法树,并解释。
12 |
13 | build abstract syntax trees and then run the interpretation.
14 |
15 | ## 类图
16 |
17 | 
18 |
19 | ## 用例
20 |
21 | 环境:保存处理过程中的整个状态。在解释类中会被重用。
22 |
23 | 终止表达式:停止解释,返回结果。
24 |
25 | 非终止表达式:包含一个或多个抽象表达式,可以递归的解释。
26 |
27 | 客户端:创建抽象语法树。初始化环境,调用解释器解释。
28 |
29 | **SQL风格的查询**:[code example](./code/u027)
30 |
31 | ## 实际应用
32 |
33 | JDK中的使用:
34 |
35 | `java.util.Pattern`
36 |
37 | `java.text.Format`
38 |
39 | `java.text.Normalizer`
40 |
41 | [normalizer的使用](https://juejin.im/entry/5cbd5f485188250ab10aaee8)
42 |
43 | ## 参考
44 |
45 | [baeldung-interpreter-pattern](https://www.baeldung.com/java-interpreter-pattern)
--------------------------------------------------------------------------------
/028_VisitorPattern.md:
--------------------------------------------------------------------------------
1 |
2 | # 访问者模式(Visitor Pattern)
3 |
4 | ## 定义
5 |
6 | 把数据结构和作用于结构上的操作之间解耦合。简单点说就是数据结构和算法分开。
7 |
8 | Allows for one or more operation to be applied to a set of objects at runtime,
9 | decoupling the operations from the object structure.
10 |
11 | ## 类图
12 |
13 | 
14 |
15 | ## 用例
16 |
17 | 访问者模式算是比较复杂的。《大话设计模式》中举的男人女人(稳定的数据结构)的例子。
18 |
19 | 具体请看代码吧:
20 | [code example](./code/u028)
21 |
22 | ## 实际应用
23 |
24 | 比较稳定的数据结构,算法易于变化,使用Visitor Pattern是合适的。
25 |
26 | 优点:增加新的访问者很容易。
27 |
28 | 缺点:增加新的数据结构困难。因为访问者的实现基于已有的数据结构。
29 |
30 |
--------------------------------------------------------------------------------
/029_Summary.md:
--------------------------------------------------------------------------------
1 | # 设计模式总结-模式分类
2 |
3 | ## 重点掌握灰色的五个设计模式:
4 |
5 | 
6 |
7 |
8 | ## 创建型模式
9 |
10 | 关于对象如何实例化:
11 |
12 | 1. 抽象工厂模式:提供一个创建一系列或相关依赖对象的接口,而无需指定他们的具体实现类。
13 |
14 | 2. 建造者模式:将一个复杂对象的构建和它的表示分离,是的统一的创建过程可以创建不同的表示。
15 |
16 | 3. 工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
17 |
18 | 4. 原型模式:用原型实例指定创建对象的种类,并且通过考虑这些圆形穿件新的对象。
19 |
20 | 5. 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
21 |
22 | 创建型模式将系统使用哪些具体类的信息封装起来。不让用户依赖于对象的创建方式,避免用户使用new来创建对象。
23 |
24 | ## 结构型模式
25 |
26 | 1. 适配器模式:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
27 |
28 | 2. 桥接模式:将抽象部分与它的实现部分分离,使他们可以独立于变化。【不好理解,需要仔细体会体会】
29 |
30 | 3. 组合模式:将对象组合成树型🌲结构可以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
31 |
32 | 4. 装饰器模式:动态地给一个对象增加一些额外的职责。就增加功能来说,装饰模式相比生成子类更加灵活。为已有的功能动态增加功能。
33 |
34 | 5. 外观模式:为子系统种的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
35 |
36 | 6. 享元模式:运用共享技术有效地支持大量细粒度的对象。
37 |
38 | 7. 代理模式:为其他对象提供一种代理以控制对这个对象的访问。
39 |
40 | ## 行为模式:
41 |
42 | 1. 观察者模式:定义对象间的一种多对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
43 | 2. 模板方法模式:定义一个操作的算法骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可以重定义该算法的某些特定步骤。 这个比较容易理解。
44 | 3. 命令模式:将一个请求封装成为一个对象,从而你可以用不同的请求对客户进行参数化;可以对请求排队或记录请求日志,以及支持可以撤销的操作。
45 | 4. 状态模式:允许一个对象在其内部状态改变时改变它的行为,让对象看起来似乎改变了它的类。
46 | 5. 职责链模式:使多个对象有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
47 | 6. 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
48 | 7. 中介者模式:用一个中介对象来封装一系列的对象交互。中介者使对象不需要显示的互相引用,从而使其耦合松散,而且可以独立滴改变它们之间的交互。
49 | 8. 访问者模式:表示一个作用于对象结构中的各元素的操作。它使你可以在不改变元素的类的前提下定义用于这些元素的新操作。
50 | 9. 策略模式:定义一系列算法,把它们一个个封装起来,并使它们可以相互替换。本模式可以使得算法独立于使用它的客户而变化。
51 | 10. 备忘录模式:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后可以将对象恢复到原先保存的状态。
52 | 11. 迭代器模式:提供一种顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示。
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # :fire: 手绘设计模式 :fire:
2 |
3 | ## Preface
4 |
5 | Design patterns represent the best practices used by experienced object-oriented software
6 | developers. Design patterns are solutions to general problems that software developers
7 | faced during software development.
8 | These solutions were obtained by trial and error by numerous
9 | software developers over quite a substantial period of time.
10 |
11 | This tutorial will take you through step by step
12 | approach and examples using Java while learning Design Pattern concepts.
13 |
14 | BTW, I have drawn all UMLs by hand. :smiley:
15 |
16 | Enjoy! Happy Learning!
17 |
18 | Features:
19 |
20 | - :white_check_mark: Based on Java
21 | - :white_check_mark: Hand-Drawn UML
22 | - :white_check_mark: 23 common design patterns
23 | - :white_check_mark: **SOLID**
24 |
25 | Currently this repo is under heavy development. Keep an eye on it!.
26 |
27 | ## 目录 Content
28 |
29 | ### 创建型模式
30 |
31 | 1. [抽象工厂模式](015_AbstractPattern.md) :提供一个创建一系列或相关依赖对象的接口,而无需指定他们的具体实现类。
32 |
33 | 2. [建造者模式](013_BuilderPattern.md):将一个复杂对象的构建和它的表示分离,是的统一的创建过程可以创建不同的表示。
34 |
35 | 3. [工厂方法](008_FactoryMethodPattern.md):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
36 |
37 | 4. [原型模式](009_PrototypePattern.md):用原型实例指定创建对象的种类,并且通过考虑这些圆形穿件新的对象。
38 |
39 | 5. [单例模式](021_SingletonPattern.md):保证一个类仅有一个实例,并提供一个访问它的全局访问点。
40 |
41 | ### 结构型模式
42 |
43 | 1. [适配器模式](017_AdapterPattern.md):将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
44 |
45 | 2. [桥接模式](022_BrigePattern.md):将抽象部分与它的实现部分分离,使他们可以独立于变化。
46 |
47 | 3. [组合模式](019_CompositePattern.md):将对象组合成树型🌲结构可以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
48 |
49 | 4. [装饰器模式](006_DecoratorPattern.md):动态地给一个对象增加一些额外的职责。就增加功能来说,装饰模式相比生成子类更加灵活。为已有的功能动态增加功能。
50 |
51 | 5. [外观模式](012_FacadePattern.md):为子系统种的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
52 |
53 | 6. [享元模式](026_FlyweightPattern.md):运用共享技术有效地支持大量细粒度的对象。
54 |
55 | 7. [代理模式](007_ProxyPattern.md):为其他对象提供一种代理以控制对这个对象的访问。
56 |
57 | ### 行为模式:
58 |
59 | 1. [观察者模式](014_ObserverPattern.md):定义对象间的一种多对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
60 |
61 | 2. [模板方法模式](010_TemplateMethodPattern.md):定义一个操作的算法骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可以重定义该算法的某些特定步骤。 这个比较容易理解。
62 |
63 | 3. [命令模式](023_CommandPattern.md):将一个请求封装成为一个对象,从而你可以用不同的请求对客户进行参数化;可以对请求排队或记录请求日志,以及支持可以撤销的操作。
64 |
65 | 4. [状态模式](016_StatePattern.md):允许一个对象在其内部状态改变时改变它的行为,让对象看起来似乎改变了它的类。
66 |
67 | 5. [职责链模式](024_ChainOfResponsibility.md):使多个对象有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
68 |
69 | 6. [解释器模式](027_InterpreterPattern.md):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
70 |
71 | 7. [中介者模式](025_MediatorPattern.md):用一个中介对象来封装一系列的对象交互。中介者使对象不需要显示的互相引用,从而使其耦合松散,而且可以独立滴改变它们之间的交互。
72 |
73 | 8. [访问者模式](028_VisitorPattern.md):表示一个作用于对象结构中的各元素的操作。它使你可以在不改变元素的类的前提下定义用于这些元素的新操作。
74 |
75 | 9. [策略模式](002_StrategyPattern.md):定义一系列算法,把它们一个个封装起来,并使它们可以相互替换。本模式可以使得算法独立于使用它的客户而变化。
76 |
77 | 10. [备忘录模式](018_MementoPattern.md):在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后可以将对象恢复到原先保存的状态。
78 |
79 | 11. [迭代器模式](020_IteratorPattern.md):提供一种顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示。
80 |
81 |
82 | 
83 |
84 |
85 | 2020@辣么大 gdhu
86 |
87 |
88 |
--------------------------------------------------------------------------------
/code/geekbang/u020/Test.java:
--------------------------------------------------------------------------------
1 | package geekbang.u020;
2 |
3 | import jdk.internal.joptsimple.internal.Strings;
4 |
5 | /**
6 | * Created by HuGuodong on 12/18/19.
7 | */
8 | public class Test {
9 |
10 | public static void main(String[] args) {
11 | String[] ips = {
12 | "1.2.3.4",
13 | "000.12.23.034",
14 | "121.234.9.1",
15 | "23.45.56.12",
16 | "255.255.255.255",
17 | "255.1.0.256",
18 | "00.11.22.33.44",
19 | "123.45",
20 | "Im.not.IP.address"
21 | };
22 | int NUM = 1000;
23 |
24 | }
25 |
26 | // 第一种实现方式: 使用正则表达式
27 | public boolean isValidIpAddressV1(String ipAddress) {
28 | if (Strings.isNullOrEmpty(ipAddress)) return false;
29 | String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
30 | + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
31 | + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
32 | + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
33 | return ipAddress.matches(regex);
34 | }
35 |
36 | // 第二种实现方式: 使用现成的工具类
37 | public boolean isValidIpAddressV2(String ipAddress) {
38 | if (Strings.isNullOrEmpty(ipAddress)) return false;
39 | String[] ipUnits = ipAddress.split(".");
40 | if (ipUnits.length != 4) {
41 | return false;
42 | }
43 | for (int i = 0; i < 4; ++i) {
44 | int ipUnitIntValue;
45 | try {
46 | ipUnitIntValue = Integer.parseInt(ipUnits[i]);
47 | } catch (NumberFormatException e) {
48 | return false;
49 | }
50 | if (ipUnitIntValue < 0 || ipUnitIntValue > 255) {
51 | return false;
52 | }
53 | if (i == 0 && ipUnitIntValue == 0) {
54 | return false;
55 | }
56 | }
57 | return true;
58 | }
59 |
60 | // 第三种实现方式: 不使用任何工具类
61 | public boolean isValidIpAddressV3(String ipAddress) {
62 | char[] ipChars = ipAddress.toCharArray();
63 | int length = ipChars.length;
64 | int ipUnitIntValue = -1;
65 | boolean isFirstUnit = true;
66 | int unitsCount = 0;
67 | for (int i = 0; i < length; ++i) {
68 | char c = ipChars[i];
69 | if (c == '.') {
70 | if (ipUnitIntValue < 0 || ipUnitIntValue > 255) return false;
71 | if (isFirstUnit && ipUnitIntValue == 0) return false;
72 | if (isFirstUnit) isFirstUnit = false;
73 | ipUnitIntValue = -1;
74 | unitsCount++;
75 | continue;
76 | }
77 | if (c < '0' || c > '9') {
78 | return false;
79 | }
80 | if (ipUnitIntValue == -1) ipUnitIntValue = 0;
81 | ipUnitIntValue = ipUnitIntValue * 10 + (c - '0');
82 | }
83 | if (ipUnitIntValue < 0 || ipUnitIntValue > 255) return false;
84 | if (unitsCount != 3) return false;
85 | return true;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/code/incomplete/ideas/Client.java:
--------------------------------------------------------------------------------
1 | package incomplete.ideas;
2 |
3 | /**
4 | * Created by HuGuodong on 11/20/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | ILog log= new ConsoleLog();
10 | log.log(null);
11 | log.init();
12 | ILog.OS();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/code/incomplete/ideas/ILog.java:
--------------------------------------------------------------------------------
1 | package incomplete.ideas;
2 |
3 | import java.io.OutputStream;
4 |
5 | /**
6 | * Created by HuGuodong on 11/20/19.
7 | */
8 | public interface ILog {
9 |
10 | enum Type {
11 | LOW,
12 | MEDIUM,
13 | HIGH
14 | }
15 |
16 | interface InILog{
17 | void initInLog();
18 | }
19 |
20 | default void init() {
21 | Type t = Type.LOW;
22 | System.out.println(t.ordinal());
23 | }
24 |
25 | static void OS() {
26 | System.out.println(System.getProperty("os.name", "linux"));
27 | }
28 |
29 | void log(OutputStream out);
30 | }
31 |
32 |
33 | class ConsoleLog implements ILog {
34 |
35 | @Override
36 | public void log(OutputStream out) {
37 | System.out.println("ConsoleLog...");
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/code/incomplete/ideas/TestBufferdInputStream.java:
--------------------------------------------------------------------------------
1 | package incomplete.ideas;
2 |
3 | import java.io.BufferedInputStream;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.FileNotFoundException;
7 |
8 | /**
9 | * Created by HuGuodong on 11/19/19.
10 | */
11 | public class TestBufferdInputStream {
12 |
13 | public static void main(String[] args) {
14 | try {
15 | BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("1.txt")));
16 | } catch (FileNotFoundException e) {
17 | e.printStackTrace();
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/code/u001/AbstractOperation.java:
--------------------------------------------------------------------------------
1 | package u001;
2 |
3 | /**
4 | * Created by HuGuodong on 2019/11/9.
5 | */
6 | public abstract class AbstractOperation {
7 |
8 | private double a;
9 | private double b;
10 |
11 | public double getA() {
12 | return a;
13 | }
14 |
15 | public void setA(double a) {
16 | this.a = a;
17 | }
18 |
19 | public double getB() {
20 | return b;
21 | }
22 |
23 | public void setB(double b) {
24 | this.b = b;
25 | }
26 |
27 | public abstract double getResult();
28 | }
29 |
30 | class OperationAdd extends AbstractOperation {
31 |
32 | @Override
33 | public double getResult() {
34 | return getA() + getB();
35 | }
36 | }
37 |
38 | class OperationSub extends AbstractOperation {
39 |
40 | @Override
41 | public double getResult() {
42 | return getA() - getB();
43 | }
44 | }
45 |
46 | class OperationMult extends AbstractOperation {
47 |
48 | @Override
49 | public double getResult() {
50 | return getA() * getB();
51 | }
52 | }
53 |
54 | class OperationDiv extends AbstractOperation {
55 |
56 | @Override
57 | public double getResult() {
58 | if (getB() == 0) {
59 | throw new IllegalArgumentException("b can not be zero.");
60 | }
61 | return getA() / getB();
62 | }
63 | }
--------------------------------------------------------------------------------
/code/u001/Operation.java:
--------------------------------------------------------------------------------
1 | package u001;
2 |
3 | //import edu.princeton.cs.algs4.StdIn;
4 |
5 | /**
6 | * Created by HuGuodong on 2019/11/9.
7 | */
8 | public class Operation {
9 |
10 | public static double getResult(double a, double b, String op) {
11 | double result = 0;
12 | switch (op) {
13 | case "+":
14 | result = a + b;
15 | break;
16 | case "-":
17 | result = a - b;
18 | break;
19 | case "*":
20 | result = a * b;
21 | break;
22 | case "/":
23 | result = a / b;
24 | break;
25 | }
26 | return result;
27 | }
28 |
29 | public static void main(String[] args) {
30 | double r = getResult(10, 20, "-");
31 | System.out.println(r);
32 | // double a = StdIn.readDouble();
33 | // double b = StdIn.readDouble();
34 | // String op = StdIn.readString();
35 | // System.out.println("result is :" + getResult(a, b, op));
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/code/u001/OperationClient.java:
--------------------------------------------------------------------------------
1 | package u001;
2 |
3 | /**
4 | * Created by HuGuodong on 2019/11/9.
5 | */
6 | public class OperationClient {
7 |
8 | public static void main(String[] args) {
9 | double a = 10;
10 | double b = 20;
11 | AbstractOperation operation = OperationFactory.createOp("+");
12 | operation.setA(a);
13 | operation.setB(b);
14 | double result = operation.getResult();
15 | System.out.println(result);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/code/u001/OperationFactory.java:
--------------------------------------------------------------------------------
1 | package u001;
2 |
3 | /**
4 | * Created by HuGuodong on 2019/11/9.
5 | */
6 | public class OperationFactory {
7 |
8 | public static AbstractOperation createOp(String op) {
9 | AbstractOperation oper = null;
10 | switch (op) {
11 | case "+":
12 | oper = new OperationAdd();
13 | break;
14 | case "-":
15 | oper = new OperationSub();
16 | break;
17 | case "*":
18 | oper = new OperationMult();
19 | break;
20 | case "/":
21 | oper = new OperationDiv();
22 | break;
23 |
24 | }
25 | return oper;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/code/u002/v1/Casher.java:
--------------------------------------------------------------------------------
1 | package u002.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 2019/11/10.
5 | */
6 | public class Casher {
7 |
8 | private double total;
9 |
10 | public Casher() {
11 |
12 | }
13 |
14 | public void add(double price, int num) {
15 | total += price * num;
16 | }
17 |
18 | public double getTotal() {
19 | return total;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/code/u002/v1/Client.java:
--------------------------------------------------------------------------------
1 | package u002.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 2019/11/10.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | Casher casher = new Casher();
10 | casher.add(100, 1);
11 | casher.add(500, 2);
12 | System.out.println("Total is: " + casher.getTotal());
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/code/u002/v2/Casher.java:
--------------------------------------------------------------------------------
1 | package u002.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 2019/11/10.
5 | */
6 | public class Casher {
7 |
8 | private final static int FULL = 0;
9 | private final static int DISCOUNT_8 = 1;
10 | private final static int DISCOUNT_7 = 2;
11 | private final static int DISCOUNT_6 = 3;
12 |
13 | private double total;
14 |
15 | public Casher() {
16 |
17 | }
18 |
19 | public void add(double price, int num) {
20 | total += price * num;
21 | }
22 |
23 | public void add(double price, int num, double discount) {
24 | total += price * num * discount;
25 | }
26 |
27 | public void add(int discountType, double price, int num) {
28 | switch (discountType) {
29 | case FULL:
30 | add(price, num);
31 | break;
32 | case DISCOUNT_8:
33 | add(price, num, 0.8);
34 | break;
35 | case DISCOUNT_7:
36 | add(price, num, 0.7);
37 | break;
38 | case DISCOUNT_6:
39 | add(price, num, 0.6);
40 | break;
41 | }
42 | }
43 |
44 | public double getTotal() {
45 | return total;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/code/u002/v2/Client.java:
--------------------------------------------------------------------------------
1 | package u002.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 2019/11/10.
5 | */
6 | public class Client {
7 |
8 | /**
9 | * add discount
10 | *
11 | * @param args
12 | */
13 | public static void main(String[] args) {
14 | Casher casher = new Casher();
15 | casher.add(0, 100.0, 10);
16 | casher.add(1, 100.0, 10);
17 | casher.add(2, 100.0, 10);
18 |
19 | System.out.println("Total is: " + casher.getTotal()); // 2500.0
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/code/u002/v3/CashSuper.java:
--------------------------------------------------------------------------------
1 | package u002.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 2019/11/11.
5 | */
6 | public abstract class CashSuper {
7 |
8 | public abstract double acceptCash(double money);
9 |
10 | }
11 |
12 | class Discount extends CashSuper {
13 |
14 | private double discount = 1;
15 |
16 | public Discount(double discount) {
17 | this.discount = discount;
18 | }
19 |
20 | @Override
21 | public double acceptCash(double money) {
22 | return money * discount;
23 | }
24 | }
25 |
26 | class CashNormal extends CashSuper {
27 |
28 | @Override
29 | public double acceptCash(double money) {
30 | return money;
31 | }
32 | }
33 |
34 | class CashFactory {
35 |
36 | public static CashSuper createCaseAccept(int type) {
37 | CashSuper cs = null;
38 | if (type == 0) {
39 | cs = new CashNormal();
40 | } else if (type == 1)
41 | cs = new Discount(0.8);
42 | return cs;
43 | }
44 |
45 | }
--------------------------------------------------------------------------------
/code/u002/v3/Client.java:
--------------------------------------------------------------------------------
1 | package u002.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 2019/11/11.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | // client needs to know two classes : CashSuper, CashFactory
10 | // we need more encapsulation
11 | CashSuper cs = CashFactory.createCaseAccept(1); // discount
12 | double total = cs.acceptCash(1000);
13 | System.out.println(total);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/code/u002/v4/CashContext.java:
--------------------------------------------------------------------------------
1 | package u002.v4;
2 |
3 |
4 | /**
5 | * Created by HuGuodong on 2019/11/11.
6 | */
7 | public class CashContext {
8 |
9 | private CashSuper cs;
10 |
11 | public CashContext(int type) {
12 | if (type == 0) {
13 | cs = new CashNormal();
14 | } else if (type == 1) {
15 | cs = new Discount(0.8);
16 | }
17 | }
18 |
19 | public double getResult(double money) {
20 | return cs.acceptCash(money);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/code/u002/v4/CashSuper.java:
--------------------------------------------------------------------------------
1 | package u002.v4;
2 |
3 | /**
4 | * Created by HuGuodong on 2019/11/11.
5 | */
6 | public abstract class CashSuper {
7 |
8 | public abstract double acceptCash(double money);
9 |
10 | }
11 |
12 | class Discount extends CashSuper {
13 |
14 | private double discount = 1;
15 |
16 | public Discount(double discount) {
17 | this.discount = discount;
18 | }
19 |
20 | @Override
21 | public double acceptCash(double money) {
22 | return money * discount;
23 | }
24 | }
25 |
26 | class CashNormal extends CashSuper {
27 |
28 | @Override
29 | public double acceptCash(double money) {
30 | return money;
31 | }
32 | }
33 |
34 | class CashFactory {
35 |
36 | public static CashSuper createCaseAccept(int type) {
37 | CashSuper cs = null;
38 | if (type == 0) {
39 | cs = new CashNormal();
40 | } else if (type == 1)
41 | cs = new Discount(0.8);
42 | return cs;
43 | }
44 |
45 | }
--------------------------------------------------------------------------------
/code/u002/v4/Client.java:
--------------------------------------------------------------------------------
1 | package u002.v4;
2 |
3 | /**
4 | * Created by HuGuodong on 2019/11/11.
5 | */
6 | public class Client {
7 |
8 | /**
9 | * only dispose CashContext Class
10 | *
11 | * @param args
12 | */
13 | public static void main(String[] args) {
14 | CashContext cc = new CashContext(1);
15 | double total = cc.getResult(1000);
16 | System.out.println(total);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/code/u004/MessageQueue.java:
--------------------------------------------------------------------------------
1 | package u004;
2 |
3 | /**
4 | * Created by HuGuodong on 12/17/19.
5 | */
6 | public interface MessageQueue {
7 |
8 | void put();
9 | }
10 |
11 | interface MessageFormatter {
12 |
13 | void format();
14 | }
15 |
16 | class KafkaMessageQueue implements MessageQueue {
17 |
18 | @Override
19 | public void put() {
20 |
21 | }
22 | }
23 |
24 | class RocketMessageQueue implements MessageQueue {
25 |
26 | @Override
27 | public void put() {
28 |
29 | }
30 | }
31 |
32 | class JsonMessageFormatter implements MessageFormatter {
33 |
34 | @Override
35 | public void format() {
36 |
37 | }
38 | }
39 |
40 | class Demo {
41 |
42 | MessageQueue queue;
43 |
44 | Demo(MessageQueue queue) {
45 | this.queue = queue;
46 | }
47 |
48 | void setNotification(MessageFormatter formatter) {
49 | formatter.format();
50 | }
51 |
52 | public static void main(String[] args) {
53 |
54 | }
55 | }
--------------------------------------------------------------------------------
/code/u005/dip/Person.java:
--------------------------------------------------------------------------------
1 | package u005.dip;
2 |
3 | /**
4 | * Created by HuGuodong on 12/16/19.
5 | */
6 | public class Person {
7 |
8 | private String name;
9 | private Phone phone;
10 |
11 | public Person(String name, Phone phone) {
12 | this.name = name;
13 | this.phone = phone;
14 | }
15 |
16 | public void makeCall() {
17 | phone.call();
18 | }
19 |
20 | public void playGame() {
21 | phone.play();
22 | }
23 |
24 | public static void main(String[] args) {
25 | Phone iPhone = new iPhone(); // 第三方
26 | Person xiaoming = new Person("xiaoming", iPhone); // 依赖注入
27 | xiaoming.makeCall();
28 | xiaoming.playGame();
29 |
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/code/u005/dip/Phone.java:
--------------------------------------------------------------------------------
1 | package u005.dip;
2 |
3 | /**
4 | * Created by HuGuodong on 12/16/19.
5 | */
6 | public abstract class Phone {
7 |
8 | protected String brand;
9 |
10 | public Phone(String brand) {
11 | this.brand = brand;
12 | }
13 |
14 | abstract void call();
15 |
16 | abstract void play();
17 | }
18 |
19 | class iPhone extends Phone {
20 |
21 | public iPhone() {
22 | super("iPhone");
23 | }
24 |
25 | @Override
26 | void call() {
27 | System.out.println(brand + " call");
28 | }
29 |
30 | @Override
31 | void play() {
32 | System.out.println(brand + " play");
33 | }
34 | }
35 |
36 | class HuaWei extends Phone {
37 |
38 | public HuaWei() {
39 | super("HuaWei");
40 | }
41 |
42 | @Override
43 | void call() {
44 | System.out.println(brand + " call");
45 | }
46 |
47 | @Override
48 | void play() {
49 | System.out.println(brand + " play");
50 | }
51 | }
--------------------------------------------------------------------------------
/code/u006/Client.java:
--------------------------------------------------------------------------------
1 | package u006;
2 |
3 | /**
4 | * Created by HuGuodong on 11/20/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | ICar bmw = new BMW();
10 | bmw.makeOrder();
11 | // A new order has been made.Car: u006.BMW
12 |
13 | // decorate
14 | ICar bmw_leather = new LeatherSeats(bmw);
15 | ICar bmw_addAudio = new AudioDecorator(bmw_leather);
16 | bmw_addAudio.makeOrder();
17 | // A new order has been made.Car: u006.BMW
18 | // Leather seats have been added.
19 | // Audio devices are awesome.
20 |
21 | ICar modelX = new ModelX();
22 | modelX.makeOrder();
23 | // A new order has been made. Car: u006.ModelX
24 |
25 | // decorate
26 | ICar modelX_audio = new AudioDecorator(modelX);
27 | modelX_audio.makeOrder();
28 | // A new order has been made. Car: u006.ModelX
29 | // Audio devices are awesome.
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/code/u006/ICar.java:
--------------------------------------------------------------------------------
1 | package u006;
2 |
3 | /**
4 | * Created by HuGuodong on 11/20/19.
5 | */
6 | public interface ICar {
7 |
8 | void makeOrder();
9 | }
10 |
11 | class ModelX implements ICar {
12 |
13 | @Override
14 | public void makeOrder() {
15 | System.out.println("A new order has been made. Car: " + this.getClass().getName());
16 | }
17 | }
18 |
19 | class BMW implements ICar {
20 |
21 | @Override
22 | public void makeOrder() {
23 | System.out.println("A new order has been made.Car: " + this.getClass().getName());
24 | }
25 | }
26 |
27 | abstract class CarDecorator implements ICar{
28 |
29 | protected ICar car;
30 |
31 | public CarDecorator(ICar car) {
32 | this.car = car;
33 | }
34 |
35 | public abstract void makeOrder();
36 |
37 | }
38 |
39 | class AudioDecorator extends CarDecorator {
40 |
41 | public AudioDecorator(ICar car) {
42 | super(car);
43 | }
44 |
45 | @Override
46 | public void makeOrder() {
47 | car.makeOrder();
48 | showAudioDevices();
49 | }
50 |
51 | public void showAudioDevices(){
52 | System.out.println("Audio devices are awesome.");
53 | }
54 |
55 | }
56 |
57 | class LeatherSeats extends CarDecorator {
58 |
59 | public LeatherSeats(ICar car) {
60 | super(car);
61 | }
62 |
63 | @Override
64 | public void makeOrder() {
65 | car.makeOrder();
66 | addLeatherSeats();
67 | }
68 |
69 | private void addLeatherSeats(){
70 | System.out.println("Leather seats have been added.");
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/code/u007/Client.java:
--------------------------------------------------------------------------------
1 | package u007;
2 |
3 | /**
4 | * Created by HuGuodong on 11/19/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | Proxy xiao_gang = new Proxy(new Pursuit("Lovely Girl"));
10 | xiao_gang.sendFlower();
11 | xiao_gang.sendChocolate();
12 | xiao_gang.sendDoll();
13 | // Lovely Girl, here is your flower.
14 | // Lovely Girl, here is your chocolate.
15 | // Lovely Girl, here is your doll.
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/code/u007/ISendPresents.java:
--------------------------------------------------------------------------------
1 | package u007;
2 |
3 | /**
4 | * Created by HuGuodong on 11/19/19.
5 | */
6 | public interface ISendPresents {
7 |
8 | void sendFlower();
9 |
10 | void sendDoll();
11 |
12 | void sendChocolate();
13 | }
14 |
15 | class Pursuit implements ISendPresents {
16 |
17 | private String girlName;
18 |
19 | public Pursuit(String name) {
20 | this.girlName = name;
21 | }
22 |
23 | @Override
24 | public void sendFlower() {
25 | System.out.printf("%s, here is your flower.\n", girlName);
26 | }
27 |
28 | @Override
29 | public void sendDoll() {
30 | System.out.printf("%s, here is your doll.\n", girlName);
31 | }
32 |
33 | @Override
34 | public void sendChocolate() {
35 | System.out.printf("%s, here is your chocolate.\n", girlName);
36 | }
37 | }
38 |
39 | class Proxy implements ISendPresents {
40 |
41 | private Pursuit p;
42 |
43 | public Proxy(Pursuit p) {
44 | this.p = p;
45 | }
46 |
47 | @Override
48 | public void sendFlower() {
49 | p.sendFlower();
50 | }
51 |
52 | @Override
53 | public void sendDoll() {
54 | p.sendDoll();
55 | }
56 |
57 | @Override
58 | public void sendChocolate() {
59 | p.sendChocolate();
60 | }
61 | }
--------------------------------------------------------------------------------
/code/u008/factorymethod/Client.java:
--------------------------------------------------------------------------------
1 | package u008.factorymethod;
2 |
3 | /**
4 | * Created by HuGuodong on 11/21/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | IOperationFactory operationFactory = new AddFactory();
10 | Operation oper = operationFactory.createOperation();
11 | oper.numA = 10;
12 | oper.numB = 15;
13 | System.out.println(oper.getResult());
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/code/u008/factorymethod/IOperationFactory.java:
--------------------------------------------------------------------------------
1 | package u008.factorymethod;
2 |
3 | /**
4 | * Created by HuGuodong on 11/21/19.
5 | */
6 | public interface IOperationFactory {
7 | Operation createOperation();
8 | }
9 |
10 | class AddFactory implements IOperationFactory{
11 |
12 | @Override
13 | public Operation createOperation() {
14 | return new AddOper();
15 | }
16 | }
17 |
18 | class MultFactory implements IOperationFactory{
19 |
20 | @Override
21 | public Operation createOperation() {
22 | return new MultOper();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/u008/factorymethod/Operation.java:
--------------------------------------------------------------------------------
1 | package u008.factorymethod;
2 |
3 | /**
4 | * Created by HuGuodong on 11/21/19.
5 | */
6 | public abstract class Operation {
7 |
8 | protected double numA;
9 | protected double numB;
10 |
11 | public abstract double getResult();
12 | }
13 |
14 | class AddOper extends Operation {
15 |
16 | @Override
17 | public double getResult() {
18 | return numA + numB;
19 | }
20 | }
21 |
22 | class MultOper extends Operation {
23 |
24 | @Override
25 | public double getResult() {
26 | return numA * numB;
27 | }
28 | }
--------------------------------------------------------------------------------
/code/u008/simplefactory/Client.java:
--------------------------------------------------------------------------------
1 | package u008.simplefactory;
2 |
3 | /**
4 | * Created by HuGuodong on 11/21/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | Operate op = OperateFactory.createOperate("+");
10 | op.numA = 100;
11 | op.numB = 200;
12 | double ans = op.getResult();
13 | System.out.printf("%.2f\n", ans); // 300
14 |
15 | // IllegalArgumentException: not implemented yet
16 | // op = OperateFactory.createOperate("-");
17 | op = OperateFactory.createOperate("*");
18 | op.numA = 100;
19 | op.numB = 0.33;
20 |
21 | ans = op.getResult();
22 | System.out.printf("%.2f\n", ans); // 33.00
23 |
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/u008/simplefactory/Operate.java:
--------------------------------------------------------------------------------
1 | package u008.simplefactory;
2 |
3 | /**
4 | * Created by HuGuodong on 11/21/19.
5 | */
6 | public abstract class Operate {
7 |
8 | protected double numA;
9 | protected double numB;
10 |
11 | protected abstract double getResult();
12 | }
13 |
14 | class AddOper extends Operate {
15 |
16 | @Override
17 | protected double getResult() {
18 | return numA + numB;
19 | }
20 | }
21 |
22 | class MultOper extends Operate {
23 |
24 | @Override
25 | protected double getResult() {
26 | return numA * numB;
27 | }
28 | }
29 |
30 |
31 | class OperateFactory {
32 |
33 | public static Operate createOperate(String op) {
34 | switch (op) {
35 | case "+":
36 | return new AddOper();
37 | case "*":
38 | return new MultOper();
39 | default:
40 | throw new IllegalArgumentException("not implemented yet");
41 | }
42 | }
43 | }
44 |
45 |
46 |
--------------------------------------------------------------------------------
/code/u009/Client.java:
--------------------------------------------------------------------------------
1 | package u009;
2 |
3 | /**
4 | * Created by HuGuodong on 11/21/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) throws Exception{
9 | IResume r1 = new Resume_deep();
10 | r1.setPersonalInfo("Allen", 23);
11 | r1.setWorkExperience("2010-2020", "AWS");
12 |
13 |
14 | // IResume r2 = (Resume_deep) ((Resume_deep) r1).clone();
15 | // deepCopy
16 | IResume r2 = (Resume_deep) ((Resume_deep) r1).deepCopy();
17 | r2.setWorkExperience("2009-2015", "ShenzhenPingShan hospital");
18 | r1.print();
19 | r2.print();
20 | // Resume{name='Allen', age=23, timeSpan='2010-2020', company='AWS'}
21 | // Resume{name='Allen', age=23, timeSpan='2009-2015', company='ShenzhenPingShan hospital'}
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/u009/IResume.java:
--------------------------------------------------------------------------------
1 | package u009;
2 |
3 | /**
4 | * Created by HuGuodong on 11/21/19.
5 | */
6 | public interface IResume {
7 | void setPersonalInfo(String name, int age);
8 | void setWorkExperience(String timeSpan, String company);
9 | void print();
10 | }
11 |
--------------------------------------------------------------------------------
/code/u009/Resume_deep.java:
--------------------------------------------------------------------------------
1 | package u009;
2 |
3 | /**
4 | * Created by HuGuodong on 11/21/19.
5 | */
6 | public class Resume_deep implements Cloneable, IResume{
7 | private String name;
8 | private int age;
9 |
10 | // workExperience 为引用类型,浅拷贝只复制地址。
11 | // 必须使用深拷贝
12 | private WorkExperience workExperience;
13 |
14 | public Resume_deep(){
15 | this.workExperience = new WorkExperience();
16 | }
17 |
18 | public void setPersonalInfo(String name, int age){
19 | this.name = name;
20 | this.age = age;
21 | }
22 |
23 |
24 | public void setWorkExperience(String timeSpan, String company){
25 | workExperience.setTimeSpan(timeSpan);
26 | workExperience.setCompany(company);
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return "Resume_deep{" +
32 | "name='" + name + '\'' +
33 | ", age=" + age +
34 | ", workExperience=" + workExperience +
35 | '}';
36 | }
37 |
38 | @Override
39 | public Object clone() throws CloneNotSupportedException {
40 | return super.clone();
41 | }
42 |
43 | public Object deepCopy(){
44 | Resume_deep obj = null;
45 | try{
46 | obj = new Resume_deep();
47 | obj.name = this.name;
48 | obj.age = this.age;
49 | obj.workExperience = (WorkExperience) this.workExperience.clone();
50 | }catch (Exception e){
51 | e.printStackTrace();
52 | }
53 |
54 | return obj;
55 |
56 | }
57 |
58 | public void print(){
59 | System.out.println(toString());
60 | }
61 | }
62 | class WorkExperience implements Cloneable{
63 | private String timeSpan;
64 | private String company;
65 | public WorkExperience(){
66 |
67 | }
68 |
69 | public void setTimeSpan(String timeSpan) {
70 | this.timeSpan = timeSpan;
71 | }
72 |
73 | public void setCompany(String company) {
74 | this.company = company;
75 | }
76 |
77 | public String getTimeSpan() {
78 | return timeSpan;
79 | }
80 |
81 | public String getCompany() {
82 | return company;
83 | }
84 |
85 | @Override
86 | public String toString() {
87 | return "WorkExperience{" +
88 | "timeSpan='" + timeSpan + '\'' +
89 | ", company='" + company + '\'' +
90 | '}';
91 | }
92 |
93 | @Override
94 | protected Object clone() throws CloneNotSupportedException {
95 | return super.clone();
96 | }
97 | }
--------------------------------------------------------------------------------
/code/u009/Resume_shallow.java:
--------------------------------------------------------------------------------
1 | package u009;
2 |
3 | /**
4 | * Created by HuGuodong on 11/21/19.
5 | */
6 | public class Resume_shallow implements Cloneable, IResume {
7 | private String name;
8 | private int age;
9 | private String timeSpan;
10 | private String company;
11 | public void setPersonalInfo(String name, int age){
12 | this.name = name;
13 | this.age = age;
14 | }
15 |
16 | public void setWorkExperience(String timeSpan, String company){
17 | this.timeSpan = timeSpan;
18 | this.company = company;
19 | }
20 |
21 | public void print(){
22 | System.out.println(toString());
23 | }
24 |
25 | @Override
26 | public String toString() {
27 | return "Resume{" +
28 | "name='" + name + '\'' +
29 | ", age=" + age +
30 | ", timeSpan='" + timeSpan + '\'' +
31 | ", company='" + company + '\'' +
32 | '}';
33 | }
34 |
35 | @Override
36 | protected Object clone() throws CloneNotSupportedException {
37 | return super.clone();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/code/u010/Client.java:
--------------------------------------------------------------------------------
1 | package u010;
2 |
3 | /**
4 | * Created by HuGuodong on 11/22/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | CrossCompiler iphoneCompiler = new IPhoneCompiler();
10 | iphoneCompiler.compile();
11 |
12 | CrossCompiler androidCompiler = new AandroidCompiler();
13 | androidCompiler.compile();
14 | // IPhoneCompiler collectSource
15 | // IPhoneCompiler compileToTarget
16 | // AandroidCompiler collectSource
17 | // AandroidCompiler compileToTarget
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/code/u010/CrossCompiler.java:
--------------------------------------------------------------------------------
1 | package u010;
2 |
3 | /**
4 | * Created by HuGuodong on 11/22/19.
5 | */
6 | public abstract class CrossCompiler {
7 | public abstract void collectSource();
8 | public abstract void compileToTarget();
9 | public final void compile(){
10 | collectSource();
11 | compileToTarget();
12 | }
13 | }
14 |
15 | class AandroidCompiler extends CrossCompiler{
16 |
17 | @Override
18 | public void collectSource() {
19 | System.out.println("AandroidCompiler collectSource");
20 | }
21 |
22 | @Override
23 | public void compileToTarget() {
24 | System.out.println("AandroidCompiler compileToTarget");
25 | }
26 | }
27 |
28 | class IPhoneCompiler extends CrossCompiler{
29 |
30 | @Override
31 | public void collectSource() {
32 | System.out.println("IPhoneCompiler collectSource");
33 | }
34 |
35 | @Override
36 | public void compileToTarget() {
37 | System.out.println("IPhoneCompiler compileToTarget");
38 | }
39 | }
--------------------------------------------------------------------------------
/code/u012/Client.java:
--------------------------------------------------------------------------------
1 | package u012;
2 |
3 | /**
4 | * Created by HuGuodong on 11/23/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | Fund fund = new Fund("Make Your Rich!");
10 | fund.buy();
11 | fund.sell();
12 | // Fund Buy Operation
13 | // buy stock: GOL
14 | // buy stock: APL
15 | // buy stock: AAL
16 | // buy realstate: WANDA
17 | // buy debt: debt 5% interests per year
18 | // Fund Sell Operation
19 | // sell stock: GOL
20 | // sell stock: APL
21 | // sell stock: AAL
22 | // sell realstate: WANDA
23 | // sell debt: debt 5% interests per year
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/u012/Fund.java:
--------------------------------------------------------------------------------
1 | package u012;
2 |
3 | import java.sql.SQLOutput;
4 |
5 | /**
6 | * Created by HuGuodong on 11/23/19.
7 | */
8 | public class Fund implements IInvestment{
9 | private String fundName;
10 | private Stock stock1;
11 | private Stock stock2;
12 | private Stock stock3;
13 | private RealState realState;
14 | public NationalDebt nationalDebt;
15 | public Fund(String fundName){
16 | this.fundName = fundName;
17 | stock1 = new Stock("GOL");
18 | stock2 = new Stock("APL");
19 | stock3 = new Stock("AAL");
20 | realState = new RealState("WANDA");
21 | nationalDebt = new NationalDebt("debt 5% interests per year");
22 |
23 | }
24 |
25 | @Override
26 | public void buy() {
27 | System.out.println("Fund Buy Operation: " + fundName);
28 | stock1.buy();
29 | stock2.buy();
30 | stock3.buy();
31 | realState.buy();
32 | nationalDebt.buy();
33 | }
34 |
35 | @Override
36 | public void sell() {
37 | System.out.println("Fund Sell Operation");
38 | stock1.sell();
39 | stock2.sell();
40 | stock3.sell();
41 | realState.sell();
42 | nationalDebt.sell();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/code/u012/IInvestment.java:
--------------------------------------------------------------------------------
1 | package u012;
2 |
3 | /**
4 | * Created by HuGuodong on 11/23/19.
5 | */
6 | public interface IInvestment {
7 | void buy();
8 | void sell();
9 | }
10 |
11 | class Stock implements IInvestment{
12 | protected String name;
13 | public Stock(String name){
14 | this.name = name;
15 | }
16 |
17 | @Override
18 | public void buy() {
19 | System.out.println("buy stock: "+ name);
20 | }
21 |
22 | @Override
23 | public void sell() {
24 | System.out.println("sell stock: "+ name);
25 | }
26 | }
27 |
28 | class RealState implements IInvestment{
29 | private String name;
30 | public RealState(String name){
31 | this.name = name;
32 | }
33 | @Override
34 | public void buy() {
35 | System.out.println("buy realstate: "+ name);
36 | }
37 |
38 | @Override
39 | public void sell() {
40 | System.out.println("sell realstate: "+ name);
41 | }
42 | }
43 |
44 | class NationalDebt implements IInvestment{
45 | private String desc;
46 | public NationalDebt(String desc){
47 | this.desc = desc;
48 | }
49 | @Override
50 | public void buy() {
51 | System.out.println("buy debt: "+ desc);
52 | }
53 |
54 | @Override
55 | public void sell() {
56 | System.out.println("sell debt: " + desc);
57 | }
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/code/u013/Client.java:
--------------------------------------------------------------------------------
1 | package u013;
2 |
3 | /**
4 | * Created by HuGuodong on 11/24/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | PersonBuilder thinBuilder = new ThinPersonBuilder();
10 | PersonDirector director = new PersonDirector(thinBuilder);
11 | director.createPerson();
12 |
13 | PersonBuilder fatBuilder = new FatPersonBuilder();
14 | director = new PersonDirector(fatBuilder);
15 | director.createPerson();
16 |
17 | // ThinPersonBuilder: buildHead
18 | // ThinPersonBuilder: buildBody
19 | // ThinPersonBuilder: buildArms
20 | // ThinPersonBuilder: buildLegs
21 | // FatPersonBuilder: buildHead
22 | // FatPersonBuilder: buildBody
23 | // FatPersonBuilder: buildArms
24 | // FatPersonBuilder: buildLegs
25 |
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/code/u013/PersonBuilder.java:
--------------------------------------------------------------------------------
1 | package u013;
2 |
3 | import java.awt.Graphics;
4 |
5 | /**
6 | * Created by HuGuodong on 11/24/19.
7 | */
8 | public abstract class PersonBuilder {
9 |
10 | public abstract void buildHead();
11 |
12 | public abstract void buildBody();
13 |
14 | public abstract void buildArms();
15 |
16 | public abstract void buildLegs();
17 | }
18 |
19 | class ThinPersonBuilder extends PersonBuilder {
20 |
21 | @Override
22 | public void buildHead() {
23 | System.out.printf("%s: %s\n", this.getClass().getSimpleName(), "buildHead");
24 | }
25 |
26 | @Override
27 | public void buildBody() {
28 | System.out.printf("%s: %s\n", this.getClass().getSimpleName(), "buildBody");
29 | }
30 |
31 | @Override
32 | public void buildArms() {
33 | System.out.printf("%s: %s\n", this.getClass().getSimpleName(), "buildArms");
34 | }
35 |
36 | @Override
37 | public void buildLegs() {
38 | System.out.printf("%s: %s\n", this.getClass().getSimpleName(), "buildLegs");
39 | }
40 | }
41 |
42 | class FatPersonBuilder extends PersonBuilder {
43 |
44 | @Override
45 | public void buildHead() {
46 | System.out.printf("%s: %s\n", this.getClass().getSimpleName(), "buildHead");
47 | }
48 |
49 | @Override
50 | public void buildBody() {
51 | System.out.printf("%s: %s\n", this.getClass().getSimpleName(), "buildBody");
52 | }
53 |
54 | @Override
55 | public void buildArms() {
56 | System.out.printf("%s: %s\n", this.getClass().getSimpleName(), "buildArms");
57 | }
58 |
59 | @Override
60 | public void buildLegs() {
61 | System.out.printf("%s: %s\n", this.getClass().getSimpleName(), "buildLegs");
62 | }
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/code/u013/PersonDirector.java:
--------------------------------------------------------------------------------
1 | package u013;
2 |
3 | /**
4 | * Created by HuGuodong on 11/24/19.
5 | */
6 | public class PersonDirector {
7 | private PersonBuilder builder;
8 | public PersonDirector(PersonBuilder builder){
9 | this.builder = builder;
10 | }
11 | public void createPerson(){
12 | builder.buildHead();
13 | builder.buildBody();
14 | builder.buildArms();
15 | builder.buildLegs();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/code/u014/v1/Client.java:
--------------------------------------------------------------------------------
1 | package u014.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 11/24/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | Secretary notifier = new Secretary();
10 |
11 | StockObserver observer1 = new StockObserver("xiaoming", notifier);
12 | StockObserver observer2 = new StockObserver("xiaoqiang", notifier);
13 |
14 | notifier.attach(observer1);
15 | notifier.attach(observer2);
16 |
17 | notifier.action = "Boss is coming";
18 | notifier.notifyObs();
19 | //
20 | // Boss is coming, xiaoming 关闭股票行情,继续工作!
21 | // Boss is coming, xiaoqiang 关闭股票行情,继续工作!
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/u014/v1/Secretary.java:
--------------------------------------------------------------------------------
1 | package u014.v1;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by HuGuodong on 11/24/19.
8 | */
9 | public class Secretary {
10 | private List observers = new ArrayList<>();
11 | public String action;
12 |
13 | public void attach(StockObserver observer){
14 | observers.add(observer);
15 | }
16 |
17 | public void notifyObs(){
18 | observers.forEach(StockObserver::update);
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/code/u014/v1/StockObserver.java:
--------------------------------------------------------------------------------
1 | package u014.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 11/24/19.
5 | */
6 | public class StockObserver {
7 | private String name;
8 | private Secretary sub;
9 |
10 | public StockObserver(String name, Secretary sub){
11 | this.name = name;
12 | this.sub = sub;
13 | }
14 |
15 | public void update(){
16 | System.out.printf("%s, %s 关闭股票行情,继续工作!\n", sub.action, name);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/code/u014/v2/Client.java:
--------------------------------------------------------------------------------
1 | package u014.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/25/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | Secretary sub = new Secretary();
10 |
11 | Observer observer1 = new StockObserver("Ming", sub);
12 | Observer nbaObserver2 = new NBAObserver("Joe", sub);
13 | sub.action = "Boss is coming";
14 |
15 | sub.attach(observer1);
16 | sub.attach(nbaObserver2);
17 | sub.notifyObs();
18 | // Boss is coming, Ming 关闭股票行情,继续工作!
19 | // Boss is coming, Joe 关闭NBA,继续工作!
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/code/u014/v2/NBAObserver.java:
--------------------------------------------------------------------------------
1 | package u014.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/25/19.
5 | */
6 | public class NBAObserver extends Observer {
7 |
8 | public NBAObserver(String name, Secretary sub){
9 | super(name, sub);
10 | }
11 | @Override
12 | public void update() {
13 | System.out.printf("%s, %s 关闭NBA,继续工作!\n", sub.action, name);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/code/u014/v2/Observer.java:
--------------------------------------------------------------------------------
1 | package u014.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/25/19.
5 | */
6 | abstract public class Observer {
7 |
8 | protected String name;
9 | protected Secretary sub;
10 |
11 | public Observer(String name, Secretary sub) {
12 | this.name = name;
13 | this.sub = sub;
14 | }
15 | public abstract void update();
16 | }
17 |
--------------------------------------------------------------------------------
/code/u014/v2/Secretary.java:
--------------------------------------------------------------------------------
1 | package u014.v2;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by HuGuodong on 11/25/19.
8 | */
9 | public class Secretary {
10 | private List observers = new ArrayList<>();
11 |
12 | public String action;
13 |
14 | public void attach(Observer observer){
15 | observers.add(observer);
16 | }
17 |
18 | public void detach(Observer observer){
19 | observers.remove(observer);
20 | }
21 |
22 | public void notifyObs(){
23 | observers.forEach(Observer::update);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/u014/v2/StockObserver.java:
--------------------------------------------------------------------------------
1 | package u014.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/25/19.
5 | */
6 | public class StockObserver extends Observer {
7 | public StockObserver(String name, Secretary sub){
8 | super(name, sub);
9 | }
10 | @Override
11 | public void update() {
12 | System.out.printf("%s, %s 关闭股票行情,继续工作!\n", sub.action, name);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/code/u014/v3/Client.java:
--------------------------------------------------------------------------------
1 | package u014.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 11/25/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | Subject sub = new Secretary();
10 |
11 | Observer observer1 = new StockObserver("Ming", sub);
12 | Observer nbaObserver2 = new NBAObserver("Joe", sub);
13 | sub.setAction("Boss is coming");
14 |
15 | sub.attach(observer1);
16 | sub.attach(nbaObserver2);
17 | sub.detach(observer1);
18 | sub.notifyObs();
19 | // Boss is coming, Joe 关闭NBA,继续工作!
20 |
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/u014/v3/NBAObserver.java:
--------------------------------------------------------------------------------
1 | package u014.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 11/25/19.
5 | */
6 | public class NBAObserver extends Observer {
7 |
8 | public NBAObserver(String name, Subject sub){
9 | super(name, sub);
10 | }
11 | @Override
12 | public void update() {
13 | System.out.printf("%s, %s 关闭NBA,继续工作!\n", sub.getAction(), name);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/code/u014/v3/Observer.java:
--------------------------------------------------------------------------------
1 | package u014.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 11/25/19.
5 | */
6 | abstract public class Observer {
7 |
8 | protected String name;
9 | protected Subject sub;
10 |
11 | public Observer(String name, Subject sub) {
12 | this.name = name;
13 | this.sub = sub;
14 | }
15 | public abstract void update();
16 | }
17 |
--------------------------------------------------------------------------------
/code/u014/v3/Secretary.java:
--------------------------------------------------------------------------------
1 | package u014.v3;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by HuGuodong on 11/25/19.
8 | */
9 | public class Secretary implements Subject{
10 | private List observers = new ArrayList<>();
11 |
12 | public String action;
13 |
14 | public void attach(Observer observer){
15 | observers.add(observer);
16 | }
17 |
18 | public void detach(Observer observer){
19 | observers.remove(observer);
20 | }
21 |
22 | public void notifyObs(){
23 | observers.forEach(Observer::update);
24 | }
25 |
26 | public String getAction(){
27 | return action;
28 | }
29 |
30 | public void setAction(String action){
31 | this.action = action;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/code/u014/v3/StockObserver.java:
--------------------------------------------------------------------------------
1 | package u014.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 11/25/19.
5 | */
6 | public class StockObserver extends Observer {
7 | public StockObserver(String name, Subject sub){
8 | super(name, sub);
9 | }
10 | @Override
11 | public void update() {
12 | System.out.printf("%s, %s 关闭股票行情,继续工作!\n", sub.getAction(), name);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/code/u014/v3/Subject.java:
--------------------------------------------------------------------------------
1 | package u014.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 11/26/19.
5 | */
6 | public interface Subject {
7 | void attach(Observer observer);
8 | void detach(Observer observer);
9 | void notifyObs();
10 | String getAction();
11 | void setAction(String action);
12 | }
13 |
--------------------------------------------------------------------------------
/code/u014/v4/Client.java:
--------------------------------------------------------------------------------
1 | package u014.v4;
2 |
3 | /**
4 | * Created by HuGuodong on 11/26/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | ConcreteSubject subject = new ConcreteSubject();
10 | subject.attach(new ConcreteObserver(subject)); // ConcreteObserver has a reference to a concrete subject
11 | subject.attach(new ConcreteObserver(subject));
12 | subject.setState("update state");
13 | subject.notifyObs();
14 | // update state
15 | // update state
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/code/u014/v4/ConcreteObserver.java:
--------------------------------------------------------------------------------
1 | package u014.v4;
2 |
3 | /**
4 | * Created by HuGuodong on 11/26/19.
5 | */
6 | public class ConcreteObserver implements Observer {
7 | private ConcreteSubject subject;
8 |
9 | public ConcreteObserver(ConcreteSubject subject){
10 | this.subject = subject;
11 | }
12 | @Override
13 | public void update() {
14 | System.out.println(subject.getState());
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/code/u014/v4/ConcreteSubject.java:
--------------------------------------------------------------------------------
1 | package u014.v4;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by HuGuodong on 11/26/19.
8 | */
9 | public class ConcreteSubject implements Subject {
10 | private List observers = new ArrayList<>();
11 | private String state;
12 |
13 | public void setState(String state){
14 | this.state = state;
15 | }
16 | public String getState(){
17 | return state;
18 | }
19 | @Override
20 | public void attach(Observer obs) {
21 | observers.add(obs);
22 | }
23 |
24 | @Override
25 | public void detach(Observer obs) {
26 | observers.remove(obs);
27 | }
28 |
29 | @Override
30 | public void notifyObs() {
31 | observers.forEach(Observer::update);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/code/u014/v4/Observer.java:
--------------------------------------------------------------------------------
1 | package u014.v4;
2 |
3 | /**
4 | * Created by HuGuodong on 11/26/19.
5 | */
6 | public interface Observer {
7 | void update();
8 | }
9 |
--------------------------------------------------------------------------------
/code/u014/v4/Subject.java:
--------------------------------------------------------------------------------
1 | package u014.v4;
2 |
3 | /**
4 | * Created by HuGuodong on 11/26/19.
5 | */
6 | public interface Subject {
7 | void attach(Observer obs);
8 | void detach(Observer obs);
9 | void notifyObs();
10 | }
11 |
--------------------------------------------------------------------------------
/code/u015/v1/Client.java:
--------------------------------------------------------------------------------
1 | package u015.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 11/27/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | User user = new User();
10 | SqlServerUser server = new SqlServerUser();
11 | server.insert(user);
12 | server.getUser(1);
13 | // add a new user.
14 | // find a user.
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/code/u015/v1/User.java:
--------------------------------------------------------------------------------
1 | package u015.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 11/27/19.
5 | */
6 | public class User {
7 | private int id;
8 | private String name;
9 |
10 | public int getId() {
11 | return id;
12 | }
13 |
14 | public void setId(int id) {
15 | this.id = id;
16 | }
17 |
18 | public String getName() {
19 | return name;
20 | }
21 |
22 | public void setName(String name) {
23 | this.name = name;
24 | }
25 |
26 | @Override
27 | public String toString() {
28 | return "User{" +
29 | "id=" + id +
30 | ", name='" + name + '\'' +
31 | '}';
32 | }
33 | }
34 |
35 | class SqlServerUser{
36 | public void insert(User user){
37 | System.out.println("add a new user.");
38 | }
39 |
40 | public User getUser(int id){
41 | System.out.println("find a user.");
42 | return null;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/code/u015/v2/Client.java:
--------------------------------------------------------------------------------
1 | package u015.v2;
2 |
3 | import u015.v1.User;
4 |
5 | /**
6 | * Created by HuGuodong on 11/27/19.
7 | */
8 | public class Client {
9 |
10 | public static void main(String[] args) {
11 | User user = new User();
12 | IFactory factory = new AccessFactory();
13 | IUser u = factory.createUser();
14 | u.insert(user);
15 | u.getUser(1);
16 | // Create AccessFactory -> createUser
17 | // AccessUser insert
18 | // AccessUser getUser
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/code/u015/v2/IFactory.java:
--------------------------------------------------------------------------------
1 | package u015.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/27/19.
5 | */
6 | public interface IFactory {
7 | IUser createUser();
8 | }
9 |
10 | class SqlServerFactory implements IFactory{
11 |
12 | @Override
13 | public IUser createUser() {
14 | System.out.println("Create SqlServerFactory -> createUser");
15 | return new SqlServerUser();
16 | }
17 | }
18 |
19 | class AccessFactory implements IFactory{
20 |
21 | @Override
22 | public IUser createUser() {
23 | System.out.println("Create AccessFactory -> createUser");
24 | return new AccessUser();
25 | }
26 | }
--------------------------------------------------------------------------------
/code/u015/v2/IUser.java:
--------------------------------------------------------------------------------
1 | package u015.v2;
2 |
3 | import u015.v1.User;
4 |
5 | /**
6 | * Created by HuGuodong on 11/27/19.
7 | */
8 | public interface IUser {
9 | void insert(User user);
10 | User getUser(int id);
11 | }
12 |
13 | class SqlServerUser implements IUser{
14 |
15 | @Override
16 | public void insert(User user) {
17 |
18 | }
19 |
20 | @Override
21 | public User getUser(int id) {
22 | return null;
23 | }
24 | }
25 |
26 | class AccessUser implements IUser{
27 |
28 | @Override
29 | public void insert(User user) {
30 | System.out.println("AccessUser insert");
31 | }
32 |
33 | @Override
34 | public User getUser(int id) {
35 | System.out.println("AccessUser getUser");
36 | return null;
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/code/u015/v3/Client.java:
--------------------------------------------------------------------------------
1 | package u015.v3;
2 |
3 | import u015.v1.User;
4 |
5 | /**
6 | * Created by HuGuodong on 11/27/19.
7 | */
8 | public class Client {
9 |
10 | public static void main(String[] args) {
11 | User user = new User();
12 | IFactory factory = new AccessFactory();
13 | IUser u = factory.createUser();
14 | u.insert(user);
15 | u.getUser(1);
16 | // Create AccessFactory -> createUser
17 | // AccessUser insert
18 | // AccessUser getUser
19 |
20 | IDepartment department = factory.createDepartment();
21 | department.getDepartment(1);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/u015/v3/Department.java:
--------------------------------------------------------------------------------
1 | package u015.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 11/27/19.
5 | */
6 | public class Department {
7 | }
8 |
--------------------------------------------------------------------------------
/code/u015/v3/IDepartment.java:
--------------------------------------------------------------------------------
1 | package u015.v3;
2 |
3 | import java.text.DecimalFormat;
4 |
5 | /**
6 | * Created by HuGuodong on 11/27/19.
7 | */
8 | public interface IDepartment {
9 | void insert(Department department);
10 | Department getDepartment(int id);
11 | }
12 |
13 | class SqlServerDepartment implements IDepartment{
14 |
15 | @Override
16 | public void insert(Department department) {
17 |
18 | }
19 |
20 | @Override
21 | public Department getDepartment(int id) {
22 | return null;
23 | }
24 | }
25 |
26 | class AccessDepartment implements IDepartment{
27 |
28 | @Override
29 | public void insert(Department department) {
30 |
31 | }
32 |
33 | @Override
34 | public Department getDepartment(int id) {
35 | return null;
36 | }
37 | }
--------------------------------------------------------------------------------
/code/u015/v3/IFactory.java:
--------------------------------------------------------------------------------
1 | package u015.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 11/27/19.
5 | */
6 | public interface IFactory {
7 | IUser createUser();
8 | IDepartment createDepartment();
9 | }
10 |
11 | class SqlServerFactory implements IFactory {
12 |
13 | @Override
14 | public IUser createUser() {
15 | System.out.println("Create SqlServerFactory -> createUser");
16 | return new SqlServerUser();
17 | }
18 |
19 | @Override
20 | public IDepartment createDepartment() {
21 | return new SqlServerDepartment();
22 | }
23 | }
24 |
25 | class AccessFactory implements IFactory {
26 |
27 | @Override
28 | public IUser createUser() {
29 | System.out.println("Create AccessFactory -> createUser");
30 | return new AccessUser();
31 | }
32 |
33 | @Override
34 | public IDepartment createDepartment() {
35 | return new AccessDepartment();
36 | }
37 | }
--------------------------------------------------------------------------------
/code/u015/v3/IUser.java:
--------------------------------------------------------------------------------
1 | package u015.v3;
2 |
3 | import u015.v1.User;
4 |
5 | /**
6 | * Created by HuGuodong on 11/27/19.
7 | */
8 | public interface IUser {
9 | void insert(User user);
10 | User getUser(int id);
11 | }
12 |
13 | class SqlServerUser implements IUser {
14 |
15 | @Override
16 | public void insert(User user) {
17 |
18 | }
19 |
20 | @Override
21 | public User getUser(int id) {
22 | return null;
23 | }
24 | }
25 |
26 | class AccessUser implements IUser {
27 |
28 | @Override
29 | public void insert(User user) {
30 | System.out.println("AccessUser insert");
31 | }
32 |
33 | @Override
34 | public User getUser(int id) {
35 | System.out.println("AccessUser getUser");
36 | return null;
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/code/u016/v1/Client.java:
--------------------------------------------------------------------------------
1 | package u016.v1;
2 |
3 | import static u016.v1.WriteProgram.HOUR;
4 | import static u016.v1.WriteProgram.workFinished;
5 | import static u016.v1.WriteProgram.writeProgram;
6 |
7 | /**
8 | * Created by HuGuodong on 11/28/19.
9 | */
10 | public class Client {
11 |
12 | public static void main(String[] args) {
13 | HOUR = 10;
14 | writeProgram();
15 | workFinished = true;
16 | HOUR = 22;
17 | writeProgram();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/code/u016/v1/WriteProgram.java:
--------------------------------------------------------------------------------
1 | package u016.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 11/28/19.
5 | */
6 | public class WriteProgram {
7 | public static int HOUR = 0;
8 | public static boolean workFinished = false;
9 | public static void writeProgram(){
10 | if(HOUR<12)
11 | System.out.printf("current time is %d\n", HOUR);
12 | else if(HOUR<13)
13 | System.out.printf("current time is %d\n", HOUR);
14 | else if(HOUR<17)
15 | System.out.printf("current time is %d\n", HOUR);
16 | else {
17 | if(workFinished){
18 | System.out.printf("work finished, current time is %d\n", HOUR);
19 | }else{
20 | System.out.printf("work not finished, current time is %d\n", HOUR);
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/u016/v2/ConcreteStateA.java:
--------------------------------------------------------------------------------
1 | package u016.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/28/19.
5 | */
6 | public class ConcreteStateA extends State {
7 |
8 | @Override
9 | void handle(Context context) {
10 |
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/code/u016/v2/ConcreteStateB.java:
--------------------------------------------------------------------------------
1 | package u016.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/28/19.
5 | */
6 | public class ConcreteStateB extends State {
7 |
8 | @Override
9 | void handle(Context context) {
10 |
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/code/u016/v2/Context.java:
--------------------------------------------------------------------------------
1 | package u016.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/28/19.
5 | */
6 | public class Context {
7 |
8 | private State state;
9 |
10 | public Context(State state) {
11 | this.state = state;
12 | }
13 |
14 | public void setState(State state) {
15 | this.state = state;
16 | System.out.println("state updates");
17 | }
18 |
19 | public State getState() {
20 | return this.state;
21 | }
22 |
23 | public void request() {
24 | state.handle(this);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/code/u016/v2/State.java:
--------------------------------------------------------------------------------
1 | package u016.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/28/19.
5 | */
6 | public abstract class State {
7 | abstract void handle(Context context);
8 | }
9 |
--------------------------------------------------------------------------------
/code/u016/v3/Client.java:
--------------------------------------------------------------------------------
1 | package u016.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 11/28/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | Work w = new Work();
10 | w.setHour(14);
11 | w.writeProgram();
12 | w.setHour(11);
13 | w.writeProgram();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/code/u016/v3/ForenoonState.java:
--------------------------------------------------------------------------------
1 | package u016.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 11/28/19.
5 | */
6 | public class ForenoonState extends State {
7 |
8 | @Override
9 | void writeProgram(Work w) {
10 | if(w.getHour()<12){
11 | // w.setState(new ForenoonState());
12 | System.out.printf("current time is %d, I feel grate!\n",w.getHour());
13 | }else{
14 | w.setState(new NoonState());
15 | w.writeProgram();
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/code/u016/v3/NoonState.java:
--------------------------------------------------------------------------------
1 | package u016.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 11/28/19.
5 | */
6 | public class NoonState extends State {
7 |
8 | @Override
9 | void writeProgram(Work w) {
10 | w.setState(new ForenoonState());
11 | System.out.println("noon!");
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/code/u016/v3/State.java:
--------------------------------------------------------------------------------
1 | package u016.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 11/28/19.
5 | */
6 | public abstract class State {
7 | abstract void writeProgram(Work w);
8 | }
9 |
--------------------------------------------------------------------------------
/code/u016/v3/Work.java:
--------------------------------------------------------------------------------
1 | package u016.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 11/28/19.
5 | */
6 | public class Work {
7 |
8 | private int hour;
9 | private boolean taskFinished;
10 |
11 |
12 | private State current;
13 |
14 | public Work() {
15 | this.current = new ForenoonState();
16 | }
17 |
18 | public void setState(State s) {
19 | current = s;
20 | }
21 |
22 | public void writeProgram() {
23 | current.writeProgram(this);
24 | }
25 |
26 | public void setHour(int hour) {
27 | this.hour = hour;
28 | }
29 |
30 | public int getHour() {
31 | return hour;
32 | }
33 |
34 | public boolean isTaskFinished() {
35 | return taskFinished;
36 | }
37 |
38 | public void setTaskFinished(boolean taskFinished) {
39 | this.taskFinished = taskFinished;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/code/u017/v1/Adaptee.java:
--------------------------------------------------------------------------------
1 | package u017.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 11/29/19.
5 | */
6 | public class Adaptee {
7 | public void specificRequest(){
8 | System.out.println("Specific Request");
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/code/u017/v1/Adapter.java:
--------------------------------------------------------------------------------
1 | package u017.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 11/29/19.
5 | */
6 | public class Adapter extends Target {
7 | private Adaptee adaptee = new Adaptee();
8 | @Override
9 | void request() {
10 | System.out.println("Adapter.");
11 | adaptee.specificRequest();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/code/u017/v1/Client.java:
--------------------------------------------------------------------------------
1 | package u017.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 11/29/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | Adapter adapter = new Adapter();
10 | adapter.request();
11 | // Adapter.
12 | // Specific Request
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/code/u017/v1/Target.java:
--------------------------------------------------------------------------------
1 | package u017.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 11/29/19.
5 | */
6 | public abstract class Target {
7 | abstract void request();
8 | }
9 |
--------------------------------------------------------------------------------
/code/u017/v2/TestInputStream.java:
--------------------------------------------------------------------------------
1 | package u017.v2;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.InputStream;
5 | import java.io.InputStreamReader;
6 |
7 | /**
8 | * Created by HuGuodong on 11/29/19.
9 | */
10 | public class TestInputStream {
11 |
12 | public static void main(String[] args) {
13 | // System.in inputstream
14 | // BufferedReader <--> character
15 | // InputStream <--> bytes stream
16 | // InputStreamReader: Adapter (bytes stream to character)
17 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/code/u018/v1/Client.java:
--------------------------------------------------------------------------------
1 | package u018.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 11/30/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | GameRole role = new GameRole(100,100,100); // current state
10 | GameRole backRole = new GameRole(role);
11 | role.showState();
12 | role.die(); // state changes
13 | role.showState();
14 |
15 | role.loadState(backRole); // recover state
16 | role.showState();
17 |
18 | // GameRole{life=100, atk=100, def=100}
19 | // GameRole{life=0, atk=0, def=0}
20 | // GameRole{life=100, atk=100, def=100}
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/u018/v1/GameRole.java:
--------------------------------------------------------------------------------
1 | package u018.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 11/30/19.
5 | */
6 | public class GameRole {
7 | private int life;
8 | private int atk;
9 | private int def;
10 |
11 | public void showState(){
12 | System.out.println(toString());
13 | }
14 |
15 |
16 | @Override
17 | public String toString() {
18 | return "GameRole{" +
19 | "life=" + life +
20 | ", atk=" + atk +
21 | ", def=" + def +
22 | '}';
23 | }
24 |
25 | public void die(){
26 | this.life = 0;
27 | this.atk = 0;
28 | this.def = 0;
29 | }
30 |
31 | public void loadState(GameRole role){
32 | this.life = role.life;
33 | this.atk = role.atk;
34 | this.def = role.def;
35 | }
36 |
37 | public GameRole(GameRole role){
38 | this.life = role.life;
39 | this.atk = role.atk;
40 | this.def = role.def;
41 | }
42 |
43 | public GameRole(int life, int atk, int def) {
44 | this.life = life;
45 | this.atk = atk;
46 | this.def = def;
47 | }
48 |
49 | public int getLife() {
50 | return life;
51 | }
52 |
53 | public void setLife(int life) {
54 | this.life = life;
55 | }
56 |
57 | public int getAtk() {
58 | return atk;
59 | }
60 |
61 | public void setAtk(int atk) {
62 | this.atk = atk;
63 | }
64 |
65 | public int getDef() {
66 | return def;
67 | }
68 |
69 | public void setDef(int def) {
70 | this.def = def;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/code/u018/v2/Caretaker.java:
--------------------------------------------------------------------------------
1 | package u018.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/30/19.
5 | */
6 | public class Caretaker {
7 | private Memento memento;
8 |
9 | public Memento getMemento() {
10 | return memento;
11 | }
12 |
13 | public void setMemento(Memento memento) {
14 | this.memento = memento;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/code/u018/v2/Client.java:
--------------------------------------------------------------------------------
1 | package u018.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/30/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | // create memento
10 | // recover state
11 | Originator o = new Originator();
12 | o.setState("init state");
13 | o.show();
14 |
15 | // save memento
16 | Caretaker c = new Caretaker();
17 | // set
18 | c.setMemento(o.createMemento()); // createMemento
19 |
20 | o.setState("state changed");
21 | o.show();
22 |
23 | // recover state by c.get memento
24 | o.recover(c.getMemento());
25 | o.show();
26 |
27 | // Originator{state='init state'}
28 | // Originator{state='state changed'}
29 | // using memento to recover state
30 | // Originator{state='init state'}
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/code/u018/v2/Memento.java:
--------------------------------------------------------------------------------
1 | package u018.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/30/19.
5 | */
6 | public class Memento {
7 |
8 | private String state;
9 |
10 | public Memento(String state) {
11 | this.state = state;
12 | }
13 |
14 | public String getState() {
15 | return state;
16 | }
17 |
18 | public void setState(String state) {
19 | this.state = state;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/code/u018/v2/Originator.java:
--------------------------------------------------------------------------------
1 | package u018.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 11/30/19.
5 | */
6 | public class Originator {
7 | private String state;
8 | public Memento createMemento(){
9 | return new Memento(state);
10 | }
11 |
12 | public void show(){
13 | System.out.println(toString());
14 | }
15 |
16 |
17 | public void recover(Memento memento){
18 | System.out.println("using memento to recover state");
19 | state = memento.getState();
20 | }
21 |
22 | public String getState() {
23 | return state;
24 | }
25 |
26 | public void setState(String state) {
27 | this.state = state;
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | return "Originator{" +
33 | "state='" + state + '\'' +
34 | '}';
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/code/u019/v1/Client.java:
--------------------------------------------------------------------------------
1 | package u019.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/1/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 |
10 | // build root
11 | Composite root = new Composite("root");
12 |
13 | // add two leaves
14 | root.add(new Leaf("leaf-a"));
15 | root.add(new Leaf("leaf-b"));
16 |
17 | // build a branch
18 | Composite branch1 = new Composite("branch-1");
19 | branch1.add(new Leaf("leaf-c"));
20 | branch1.add(new Leaf("leaf-d"));
21 |
22 | // add branch to root
23 | root.add(branch1);
24 |
25 | // build a branch
26 | Composite branch2 = new Composite("branch-2");
27 | branch2.add(new Leaf("leaf-e"));
28 | branch2.add(new Leaf("leaf-f"));
29 |
30 | // add a branch to a branch
31 | branch1.add(branch2);
32 |
33 | // display hierarchies
34 | root.display(0);
35 |
36 | // root
37 | // --leaf-a
38 | // --leaf-b
39 | // --branch-1
40 | // ----leaf-c
41 | // ----leaf-d
42 | // ----branch-2
43 | // ------leaf-e
44 | // ------leaf-f
45 |
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/code/u019/v1/Component.java:
--------------------------------------------------------------------------------
1 | package u019.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/1/19.
5 | */
6 | public abstract class Component {
7 | protected String name;
8 | public Component(String name){
9 | this.name = name;
10 | }
11 |
12 | public abstract void add(Component c);
13 | public abstract void remove(Component c);
14 | public abstract void display(int depth);
15 | }
16 |
--------------------------------------------------------------------------------
/code/u019/v1/Composite.java:
--------------------------------------------------------------------------------
1 | package u019.v1;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by HuGuodong on 12/1/19.
8 | */
9 | public class Composite extends Component {
10 |
11 | List children = new ArrayList<>();
12 |
13 | public Composite(String name) {
14 | super(name);
15 | }
16 |
17 | @Override
18 | public void add(Component c) {
19 | children.add(c);
20 | }
21 |
22 | @Override
23 | public void remove(Component c) {
24 | children.remove(c);
25 | }
26 |
27 | @Override
28 | public void display(int depth) {
29 | System.out.println("-".repeat(depth) + name);
30 | children.forEach(component -> {
31 | component.display(depth + 2);
32 | });
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/code/u019/v1/Leaf.java:
--------------------------------------------------------------------------------
1 | package u019.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/1/19.
5 | */
6 | public class Leaf extends Component {
7 |
8 | public Leaf(String name) {
9 | super(name);
10 | }
11 |
12 | @Override
13 | public void add(Component c) {
14 | throw new UnsupportedOperationException("Can not add to a leaf.");
15 | }
16 |
17 | @Override
18 | public void remove(Component c) {
19 | throw new UnsupportedOperationException("Can not remove from leaf.");
20 | }
21 |
22 | @Override
23 | public void display(int depth) {
24 | System.out.println("-".repeat(depth) + name);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/code/u020/TestIterator.java:
--------------------------------------------------------------------------------
1 | package u020;
2 |
3 | import java.util.Arrays;
4 | import java.util.Iterator;
5 | import java.util.List;
6 |
7 | /**
8 | * Created by HuGuodong on 12/2/19.
9 | */
10 | public class TestIterator {
11 |
12 | public static void main(String[] args) {
13 | List songs = Arrays.asList("南方姑娘", "曾经的你", "Lydia");
14 | Iterator playListIterator = songs.iterator();
15 | while (playListIterator.hasNext())
16 | System.out.println(playListIterator.next());
17 | // 南方姑娘
18 | // 曾经的你
19 | // Lydia
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/code/u021/bestpractice/DemoSingleton.java:
--------------------------------------------------------------------------------
1 | package u021.bestpractice;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by HuGuodong on 12/4/19.
7 | */
8 | public class DemoSingleton implements Serializable {
9 |
10 | private static final long serialVersionUID = 1L;
11 |
12 | private DemoSingleton() {}
13 |
14 | private static class DemoSingletonHolder {
15 |
16 | private static final DemoSingleton instance = new DemoSingleton();
17 | }
18 |
19 | public static DemoSingleton getInstance() {
20 | return DemoSingletonHolder.instance;
21 | }
22 |
23 | protected Object readResolve() {
24 | return getInstance();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/code/u021/bill/BillPughSingleton.java:
--------------------------------------------------------------------------------
1 | package u021.bill;
2 |
3 | /**
4 | * Created by HuGuodong on 12/3/19.
5 | */
6 | public class BillPughSingleton {
7 |
8 | public static int NUM = 10;
9 |
10 | private BillPughSingleton() {
11 | System.out.println("create singleton.");
12 | }
13 |
14 | private static class LazyHolder {
15 |
16 | static {
17 | System.out.println("create class LazyHolder...");
18 | }
19 |
20 | private static final BillPughSingleton instance = new BillPughSingleton();
21 | }
22 |
23 | public static BillPughSingleton getInstance() {
24 | return LazyHolder.instance;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/code/u021/bill/BillPughSingletonTest.java:
--------------------------------------------------------------------------------
1 | package u021.bill;
2 |
3 | /**
4 | * Created by HuGuodong on 12/3/19.
5 | */
6 | public class BillPughSingletonTest {
7 |
8 | public static void main(String[] args) {
9 | // output 10, instance does not create.
10 | // System.out.println(BillPughSingleton.NUM);
11 | //
12 | // System.out.println(BillPughSingleton.getInstance());
13 | // System.out.println(BillPughSingleton.getInstance());
14 | // create singleton.
15 | // u021.bill.BillPughSingleton@1134affc
16 | // u021.bill.BillPughSingleton@1134affc
17 |
18 | for (int i = 0; i < 100; i++) {
19 | Runnable r = ()->{
20 | BillPughSingleton.getInstance(); // only create one time.
21 | };
22 | var t = new Thread(r);
23 | t.start();
24 | }
25 |
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/code/u021/eager/Client.java:
--------------------------------------------------------------------------------
1 | package u021.eager;
2 |
3 | import u021.eager.EagerSingleton;
4 |
5 | /**
6 | * Created by HuGuodong on 12/3/19.
7 | */
8 | public class Client {
9 |
10 | public static void main(String[] args) {
11 | EagerSingleton instance = EagerSingleton.getInstance();
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/code/u021/eager/EagerSingleton.java:
--------------------------------------------------------------------------------
1 | package u021.eager;
2 |
3 | /**
4 | * Created by HuGuodong on 12/3/19.
5 | */
6 | public class EagerSingleton {
7 |
8 | private static volatile EagerSingleton instance = new EagerSingleton();
9 |
10 | public static EagerSingleton getInstance() {
11 | return instance;
12 | }
13 |
14 | private EagerSingleton() {
15 | System.out.printf("%s Instance Created!\n", this.getClass().getSimpleName());
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/code/u021/lazy/LazySingleton.java:
--------------------------------------------------------------------------------
1 | package u021.lazy;
2 |
3 | /**
4 | * Created by HuGuodong on 12/3/19.
5 | */
6 | public final class LazySingleton {
7 |
8 | private static volatile LazySingleton instance = null;
9 |
10 | private LazySingleton() {
11 | // System.out.println("instance address: " + instance);
12 | }
13 |
14 | public static LazySingleton getInstance() {
15 | if (instance == null) {
16 | synchronized (LazySingleton.class) { // lock
17 | instance = new LazySingleton();
18 | // multi thread will generate two or more instances.
19 | System.out.println("instance address: " + instance);
20 | }
21 | }
22 | // System.out.println("instance address: " + instance);
23 | return instance;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/u021/lazy/LazySingletonClient.java:
--------------------------------------------------------------------------------
1 | package u021.lazy;
2 |
3 | /**
4 | * Created by HuGuodong on 12/3/19.
5 | */
6 | public class LazySingletonClient {
7 |
8 | public static void main(String[] args) {
9 | // The first time instance is requested. i.e. address is u021.lazy.LazySingleton@2812cbfa
10 | LazySingleton instance = LazySingleton.getInstance();
11 | for (int i = 0; i < 100; i++) {
12 | Runnable r = ()->{
13 | // print address to check whether LazySingleton works well in multi thread environment.
14 | // because instance was created in the beginning of the main function, so
15 | // console will show the same address of instance.
16 | // u021.lazy.LazySingleton@2812cbfa ...
17 | LazySingleton.getInstance();
18 | };
19 | var t = new Thread(r);
20 | t.start();
21 | }
22 | // output
23 | // instance address: u021.lazy.LazySingleton@2812cbfa
24 | // instance address: u021.lazy.LazySingleton@2812cbfa
25 | // instance address: u021.lazy.LazySingleton@2812cbfa
26 | // instance address: u021.lazy.LazySingleton@2812cbfa
27 | // instance address: u021.lazy.LazySingleton@2812cbfa
28 |
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/code/u021/lazy/LazySingletonMultiThreadClient.java:
--------------------------------------------------------------------------------
1 | package u021.lazy;
2 |
3 | /**
4 | * Created by HuGuodong on 12/3/19.
5 | */
6 | public class LazySingletonMultiThreadClient {
7 |
8 | public static void main(String[] args) {
9 |
10 | for (int i = 0; i < 100; i++) {
11 | Runnable r = ()->{
12 | LazySingleton.getInstance();
13 | };
14 | var t = new Thread(r);
15 | t.start();
16 | }
17 | // multi thread will generate two or more instances.
18 | // if your result is different from mine, run several times to verify yours.
19 | // instance address: u021.lazy.LazySingleton@45e8464f
20 | // instance address: u021.lazy.LazySingleton@40567879
21 | // instance address: u021.lazy.LazySingleton@41e066da
22 | // instance address: u021.lazy.LazySingleton@7eb2f567
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/u021/lazy/LazySingletonV2.java:
--------------------------------------------------------------------------------
1 | package u021.lazy;
2 |
3 | /**
4 | * Created by HuGuodong on 12/3/19.
5 | */
6 | public class LazySingletonV2 {
7 |
8 | private static LazySingletonV2 instance = null;
9 |
10 | private LazySingletonV2() {}
11 |
12 | public static LazySingletonV2 getInstance() {
13 | if (instance == null) {
14 | synchronized (LazySingletonV2.class) {
15 | if (instance == null) {
16 | instance = new LazySingletonV2();
17 | // multi thread will generate two or more instances.
18 | System.out.println("instance address: " + instance);
19 | }
20 | }
21 | }
22 | return instance;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/u021/lazy/LazySingletonV2Client.java:
--------------------------------------------------------------------------------
1 | package u021.lazy;
2 |
3 | /**
4 | * Created by HuGuodong on 12/3/19.
5 | */
6 | public class LazySingletonV2Client {
7 |
8 | public static void main(String[] args) {
9 |
10 | for (int i = 0; i < 100; i++) {
11 | Runnable r = ()->{
12 | // print address to check whether LazySingletonV2 works well in multi thread environment.
13 | LazySingletonV2.getInstance();
14 | };
15 | var t = new Thread(r);
16 | t.start();
17 | }
18 | // output
19 | // instance address: u021.lazy.LazySingletonV2@1f3dd942
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/code/u021/seri/Client.java:
--------------------------------------------------------------------------------
1 | package u021.seri;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.FileOutputStream;
5 | import java.io.ObjectInput;
6 | import java.io.ObjectInputStream;
7 | import java.io.ObjectOutput;
8 | import java.io.ObjectOutputStream;
9 |
10 | /**
11 | * Created by HuGuodong on 12/3/19.
12 | */
13 | public class Client {
14 | static DemoSingleton instance = DemoSingleton.getInstance();
15 | public static void main(String[] args) throws Exception{
16 | // ObjectOutput output = new ObjectOutputStream(new FileOutputStream("filename.ser"));
17 | // output.writeObject(instance);
18 | // output.close();
19 | // instance.setI(20);
20 | ObjectInput input = new ObjectInputStream(new FileInputStream("filename.ser"));
21 | DemoSingleton instanceTwo = (DemoSingleton)input.readObject();
22 | input.close();
23 |
24 | System.out.println(instance.getI());
25 | System.out.println(instanceTwo.getI());
26 | System.out.println(instance);
27 | System.out.println(instanceTwo);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/code/u021/seri/DemoSingleton.java:
--------------------------------------------------------------------------------
1 | package u021.seri;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by HuGuodong on 12/3/19.
7 | */
8 | public class DemoSingleton implements Serializable {
9 |
10 | private static final long serialVersionUID = 1L;
11 |
12 | private static volatile DemoSingleton instance = null;
13 |
14 | public static DemoSingleton getInstance() {
15 | if (instance == null) {
16 | instance = new DemoSingleton();
17 | }
18 | return instance;
19 | }
20 |
21 | private int i = 10;
22 |
23 | // return existing instance.
24 | // protected Object readResolve(){
25 | // return instance;
26 | // }
27 |
28 | public int getI() {
29 | return i;
30 | }
31 |
32 | public void setI(int i) {
33 | this.i = i;
34 | }
35 |
36 | private int j = 100;
37 | private int k = 200;
38 | }
39 |
--------------------------------------------------------------------------------
/code/u021/st/StaticBlockSingleton.java:
--------------------------------------------------------------------------------
1 | package u021.st;
2 |
3 | /**
4 | * Created by HuGuodong on 12/3/19.
5 | */
6 | public class StaticBlockSingleton {
7 |
8 | private static final StaticBlockSingleton instance;
9 |
10 | static {
11 | instance = new StaticBlockSingleton();
12 | }
13 |
14 | private StaticBlockSingleton() {}
15 |
16 | public static StaticBlockSingleton getInstance() {
17 | return instance;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/code/u021/st/StaticBlockSingletonTest.java:
--------------------------------------------------------------------------------
1 | package u021.st;
2 |
3 | /**
4 | * Created by HuGuodong on 12/3/19.
5 | */
6 | public class StaticBlockSingletonTest {
7 |
8 |
9 | public static void main(String[] args) {
10 | var ins = StaticBlockSingleton.getInstance();
11 | System.out.println(ins);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/code/u021/v1/FooV1.java:
--------------------------------------------------------------------------------
1 | package u021.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/3/19.
5 | */
6 | public class FooV1 {
7 |
8 | private static FooV1 instance;
9 |
10 | private FooV1() {}
11 |
12 | // correct but expensive in multi threaded version
13 | public static synchronized FooV1 getInstance() {
14 | if (instance == null) {
15 | instance = new FooV1();
16 | }
17 | return instance;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/code/u021/v1/FooV2.java:
--------------------------------------------------------------------------------
1 | package u021.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/3/19.
5 | */
6 | public class FooV2 {
7 |
8 | private static FooV2 instance;
9 |
10 | private FooV2() {}
11 |
12 | public static FooV2 getInstance2() {
13 | if (instance == null) {
14 | synchronized (FooV2.class) {
15 | if (instance == null) {
16 | instance = new FooV2();
17 | }
18 | }
19 | }
20 | return instance;
21 | }
22 |
23 | public static void main(String[] args) {
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/code/u021/v1/TestPerformance.java:
--------------------------------------------------------------------------------
1 | package u021.v1;
2 |
3 | import util._Stopwatch;
4 |
5 | /**
6 | * Created by HuGuodong on 12/3/19.
7 | */
8 | public class TestPerformance {
9 |
10 | public static void main(String[] args) {
11 | int NUM = 100000;
12 | _Stopwatch time = new _Stopwatch();
13 | for (int i = 0; i < NUM; i++) {
14 | Runnable r = () -> {
15 | FooV1.getInstance();
16 | };
17 | var t = new Thread(r);
18 | t.start();
19 | }
20 | System.out.println(time.elapsedTime());
21 | for (int i = 0; i < NUM; i++) {
22 | Runnable r = () -> {
23 | FooV2.getInstance2();
24 | };
25 | var t = new Thread(r);
26 | t.start();
27 | }
28 | System.out.println(time.elapsedTime());
29 | // 4.307s sync a method is slower
30 | // 4.119s faster
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/code/u022/v1/Shape.java:
--------------------------------------------------------------------------------
1 | package u022.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/5/19.
5 | */
6 | public abstract class Shape {
7 | public abstract void draw();
8 | }
9 |
10 | class Rectangle extends Shape{
11 |
12 | @Override
13 | public void draw() {
14 |
15 | }
16 | }
17 |
18 | class BlueRectangle extends Rectangle{
19 |
20 | @Override
21 | public void draw() {
22 |
23 | }
24 | }
25 |
26 | class RedRectangle extends Rectangle{
27 |
28 | @Override
29 | public void draw() {
30 |
31 | }
32 | }
33 |
34 | class Circle extends Shape{
35 |
36 | @Override
37 | public void draw() {
38 |
39 | }
40 | }
41 |
42 | class BlueCircle extends Circle{
43 |
44 | @Override
45 | public void draw() {
46 |
47 | }
48 | }
49 |
50 | class RedCircle extends Circle{
51 |
52 | @Override
53 | public void draw() {
54 |
55 | }
56 | }
--------------------------------------------------------------------------------
/code/u022/v2/Client.java:
--------------------------------------------------------------------------------
1 | package u022.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 12/5/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | Color red = new Red();
10 | Shape rec = new Rectangle(red);
11 | rec.draw();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/code/u022/v2/Color.java:
--------------------------------------------------------------------------------
1 | package u022.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 12/5/19.
5 | */
6 | public abstract class Color {
7 | abstract void draw();
8 | }
9 |
10 | class Red extends Color{
11 |
12 | @Override
13 | void draw() {
14 | System.out.print("Red");
15 | }
16 | }
17 |
18 |
19 | class Blue extends Color{
20 |
21 | @Override
22 | void draw() {
23 | System.out.print("Blue");
24 | }
25 | }
--------------------------------------------------------------------------------
/code/u022/v2/Shape.java:
--------------------------------------------------------------------------------
1 | package u022.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 12/5/19.
5 | */
6 | public abstract class Shape {
7 | protected Color color;
8 | abstract void draw();
9 | public Shape(Color color){
10 | this.color = color;
11 | }
12 |
13 | }
14 |
15 | class Rectangle extends Shape{
16 | public Rectangle(Color color){
17 | super(color);
18 | }
19 |
20 | @Override
21 | void draw() {
22 | color.draw();
23 | System.out.println("Rectangle");
24 | }
25 | }
--------------------------------------------------------------------------------
/code/u022/v3/Client.java:
--------------------------------------------------------------------------------
1 | package u022.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 12/5/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | FileDownloaderImplementor provider = new LinuxFileDownloaderImplProvider();
10 | FileDownloaderAbstraction downloader = new FileDownloaderAbstractionImpl(provider);
11 | Object o = downloader.download("xxx");
12 | downloader.store(o);
13 | // linux download file.
14 | // linux store file.
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/code/u022/v3/FileDownloaderAbstraction.java:
--------------------------------------------------------------------------------
1 | package u022.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 12/5/19.
5 | */
6 | public interface FileDownloaderAbstraction {
7 | // v1
8 | Object download(String path);
9 | boolean store(Object object);
10 |
11 | // v2 assume we add a new method at abstraction level, i.e. delete
12 | boolean delete(Object object);
13 | }
14 |
--------------------------------------------------------------------------------
/code/u022/v3/FileDownloaderAbstractionImpl.java:
--------------------------------------------------------------------------------
1 | package u022.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 12/5/19.
5 | */
6 | public class FileDownloaderAbstractionImpl implements FileDownloaderAbstraction {
7 |
8 | private FileDownloaderImplementor provider = null;
9 |
10 | public FileDownloaderAbstractionImpl(FileDownloaderImplementor provider){
11 | this.provider = provider;
12 | }
13 |
14 | @Override
15 | public Object download(String path) {
16 | return provider.downloadFile(path);
17 | }
18 |
19 | @Override
20 | public boolean store(Object object) {
21 | return provider.storeFile(object);
22 | }
23 |
24 | // v2 : add delete, it does not affect provider
25 | @Override
26 | public boolean delete(Object object) {
27 | return false;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/code/u022/v3/FileDownloaderImplementor.java:
--------------------------------------------------------------------------------
1 | package u022.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 12/5/19.
5 | */
6 | public interface FileDownloaderImplementor {
7 | Object downloadFile(String path);
8 | boolean storeFile(Object object);
9 | // v3: we add deleteFile method, it does not affect FileAbstraction layer, so client will not bu affected.
10 | boolean deleteFile(Object object);
11 | }
12 |
--------------------------------------------------------------------------------
/code/u022/v3/LinuxFileDownloaderImplProvider.java:
--------------------------------------------------------------------------------
1 | package u022.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 12/5/19.
5 | */
6 | public class LinuxFileDownloaderImplProvider implements FileDownloaderImplementor {
7 |
8 | @Override
9 | public Object downloadFile(String path) {
10 | System.out.println("linux download file.");
11 | return new Object();
12 | }
13 |
14 | @Override
15 | public boolean storeFile(Object object) {
16 | System.out.println("linux store file.");
17 | return true;
18 | }
19 |
20 | @Override
21 | public boolean deleteFile(Object object) {
22 | return false;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/u022/v3/WindowsFileDownloaderImplProvider.java:
--------------------------------------------------------------------------------
1 | package u022.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 12/5/19.
5 | */
6 | public class WindowsFileDownloaderImplProvider implements FileDownloaderImplementor {
7 |
8 | @Override
9 | public Object downloadFile(String path) {
10 | System.out.println("windows download file.");
11 | return new Object();
12 | }
13 |
14 | @Override
15 | public boolean storeFile(Object object) {
16 | System.out.println("windows store file.");
17 | return true;
18 | }
19 |
20 | @Override
21 | public boolean deleteFile(Object object) {
22 | return false;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/u023/v1/Client.java:
--------------------------------------------------------------------------------
1 | package u023.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | Receiver receiver = new Receiver();
10 | Command command = new ConcreteCommand(receiver);
11 | Invoker invoker = new Invoker();
12 | invoker.setCommand(command);
13 | invoker.executeCommand();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/code/u023/v1/Command.java:
--------------------------------------------------------------------------------
1 | package u023.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public interface Command {
7 | public void execute();
8 | }
9 |
--------------------------------------------------------------------------------
/code/u023/v1/ConcreteCommand.java:
--------------------------------------------------------------------------------
1 | package u023.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public class ConcreteCommand implements Command {
7 | private Receiver receiver;
8 | public ConcreteCommand(Receiver receiver){
9 | this.receiver = receiver;
10 | }
11 | @Override
12 | public void execute() {
13 | receiver.doAction();
14 | System.out.println("execute concrete command");
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/code/u023/v1/Invoker.java:
--------------------------------------------------------------------------------
1 | package u023.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public class Invoker {
7 | private Command command;
8 |
9 |
10 | /**
11 | * set concrete command
12 | * @param command
13 | */
14 | public void setCommand(Command command){
15 | this.command = command;
16 | }
17 |
18 | /**
19 | * execute concrete command
20 | */
21 | public void executeCommand(){
22 | command.execute();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/u023/v1/Receiver.java:
--------------------------------------------------------------------------------
1 | package u023.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public class Receiver {
7 |
8 |
9 | public void doAction(){
10 | System.out.println("do action");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/code/u023/v2/Client.java:
--------------------------------------------------------------------------------
1 | package u023.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 |
10 | Light light = new Light(); // receiver
11 |
12 | RemoteController controller = new RemoteController(); // invoker
13 |
14 | controller.setCommand(new TurnOnLightCommand(light));
15 | controller.buttonPressed();
16 |
17 | controller.setCommand(new TurnOffLightCommand(light)); // set new command
18 | controller.buttonPressed();
19 | // output
20 | // TurnOnLightCommand
21 | // light is on
22 | // TurnOffLightCommand
23 | // light is off
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/u023/v2/ICommand.java:
--------------------------------------------------------------------------------
1 | package u023.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public interface ICommand {
7 | void execute();
8 | }
9 |
--------------------------------------------------------------------------------
/code/u023/v2/Light.java:
--------------------------------------------------------------------------------
1 | package u023.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public class Light {
7 | public void turnOn(){
8 | System.out.println("light is on");
9 | }
10 |
11 | public void turnOff(){
12 | System.out.println("light is off");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/code/u023/v2/RemoteController.java:
--------------------------------------------------------------------------------
1 | package u023.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public class RemoteController {
7 | private ICommand command;
8 | public void setCommand(ICommand c){
9 | command = c;
10 | }
11 |
12 | public void buttonPressed(){
13 | command.execute();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/code/u023/v2/TurnOffLightCommand.java:
--------------------------------------------------------------------------------
1 | package u023.v2;
2 |
3 |
4 | /**
5 | * Created by HuGuodong on 12/7/19.
6 | */
7 | public class TurnOffLightCommand implements ICommand {
8 |
9 | private Light light;
10 |
11 | public TurnOffLightCommand(Light light) {
12 | this.light = light;
13 | }
14 |
15 | @Override
16 | public void execute() {
17 | System.out.println("TurnOffLightCommand");
18 | light.turnOff();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/code/u023/v2/TurnOnLightCommand.java:
--------------------------------------------------------------------------------
1 | package u023.v2;
2 |
3 |
4 | /**
5 | * Created by HuGuodong on 12/7/19.
6 | */
7 | public class TurnOnLightCommand implements ICommand {
8 |
9 | private Light light;
10 |
11 | public TurnOnLightCommand(Light light) {
12 | this.light = light;
13 | }
14 |
15 | @Override
16 | public void execute() {
17 | System.out.println("TurnOnLightCommand");
18 | light.turnOn();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/code/u024/v1/APPLY_TYPE.java:
--------------------------------------------------------------------------------
1 | package u024.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public enum APPLY_TYPE {
7 | VOCATION,
8 | SALARY_RAISE
9 | }
10 |
--------------------------------------------------------------------------------
/code/u024/v1/Apply.java:
--------------------------------------------------------------------------------
1 | package u024.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public class Apply {
7 |
8 | private APPLY_TYPE applyType;
9 | private String applyContent;
10 | private int applyNum;
11 |
12 | public Apply(APPLY_TYPE applyType, String applyContent, int applyNum) {
13 | this.applyType = applyType;
14 | this.applyContent = applyContent;
15 | this.applyNum = applyNum;
16 | }
17 |
18 | public APPLY_TYPE getApplyType() {
19 | return applyType;
20 | }
21 |
22 | public String getApplyContent() {
23 | return applyContent;
24 | }
25 |
26 | public int getApplyNum() {
27 | return applyNum;
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | return "Apply{" +
33 | "applyType='" + applyType + '\'' +
34 | ", applyContent='" + applyContent + '\'' +
35 | ", applyNum='" + applyNum + '\'' +
36 | '}';
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/code/u024/v1/Client.java:
--------------------------------------------------------------------------------
1 | package u024.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | Apply apply = new Apply(APPLY_TYPE.VOCATION, "vocation 10 days", 10);
10 | Manager manager = new Manager("BOB", LEVEL.MANAGER);
11 | Manager supervisor = new Manager("JOE", LEVEL.SUPERVISOR);
12 | Manager director = new Manager("BOSS", LEVEL.DIRECTOR);
13 | manager.dealApply(apply);
14 | supervisor.dealApply(apply);
15 | director.dealApply(apply);
16 | // I can not deal with it.
17 | // I can not deal with it.
18 | // Apply{applyType='VOCATION', applyContent='vocation 10 days', applyNum='10'} approved!
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/code/u024/v1/LEVEL.java:
--------------------------------------------------------------------------------
1 | package u024.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public enum LEVEL {
7 | MANAGER,
8 | SUPERVISOR,
9 | DIRECTOR
10 | }
11 |
--------------------------------------------------------------------------------
/code/u024/v1/Manager.java:
--------------------------------------------------------------------------------
1 | package u024.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/7/19.
5 | */
6 | public class Manager {
7 |
8 | private String name;
9 | private LEVEL level;
10 |
11 | public Manager(String name, LEVEL level) {
12 | this.name = name;
13 | this.level = level;
14 | }
15 |
16 | public void dealApply(Apply apply) {
17 | if (level == LEVEL.MANAGER) {
18 | if (apply.getApplyType() == APPLY_TYPE.VOCATION
19 | && apply.getApplyNum() <= 2) {
20 | System.out.println(apply.toString() + " approved!");
21 | } else {
22 | System.out.println("I can not deal with it.");
23 | }
24 | } else if (level == LEVEL.SUPERVISOR) {
25 | if (apply.getApplyType() == APPLY_TYPE.VOCATION
26 | && apply.getApplyNum() <= 5) {
27 | System.out.println(apply.toString() + " approved!");
28 | } else {
29 | System.out.println("I can not deal with it.");
30 | }
31 | } else if (level == LEVEL.DIRECTOR) {
32 | if (apply.getApplyType() == APPLY_TYPE.VOCATION
33 | && apply.getApplyNum() <= 10) {
34 | System.out.println(apply.toString() + " approved!");
35 | } else {
36 | System.out.println("I can not deal with it.");
37 | }
38 | } else {
39 | throw new RuntimeException("legal apply");
40 | }
41 |
42 |
43 |
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/code/u024/v2/Client.java:
--------------------------------------------------------------------------------
1 | package u024.v2;
2 |
3 | import u024.v1.APPLY_TYPE;
4 | import u024.v1.Apply;
5 |
6 | /**
7 | * Created by HuGuodong on 12/7/19.
8 | */
9 | public class Client {
10 |
11 | public static void main(String[] args) {
12 | Apply apply = new Apply(APPLY_TYPE.VOCATION,"vocation 20 days", 20);
13 |
14 | Manager wang = new CommonManager("Wang");
15 | Manager boss = new GeneralManager("BOB");
16 | wang.setSuperior(boss);
17 |
18 | wang.HandleApplication(apply);//APPLY NOT PASS.
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/code/u024/v2/CommonManager.java:
--------------------------------------------------------------------------------
1 | package u024.v2;
2 |
3 | import u024.v1.APPLY_TYPE;
4 | import u024.v1.Apply;
5 |
6 | /**
7 | * Created by HuGuodong on 12/7/19.
8 | */
9 | public class CommonManager extends Manager {
10 |
11 | public CommonManager(String name){
12 | super(name);
13 | }
14 |
15 | @Override
16 | public void HandleApplication(Apply apply) {
17 | if(apply.getApplyType()== APPLY_TYPE.VOCATION && apply.getApplyNum()<=2){
18 | System.out.println(apply +" is approved!");
19 | }else{
20 | if(superior!=null){
21 | superior.HandleApplication(apply);
22 | }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/u024/v2/GeneralManager.java:
--------------------------------------------------------------------------------
1 | package u024.v2;
2 |
3 | import u024.v1.APPLY_TYPE;
4 | import u024.v1.Apply;
5 |
6 | /**
7 | * Created by HuGuodong on 12/7/19.
8 | */
9 | public class GeneralManager extends Manager {
10 |
11 | public GeneralManager(String name) {
12 | super(name);
13 | }
14 |
15 | @Override
16 | public void HandleApplication(Apply apply) {
17 | if(apply.getApplyType()== APPLY_TYPE.VOCATION && apply.getApplyNum()<=10){
18 | System.out.println(apply +" is approved!");
19 | }else if(apply.getApplyType()==APPLY_TYPE.SALARY_RAISE && apply.getApplyNum()<=500){
20 | System.out.println(apply +" is approved!");
21 | }else{
22 | System.out.println("APPLY NOT PASS.");
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/u024/v2/Manager.java:
--------------------------------------------------------------------------------
1 | package u024.v2;
2 |
3 | import u024.v1.Apply;
4 |
5 | /**
6 | * Created by HuGuodong on 12/7/19.
7 | */
8 | public abstract class Manager {
9 | protected String name;
10 | protected Manager superior;
11 |
12 | public Manager(String name){
13 | this.name = name;
14 | }
15 |
16 | public void setSuperior(Manager superior){
17 | this.superior = superior;
18 | }
19 |
20 | public abstract void HandleApplication(Apply apply);
21 |
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/code/u025/ChatRoom.java:
--------------------------------------------------------------------------------
1 | package u025;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import u023.v2.ICommand;
6 |
7 | /**
8 | * Concrete Mediator
9 | * Created by HuGuodong on 12/8/19.
10 | */
11 | public class ChatRoom implements IChatRoom {
12 |
13 | private Map userMap = new HashMap<>();
14 |
15 | @Override
16 | public void sendMessage(String msg, String userid) {
17 | User user = userMap.get(userid);
18 | user.receive(msg);
19 | }
20 |
21 | @Override
22 | public void addUser(User user) {
23 | userMap.put(user.getId(), user);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/code/u025/ChatUser.java:
--------------------------------------------------------------------------------
1 | package u025;
2 |
3 | /**
4 | * Concrete Colleague
5 | * Created by HuGuodong on 12/8/19.
6 | */
7 | public class ChatUser extends User {
8 |
9 | public ChatUser(IChatRoom room, String userId, String name) {
10 | super(room, userId, name);
11 | }
12 |
13 | @Override
14 | public void send(String msg, String toUserId) {
15 | System.out.printf("%s send message: %s\n", name, msg);
16 | mediator.sendMessage(msg, toUserId);
17 | }
18 |
19 | @Override
20 | public void receive(String msg) {
21 | System.out.println(name + " received: " + msg);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/u025/Client.java:
--------------------------------------------------------------------------------
1 | package u025;
2 |
3 | /**
4 | * Created by HuGuodong on 12/8/19.
5 | */
6 | public class Client {
7 |
8 | public static void main(String[] args) {
9 | IChatRoom room = new ChatRoom();
10 | User chatUser1 = new ChatUser(room, "1", "Bob");
11 | User chatUser2 = new ChatUser(room, "2", "Kevin");
12 | User chatUser3 = new ChatUser(room, "3", "Joe");
13 |
14 | room.addUser(chatUser1);
15 | room.addUser(chatUser2);
16 | room.addUser(chatUser3);
17 |
18 | chatUser1.send("Hello Kevin", "2");
19 | chatUser2.send("今天去哪吃呀?","1");
20 | // Bob send message: Hello Kevin
21 | // Kevin received: Hello Kevin
22 | // Kevin send message: 今天去哪吃呀?
23 | // Bob received: 今天去哪吃呀?
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/code/u025/IChatRoom.java:
--------------------------------------------------------------------------------
1 | package u025;
2 |
3 | /**
4 | * Abstract Mediator
5 | * Created by HuGuodong on 12/8/19.
6 | */
7 | public interface IChatRoom {
8 | void sendMessage(String msg, String userid);
9 | void addUser(User user);
10 | }
11 |
--------------------------------------------------------------------------------
/code/u025/User.java:
--------------------------------------------------------------------------------
1 | package u025;
2 |
3 | /**
4 | * Abstract Colleague
5 | * Created by HuGuodong on 12/8/19.
6 | */
7 | public abstract class User {
8 | protected String id;
9 | protected String name;
10 | protected IChatRoom mediator;
11 |
12 | public User(IChatRoom mediator, String id, String name){
13 | this.mediator = mediator;
14 | this.id = id;
15 | this.name = name;
16 | }
17 |
18 | public abstract void send(String msg, String toUserId);
19 |
20 | public abstract void receive(String msg);
21 |
22 | public String getId() {
23 | return id;
24 | }
25 |
26 | public String getName() {
27 | return name;
28 | }
29 |
30 | public IChatRoom getMediator() {
31 | return mediator;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/code/u026/v1/WebSite.java:
--------------------------------------------------------------------------------
1 | package u026.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/9/19.
5 | */
6 | public class WebSite {
7 | private String name;
8 | public WebSite(String name){
9 | this.name = name;
10 | }
11 | public void use(){
12 | System.out.println("网站分类:"+ name);
13 | }
14 |
15 | public static void main(String[] args) {
16 | WebSite s1 = new WebSite("产品展示");
17 | s1.use();
18 | WebSite s2 = new WebSite("博客");
19 | s2.use();
20 | }
21 | }
22 |
23 |
24 |
--------------------------------------------------------------------------------
/code/u027/Context.java:
--------------------------------------------------------------------------------
1 | package u027;
2 |
3 |
4 | import java.util.ArrayList;
5 | import java.util.Collection;
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 | import java.util.function.Function;
10 | import java.util.function.Predicate;
11 | import java.util.stream.Collectors;
12 | import java.util.stream.Stream;
13 |
14 | class Context {
15 |
16 | private static Map> tables = new HashMap<>();
17 |
18 | static {
19 | List list = new ArrayList<>();
20 | list.add(new Row("John", "Doe"));
21 | list.add(new Row("Jan", "Kowalski"));
22 | list.add(new Row("Dominic", "Doom"));
23 |
24 | tables.put("people", list);
25 | }
26 |
27 | private String table;
28 | private String column;
29 |
30 | /**
31 | * Index of column to be shown in result. Calculated in {@link #setColumnMapper()}
32 | */
33 | private int colIndex = -1;
34 |
35 | /**
36 | * Default setup, used for clearing the context for next queries. See {@link Context#clear()}
37 | */
38 | private static final Predicate matchAnyString = s -> s.length() > 0;
39 | private static final Function> matchAllColumns = Stream::of;
40 | /**
41 | * Varies based on setup in subclasses of {@link Expression}
42 | */
43 | private Predicate whereFilter = matchAnyString;
44 | private Function> columnMapper = matchAllColumns;
45 |
46 | void setColumn(String column) {
47 | this.column = column;
48 | setColumnMapper();
49 | }
50 |
51 | void setTable(String table) {
52 | this.table = table;
53 | }
54 |
55 | void setFilter(Predicate filter) {
56 | whereFilter = filter;
57 | }
58 |
59 | /**
60 | * Clears the context to defaults. No filters, match all columns.
61 | */
62 | void clear() {
63 | column = "";
64 | columnMapper = matchAllColumns;
65 | whereFilter = matchAnyString;
66 | }
67 |
68 | List search() {
69 |
70 | List result = tables.entrySet()
71 | .stream()
72 | .filter(entry -> entry.getKey().equalsIgnoreCase(table))
73 | .flatMap(entry -> Stream.of(entry.getValue()))
74 | .flatMap(Collection::stream)
75 | .map(Row::toString)
76 | .flatMap(columnMapper)
77 | .filter(whereFilter)
78 | .collect(Collectors.toList());
79 |
80 | clear();
81 |
82 | return result;
83 | }
84 |
85 | /**
86 | * Sets column mapper based on {@link #column} attribute. Note: If column is unknown, will remain
87 | * to look for all columns.
88 | */
89 | private void setColumnMapper() {
90 | switch (column) {
91 | case "*":
92 | colIndex = -1;
93 | break;
94 | case "name":
95 | colIndex = 0;
96 | break;
97 | case "surname":
98 | colIndex = 1;
99 | break;
100 | }
101 | if (colIndex != -1) {
102 | columnMapper = s -> Stream.of(s.split(" ")[colIndex]);
103 | }
104 | }
105 | }
--------------------------------------------------------------------------------
/code/u027/Expression.java:
--------------------------------------------------------------------------------
1 | package u027;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by HuGuodong on 12/10/19.
7 | */
8 | interface Expression {
9 |
10 | List interpret(Context ctx);
11 | }
--------------------------------------------------------------------------------
/code/u027/From.java:
--------------------------------------------------------------------------------
1 | package u027;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by HuGuodong on 12/10/19.
7 | */
8 | class From implements Expression {
9 |
10 | private String table;
11 | private Where where;
12 |
13 | From(String table) {
14 | this.table = table;
15 | }
16 |
17 | From(String table, Where where) {
18 | this.table = table;
19 | this.where = where;
20 | }
21 |
22 | @Override
23 | public List interpret(Context ctx) {
24 | ctx.setTable(table);
25 | if (where == null) {
26 | return ctx.search();
27 | }
28 | return where.interpret(ctx);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/code/u027/InterpreterDemo.java:
--------------------------------------------------------------------------------
1 | package u027;
2 |
3 | import java.util.List;
4 |
5 | public class InterpreterDemo {
6 |
7 | public static void main(String[] args) {
8 |
9 | Expression query = new Select("name", new From("people"));
10 | Context ctx = new Context();
11 | List result = query.interpret(ctx);
12 | System.out.println(result);
13 |
14 | Expression query2 = new Select("*", new From("people"));
15 | List result2 = query2.interpret(ctx);
16 | System.out.println(result2);
17 |
18 | Expression query3 = new Select("name",
19 | new From("people", new Where(name -> name.toLowerCase().startsWith("j"))));
20 | List result3 = query3.interpret(ctx);
21 | System.out.println(result3);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/u027/Row.java:
--------------------------------------------------------------------------------
1 | package u027;
2 |
3 | /**
4 | * Created by HuGuodong on 12/10/19.
5 | */
6 | class Row {
7 |
8 | private String name;
9 | private String surname;
10 |
11 | Row(String name, String surname) {
12 | this.name = name;
13 | this.surname = surname;
14 | }
15 |
16 | @Override
17 | public String toString() {
18 | return name + " " + surname;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/code/u027/Select.java:
--------------------------------------------------------------------------------
1 | package u027;
2 |
3 | import java.util.List;
4 |
5 | class Select implements Expression {
6 |
7 | private String column;
8 | private From from;
9 |
10 | Select(String column, From from) {
11 | this.column = column;
12 | this.from = from;
13 | }
14 |
15 | @Override
16 | public List interpret(Context ctx) {
17 | ctx.setColumn(column);
18 | return from.interpret(ctx);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/code/u027/Where.java:
--------------------------------------------------------------------------------
1 | package u027;
2 |
3 | /**
4 | * Created by HuGuodong on 12/10/19.
5 | */
6 |
7 | import java.util.List;
8 | import java.util.function.Predicate;
9 |
10 | class Where implements Expression {
11 |
12 | private Predicate filter;
13 |
14 | Where(Predicate filter) {
15 | this.filter = filter;
16 | }
17 |
18 | @Override
19 | public List interpret(Context ctx) {
20 | ctx.setFilter(filter);
21 | return ctx.search();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/code/u028/v1/Person.java:
--------------------------------------------------------------------------------
1 | package u028.v1;
2 |
3 | /**
4 | * Created by HuGuodong on 12/10/19.
5 | */
6 | class Person {
7 |
8 | public static void main(String[] args) {
9 | System.out.println("男人成功时,背后多半有一个伟大的女人。");
10 | System.out.println("女人成功时,背后大多又一个不成功的男人。");
11 | System.out.println("男人失败时,闷头喝酒,谁也不用劝。");
12 | System.out.println("女人失败时,泪眼汪汪,谁也劝不了。");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/code/u028/v2/Client.java:
--------------------------------------------------------------------------------
1 | package u028.v2;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by HuGuodong on 12/10/19.
8 | */
9 | class Client {
10 | private static final String SUCCESS ="success";
11 | private static final String FAIL ="fail";
12 |
13 | public static void main(String[] args) {
14 | List persons = new ArrayList<>();
15 | Person man1 = new Man(SUCCESS);
16 | persons.add(man1);
17 | Person woman1 = new Woman(FAIL);
18 | persons.add(woman1);
19 | persons.forEach(p->{p.getConclusion();});
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/code/u028/v2/Man.java:
--------------------------------------------------------------------------------
1 | package u028.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 12/10/19.
5 | */
6 | public class Man extends Person {
7 |
8 | public Man(String action) {
9 | super(action);
10 | }
11 |
12 | @Override
13 | public void getConclusion() {
14 | if (action.equals("success")) {
15 | System.out.printf("%s %s 时,背后多半有一个伟大的女人\n", getClass().getSimpleName(), action);
16 | } else if (action.equals("fail")) {
17 | System.out.printf("%s %s 时,闷头喝闷酒,谁也不用劝。\n", getClass().getSimpleName(), action);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/code/u028/v2/Person.java:
--------------------------------------------------------------------------------
1 | package u028.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 12/10/19.
5 | */
6 | abstract class Person {
7 | protected String action;
8 | public Person(String action){
9 | this.action = action;
10 | }
11 |
12 | public String getAction() {
13 | return action;
14 | }
15 |
16 | public void setAction(String action) {
17 | this.action = action;
18 | }
19 | public abstract void getConclusion();
20 | }
21 |
--------------------------------------------------------------------------------
/code/u028/v2/Woman.java:
--------------------------------------------------------------------------------
1 | package u028.v2;
2 |
3 | /**
4 | * Created by HuGuodong on 12/10/19.
5 | */
6 | public class Woman extends Person {
7 |
8 | public Woman(String action) {
9 | super(action);
10 | }
11 |
12 | @Override
13 | public void getConclusion() {
14 | if (action.equals("succeed")) {
15 | System.out.printf("%s %s 时,背后大多又一个不成功的男人。\n", getClass().getSimpleName(), action);
16 | } else if (action.equals("fail")) {
17 | System.out.printf("%s %s 时,泪眼汪汪,谁也劝不了。\n", getClass().getSimpleName(), action);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/code/u028/v3/Action.java:
--------------------------------------------------------------------------------
1 | package u028.v3;
2 |
3 | /**
4 | * State
5 | * Created by HuGuodong on 12/10/19.
6 | */
7 | abstract public class Action {
8 | public abstract void getManConclusion(Man concreteElementA);
9 | public abstract void getWomanConclusion(Woman concreteElementB);
10 | }
11 |
--------------------------------------------------------------------------------
/code/u028/v3/Client.java:
--------------------------------------------------------------------------------
1 | package u028.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 12/10/19.
5 | */
6 | class Client {
7 |
8 | public static void main(String[] args) {
9 | ObjectStructure o = new ObjectStructure();
10 | o.add(new Man());
11 | o.add(new Woman());
12 |
13 | Action success = new Success();// concrete visitor
14 | o.display(success);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/code/u028/v3/Man.java:
--------------------------------------------------------------------------------
1 | package u028.v3;
2 |
3 | import u013.PersonDirector;
4 |
5 | /**
6 | * Created by HuGuodong on 12/10/19.
7 | */
8 | public class Man extends Person {
9 |
10 | @Override
11 | public void accept(Action visitor) {
12 | visitor.getManConclusion(this);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/code/u028/v3/ObjectStructure.java:
--------------------------------------------------------------------------------
1 | package u028.v3;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by HuGuodong on 12/10/19.
8 | */
9 | public class ObjectStructure {
10 | private List elements = new ArrayList<>();
11 |
12 | public void add(Person p){
13 | elements.add(p);
14 | }
15 |
16 | public void remove(Person p){
17 | elements.remove(p);
18 | }
19 |
20 | public void display(Action visitor){
21 | for(Person p : elements){
22 | p.accept(visitor);
23 | }
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/code/u028/v3/Person.java:
--------------------------------------------------------------------------------
1 | package u028.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 12/10/19.
5 | */
6 | abstract public class Person {
7 | public abstract void accept(Action visitor);
8 | }
9 |
--------------------------------------------------------------------------------
/code/u028/v3/Success.java:
--------------------------------------------------------------------------------
1 | package u028.v3;
2 |
3 | /**
4 | * Concrete State
5 | * Created by HuGuodong on 12/10/19.
6 | */
7 | public class Success extends Action {
8 |
9 | @Override
10 | public void getManConclusion(Man concreteElementA) {
11 | System.out.printf("%s %s 时,背后大多有一个成功的女人。\n", concreteElementA.getClass().getSimpleName(), getClass().getSimpleName());
12 | }
13 |
14 | @Override
15 | public void getWomanConclusion(Woman concreteElementB) {
16 | System.out.printf("%s %s 时,背后大多又一个不成功的男人。\n", concreteElementB.getClass().getSimpleName(), getClass().getSimpleName());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/code/u028/v3/Woman.java:
--------------------------------------------------------------------------------
1 | package u028.v3;
2 |
3 | /**
4 | * Created by HuGuodong on 12/10/19.
5 | */
6 | public class Woman extends Person {
7 |
8 | /**
9 | * accept 状态
10 | * @param visitor
11 | */
12 | @Override
13 | public void accept(Action visitor) {
14 | visitor.getWomanConclusion(this);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/code/u028/visitor/Client.java:
--------------------------------------------------------------------------------
1 | package u028.visitor;
2 |
3 | /**
4 | * Created by HuGuodong on 12/10/19.
5 | */
6 | class Client {
7 |
8 | public static void main(String[] args) {
9 | ObjectStructure o = new ObjectStructure();
10 | o.add(new ConcreteElementA());
11 | o.add(new ConcreteElementB());
12 |
13 | Visitor v = new ConcreteVisitorA();
14 | o.accept(v);
15 | // visit concrete a
16 | // visit concrete b
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/code/u028/visitor/ConcreteElementA.java:
--------------------------------------------------------------------------------
1 | package u028.visitor;
2 |
3 |
4 | /**
5 | * Created by HuGuodong on 12/10/19.
6 | */
7 | class ConcreteElementA extends Element {
8 |
9 | @Override
10 | void accept(Visitor v) {
11 | v.visitConcreteElementA(this);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/code/u028/visitor/ConcreteElementB.java:
--------------------------------------------------------------------------------
1 | package u028.visitor;
2 |
3 | import java.util.Vector;
4 |
5 | /**
6 | * Created by HuGuodong on 12/10/19.
7 | */
8 | class ConcreteElementB extends Element {
9 |
10 | @Override
11 | void accept(Visitor v) {
12 | v.visitConcreteElementB(this);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/code/u028/visitor/ConcreteVisitorA.java:
--------------------------------------------------------------------------------
1 | package u028.visitor;
2 |
3 | /**
4 | * Created by HuGuodong on 12/10/19.
5 | */
6 | public class ConcreteVisitorA extends Visitor {
7 |
8 | @Override
9 | void visitConcreteElementA(ConcreteElementA a) {
10 | System.out.println("visit concrete a");
11 | }
12 |
13 | @Override
14 | void visitConcreteElementB(ConcreteElementB b) {
15 | System.out.println("visit concrete b");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/code/u028/visitor/Element.java:
--------------------------------------------------------------------------------
1 | package u028.visitor;
2 |
3 | import java.util.Vector;
4 |
5 | /**
6 | * Created by HuGuodong on 12/10/19.
7 | */
8 | abstract public class Element {
9 | abstract void accept(Visitor v);
10 | }
11 |
--------------------------------------------------------------------------------
/code/u028/visitor/ObjectStructure.java:
--------------------------------------------------------------------------------
1 | package u028.visitor;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by HuGuodong on 12/10/19.
8 | */
9 | class ObjectStructure {
10 |
11 | private List elements = new ArrayList<>();
12 |
13 | public void add(Element e) {
14 | elements.add(e);
15 | }
16 |
17 | public void remove(Element e) {
18 | elements.remove(e);
19 | }
20 |
21 | public void accept(Visitor v) {
22 | elements.forEach(e -> e.accept(v));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/u028/visitor/Visitor.java:
--------------------------------------------------------------------------------
1 | package u028.visitor;
2 |
3 | /**
4 | * Created by HuGuodong on 12/10/19.
5 | */
6 | abstract public class Visitor {
7 | abstract void visitConcreteElementA(ConcreteElementA a);
8 | abstract void visitConcreteElementB(ConcreteElementB b);
9 | }
10 |
--------------------------------------------------------------------------------
/code/util/_Stopwatch.java:
--------------------------------------------------------------------------------
1 | package util;
2 |
3 | /**
4 | * Created by HuGuodong on 2019/8/6.
5 | */
6 |
7 | public class _Stopwatch {
8 |
9 | private long start;
10 |
11 | public _Stopwatch() {
12 | start = System.currentTimeMillis();
13 | }
14 |
15 | public double elapsedTime() {
16 | long now = System.currentTimeMillis();
17 | long begin = start;
18 | start = now;
19 | return (now - begin) / 1000.0;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/filename.ser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdhucoder/DesignPattern/0611d81a924ea6ca7ad904c957133e64c1cc6eec/filename.ser
--------------------------------------------------------------------------------
/incompleteideas/013_ReplayAttack.md:
--------------------------------------------------------------------------------
1 |
2 | # 重放攻击
3 |
4 | ## Replay Attacks
5 |
6 | 重放攻击(Replay Attacks)又称重播攻击、回放攻击,
7 | 是指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,
8 | 主要用于身份认证过程,破坏认证的正确性。重放攻击可以由发起者,
9 | 也可以由拦截并重发该数据的敌方进行。攻击者利用网络监听或者其他方式盗取认证凭据,
10 | 之后再把它重新发给认证服务器。重放攻击在任何网络通过程中都可能发生,是计算机世界黑客常用的攻击方式之一
11 |
12 |
13 | ## 重放攻击防止方式有三种
14 |
15 | ### 1、加时间戳
16 |
17 | 客户端与服务端有时间差,例如60s内的都算有效。那么黑客可以60s以内进行重放攻击,就有效。
18 |
19 | ### 2、时间戳+nonce(随机数)
20 |
21 | 每次请求成功后,保存nonce,例如放在redis和数据库中,再次请求如果nonce相同,则为重放攻击。
22 |
23 | ### 3、基于record的方案,就是你说的保存token
24 |
25 | 把每次请求保存在数据库中,接收到新请求后,校验是否存在,如果存在,则请求非法。也可以与1结合时间戳只保存60s以内的数据。
26 |
27 | ### 参考
28 |
29 | [baike](https://baike.baidu.com/item/%E9%87%8D%E6%94%BE%E6%94%BB%E5%87%BB)
30 | [tencent](https://cloud.tencent.com/document/product/214/1526)
31 | [juejin](https://juejin.im/post/5ad43b86f265da239236cedc)
--------------------------------------------------------------------------------
/pdf/DDD 101 — The 5-Minute Tour - The Coding Matrix - Medium.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdhucoder/DesignPattern/0611d81a924ea6ca7ad904c957133e64c1cc6eec/pdf/DDD 101 — The 5-Minute Tour - The Coding Matrix - Medium.pdf
--------------------------------------------------------------------------------
/pdf/The_Pragmatic_Programmer_YourJourneytoMastery_20thAnniversaryEdition(2019).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdhucoder/DesignPattern/0611d81a924ea6ca7ad904c957133e64c1cc6eec/pdf/The_Pragmatic_Programmer_YourJourneytoMastery_20thAnniversaryEdition(2019).pdf
--------------------------------------------------------------------------------
/template.md:
--------------------------------------------------------------------------------
1 |
2 | # Title
3 |
4 | ## 定义
5 |
6 | ## 类图
7 |
8 | ## 用例
9 |
10 | ## 实际应用
11 |
12 | ## 注意
13 |
14 | ## 参考
--------------------------------------------------------------------------------