# DesignPattern
**Repository Path**: Bemied/design-pattern
## Basic Information
- **Project Name**: DesignPattern
- **Description**: 设计模式学习过程代码与总结
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-12-31
- **Last Updated**: 2021-12-31
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
---
typora-root-url: ./
---
# DesignPattern_Study-Test
## 1. AbstractFactory(抽象工厂模式)
### Java版本
1.section1:这个示例最重要的是学习它的抽象思路,总共需要创建三个产品:黑人、白人、黄种人;共有两个产品系列:男人、女人。所以需要两个具体工厂:男人工厂,女人工厂。个人认为,如果将抽象交换,按照男人和女人来分,男人分黑人男人、白人男人、黄种人男人,也是可行的。所以这个示例中,将哪个选择为产品系列都可以。
2.section2:这个示例是最基础的抽象工厂模式的Java实现。
3.sample01:这个示例当中,使用XML指定使用哪个具体工厂类,这样就完全不用在代码中出现具体指定的类,增加了灵活性。
### C++版本 -- VS2013
1.AbstractFactory_1:这个示例是最基础的抽象工厂模式的C++实现。将各个类分散到各个文件当中。
2.AbstractFactory_2:也算是基础的抽象工厂模式的实现,但是编程风格非常好,另外通过一个enum枚举需要的具体工厂。值得学习。
3.AbstractFactory_3:这个示例是最基础的抽象工厂模式的C++实现。将各个类整合到一个文件中。
## 2.Builder模式(建造者模式、创建者模式)
### Java版本
1.sample01:这个示例是很典型的Builder模式,其中KFCWaiter是Builder模式中的Director。示例很好的展示了Builder如何通过固定的流程(流程由Director确定)创建不同的对象的。
2.section3:不太能明白示例这样做的好处,但这样确实应该算是一个Builder模式的应用,没有特别搞清楚思路。
### C++版本
1.Builder_1:最基础的Builder模式的实现,没有什么好说的。
2.Builder_2:也算是最基础的Builder模式的应用,编程风格还不错,其他没有什么。
## 3.Factory_method模式(工厂方法模式)
### Java版本
1.section1:这个示例使用模板和反射的方法,改进工厂方法模式。类图如下:
2.section2:一个使用模板和反射的方法,改进工厂方法模式的基础框架。
3.section3:section1的一种扩展,将工厂方法缩小为简单工厂模式。主要是去掉section1中的抽象类,在工厂方法之前增加static关键字(**简单工厂模式中的创建方法都是要做成static的,就如这个例子中一样!**)。简单工厂模式结构简单,但是扩展困难。
4.section4:这个是标准的工厂方法模式的例子,有几个具体的产品,就要有几个对应的具体工厂类。
*5.section5:使用工厂方法模式替代单例模式。对于这个示例,学习一下编程方法即可,不用具体使用,单例用单例就行了,这里替代没有必要!*
6.section6:对简单工厂模式的一个扩展(当然也可以对工厂方法模式进行扩展)。使用缓存保存创建的产品对象,这样产品消费完毕后,如果再次创建,就直接返回缓存的产品对象即可。
7.sample01:一个比较标准的工厂方法模式,并且进行扩展:使用XML指定使用哪个具体工厂类,使用Java语言的反射特性新建一个产品类对象。
### C++版本
1.FactoryMethod_1:一个最基本的工厂方法模式的实现,与《设计模式》书上的图例一样,但是没有体现出“具体产品与具体工厂一一对应”的关系,只有一个具体产品,一个具体工厂。其他的思路没有问题,可以借鉴。
2.FactoryMethod_2:与FactoryMethod_1相同,不过将所有代码集中到一个文件当中。
3.FactoryMethod_3:自己修改,将整个工厂方法模式集中到一个文件当中,体现了“具体产品与具体工厂一一对应”的关系。
4.FactoryMethod_4:一个标准的工厂方法模式,编程风格不错,值得借鉴。(如果只看一个C++的示例,推荐这个版本。)
## 4.Prototype模式(原型模式)
### Java版本
1.sample01:一个基本的使用Java编写的原型模式,使用浅拷贝的方式实现clone方法,最后通过对象的地址验证浅拷贝。使用Java实现的原型模式所有的具体的原型类必须从Cloneable接口派生出来。
2.sample02:一个改进的使用Java编写的原型模式,通过序列化的方式实现clone方法的深拷贝。*序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作。*
3.section1:一个基本的用Java实现的原型模式,通过接口对克隆之后的对象进行修改。
4.section2:一个使用Java实现的原型模式的基本框架。
5.section5:使用Java编写的深度拷贝的示例,采用与sample02不同的实现方法。
6.原型管理器:一个使用Java实现的改进的原型模式的示例,引入原型管理器对原型进行管理,客户端通过原型管理器创建一个新的对象。
7.相似对象的复制:一个使用Java实现的基本的原型模式的示例,通过接口,对克隆之后的对象进行修改,达到快速构建相似对象的目标。
### C++版本
1.Prototype_1:一个改进的原型模式,实现了一个原型管理器。此外,由于在具体原型类中没有成员变量,所以具体的原型类中没有实现拷贝构造函数。(如果在具体原型类中有成员变量,具体的原型类中最好要实现一个拷贝构造函数,以便在实现clone方法时,调用这个拷贝构造函数为成员变量的赋值)。
2.Prototype_2:一个比较标准的C++实现的原型模式。唯一的遗憾是只有一个具体原型类。但是实际上也可以接受,因为原型模式的精髓并不是有多个具体的原型类,而是通过具体的原型类的对象,可以快速实现创建类的对象。
## 5.Singleton模式(单例模式)
### Java版本
1.section1:一个典型的单例模式的示例,采用饿汉方方式实现(声明即初始化)。
2.section2:单例模式的扩展,提供固定数量的对象。
3.section3:一个典型的单例模式的框架,使用饿汉方式实现。
4.section4:一个典型的单例模式的框架,使用懒汉方式实现。
5.sample:一个典型的单例模式的示例,采用懒汉方式实现(第一次使用时初始化),使用双重检查锁定(Double check locking)技术实现线程安全的单例模式。
6.sample01:使用 Initialization Demand Holder (IoDH) 技术实现的单例模式,据说IoDH技术结合了懒汉方式和饿汉方式的优点,既可以按需申请空间,也可以实现线程安全。
### C++版本
1.Singleton_1:一个典型的单例模式的实现。
2.Singleton_2:并不是典型的单例模式的实现,但是也是一个有效的实现。应该算是使用C++的另一种实现方式。(这种方式个人认为没有问题,应该也算是单例模式的合理实现,但是线程安全性如何需要仔细思考一下,目前的想法是这种实现是否线程安全与编译器有关,编译器控制当两个进程同时到达静态变量定义处时的处理)
3.Singleton_3:与Singleton_2类似,不过Singleton_2返回的是单例对象的引用,这里返回的是单例对象的指针。个人认为都可以。
4.Singleton_4:本质上是一个典型的单例模式的实现,但是考虑的比较周到:1)声明了删除的拷贝构造函数和拷贝赋值运算符;2)实现了一个restart方法,可以删除单例对象(单例模式中实现restart()是否合适是另外的一说,这里只是觉得这种实现比较有意思)。
5.Singleton_5:一个典型的单例模式实现,采用懒汉式实现方法。
6.Singleton_6:一个典型的单例模式实现,采用饿汉式实现方法。
7.Singleton_7:使用双重检查锁定(Double check locking)技术实现的懒汉式单例模式。对于这个示例需要注意的是,类的静态成员不应该在类的内部进行初始化,所以单例对象m_pSingleton和互斥锁m_mutex需要在类的外部进行初始化。在类的内部,只是对这两个变量进行声明。
*对于类的普通成员变量,在类中声明的时候会自动调用构造函数进行初始化,或者随机赋一个初始值,但是对于类的静态成员变量,在类中只是声明,没有进行初始化与定义,如果忘了对类的静态成员变量进行类外的初始化,链接器就会报错:无法解析符号。出现这个问题就是因为只有声明,没有初始化,导致链接器无法链接对象实例。*
## 6.Adapter模式(适配器模式)
### Java版本
1.sample01:一个比较基本的适配器模式的实例实现,采用类适配器形式。同时利用xml+反射机制动态配置Target需要的适配器和Adaptee。
2.sample02:一个比较基本的适配器模式的实例实现,采用对象适配器形式。同时利用xml+反射机制动态配置Target需要的适配器和Adaptee。
3.section1:一个比较基本的适配器模式的实例实现,采用类适配器形式,基本能够把适配器模式的用途和实现展示出来。
4.section2:一个Adapter的比较标准的样例实现,采用类适配器形式实现。
5.section3:一个比较基本的适配器模式的实例实现,采用对象适配器形式,基本可以体现适配器的内涵。
### C++版本
1.Adapter_1:一个比较基本的适配器模式的样例实现,采用对象适配器形式。
2.Adapter_2:一个比较基本的适配器模式的样例实现,采用类适配器形式。
3.Adapter_3:一个比较基本的适配器模式的样例实现,采用类适配器形式。与Adapter_2实际上没有什么区别。
4.Adapter_4:一个比较基本的适配器模式的样例实现,采用对象适配器形式。与Adapter_1的区别在于,这里的Adaptee的对象是在Adapter的构造函数中定义的,而与Adapter_1是在main函数中定义然后通过构造函数传入的。
5.Adapter_5:一个基本的适配器模式的样例实现,采用对象适配器形式,与Adapter_4实际上并无区别,编程风格比较舒服。
## 7.Bridge模式(桥接模式)
### Java版本
1.sample01:一个非常好的桥接模式的示例,另外使用xml+反射进行扩展。
2.section3:一个比较典型的桥接模式的示例,区别是实现中的HouseCorp类(RefinedAbstraction)中,由于确定是为了House类(ConcreteImplementor)服务,所以HouseCorp构造函数的传入的参数必须是House类的对象,至于ShanZhaiCorp类(RefinedAbstraction)的构造函数的传入参数还是与一般的桥接模式相同,是Prodect类(Implementor)的对象。这个例子比较好的证明了即便是如桥接模式这样的比较固定套路的设计模式中,也可以根据实际情况进行微调。
3.section5:一个基本的桥接模式的样例实现,可以参考。
### C++版本
1.Bridge_1:一个基本的桥接模式的样例实现,可以参考。
2.Bridge_2:一个比较基本的桥接模式的示例,实现风格比较好。
## 8.Composite模式(组合模式)
### Java版本
- sample01:一个简单的组合模式的实例,基本能够看出组合模式的核心元素。
- section3:一个简单的组合模式的实例,基本能够看出组合模式的核心元素。
- section4:一个简单的组合模式框架的示例。
- section5:一个简单的组合模式框架的示例。
- section6:一个简单的的组合模式的实例。
### C++版本
- Composite_1:一个简单的组合模式的示例,
- Composite_2:一个简单的组合模式的实例,基本体现了组合模式的核心元素。编程风格比较好。
## 9.Decorator模式(装饰模式)
### Java版本
1.sample01:所谓的“半透明装饰模式”的实现,个人不推荐这种实现方式,不过可以作为了解。
2.sample02:一个非常典型的装饰模式的实现,这个示例是可以应用到现实程序中的。
3.section2:一个典型的装饰模式的实现。
4.section3:一个典型的装饰模式的示例,并且对一个对象进行多次修饰。
### C++版本
1.Decorator_1:一个典型的装饰模式的示例,比较标准。
2.Decorator_2:一个典型的装饰模式的示例,与 Decorator_1 相比,只是将所有代码都集中到一个文件当中了。
3.Decorator_3:一个典型的装饰模式的实例,编程风格比较舒服,这个例子也能在一定程度上反应装饰模式的实际应用。
## 10.Facade模式(外观模式)
### Java版本
- JDBCFacade:一个 JDBC 的外观模式的实现。这个例子非常好,相当于对于 JDBC 另外封装了一个类,这个类可以直接在实践当中应用。
- sample01:一个简单的外观模式的实例,基本涵盖了外观模式的核心元素。
- section3:一个简单的外观模式的实例。
- section5:一个简单的外观模式的框架示例。
- section7:一个简单的外观模式的示例,增加了一个复杂函数,为了体现外观模式整合接口的能力。
### C++版本
- Facade_1:一个简单的外观模式的框架示例,将类分散到各个文件中。
- Facade_2:一个简单的外观模式的框架示例,所有类都在同一个文件中。
## 11.Flyweight模式(享元模式)
### Java版本
- sample02:一个简单的享元模式的样例,能够反映享元模式的核心思路。这个例子扩展一下,可以扩展到围棋应用。
- section3:一个典型的享元模式的实现框架。基本能够反映享元模式的核心思路。
### C++版本
- Flyweight_1:一个享元模式的示例,要素比较齐全,基本反映了享元模式的核心思路。(不足之处在于不希望进行共享的类 - UnsharedConcreteFlyweight - 没有很好的展示,另外内部状态和外部状态有些混乱 - 将外部状态传入之后,作为内部状态 - 从这一点上而言,这个例子可以作为一个反例。)
- Flyweight_2:一个典型的享元模式的示例,能够很好的分清楚内部状态和外部状态,很好的展示了享元模式的核心思想,编程风格比较好。值得学习。
## 12.Proxy模式(代理模式)
### Java版本
- dynamic_section1:一个动态代理的框架(可以直接套用),比较高端,有返回值。在dynamic_section1当中,通过一个DynamicProxy类,将客户端调用简化(可以对比DynamicProxy包),注意,这里DynamicProxy类,只是简化,没有实际的业务意义,实际上的Proxy还是MyInvocationHandler。
- dynamic_section2:是dynamic_section1的一个简单扩展,核心思路还是dynamic_section1的动态代理。
- DynamicProxy:一个典型的动态代理的示例,代码的实现看起来也比较舒服,比较清晰。在学习这个例子的时候,可以参考dynamic_section1一同学习。
- sample01:一个非常典型的代理模式的实现,在代理当中,对使用真实主题对象的权限进行检查,是典型的保护代理的示例。
- section2:一个非常简单的代理模式的样例,甚至都不一定是常规的代理模式的实现,这个例子中,将真实主题的对象传入,所以这个代理模式只能算是形似的实现,没有把握代理模式的核心。但是,如果这个例子中,在各个操作之前进行一些保护、判断的操作,就可以成为一个保护代理,于是就能说的过去了。这个例子放到这里就当一个反例吧。
- section4:一个简单的代理模式的样例,与section2对比,这里的实现没有将真实主题的对象传入,而是在代理类的构造函数中创建一个真实主题对象,做到了真实主题对象对于用户的透明,相比section2而言,这样的实现有一定的实际意义,这样可以在需要替换真实主题的时候在代理中对真实主题进行替换,而不影响客户端的调用。这并不是代理模式典型的用途,简单了解,通过这个样例认识一下代理模式即可。
- section6:一个比较奇葩的代理模式的实现,书中称为“强制代理”:一般的思维都是通过代理找到真实的角色, 但是强制代理却是要“强制”, 你必须通过真实角色查找到代理角色,否则你不能访问。 无论通过代理类还是通过直接new一个主题角色类, 都不能访问, 只有通过真实角色指定的代理类才可以访问, 也就是说由真实角色管理代理角色。 也就是说,高层模块new了一个真实角色的对象, 返回的却是代理角色。
- section8:一个代理模式的简单样例,代理在其中的一个操作(upgrade)当中附加了一个操作(count),可以算是代理模式比较典型的应用。
- section11:一个动态代理的示例。利用Java当中提供的语言设施(InvocationHandler和Proxy),实现的动态代理。动态代理是AOP(Aspect Oriented Programming,面向横切面编程)的核心。**这里需要注意,AOP的设计思路没有理解,动态代理的实现和使用没有掌握,需要进一步学习!**
### C++版本
- Proxy_1:一个比较简单的代理的样例,基本实现了代理的要素。具体主题的对象在代理类的构造函数中定义,客户端调用时比较简单。
- Proxy_2:一个简单的代理模式的样例,具体主题对象在客户端中定义,通过代理的构造函数传入代理类中。
- Proxy_3:一个非常简单的代理模式的实现,具体主题的对象在代理类的构造函数中定义。
- Proxy_4:一个典型的代理模式的实现,这个例子比较经典,同时体现了“虚代理”和“保护代理”两种代理的应用模式,值得学习。
## 13.CommandChain模式(职责链模式)
### Java版本
- CommandChain:一个复杂的职责链模式的实现,完整的表达了职责链的核心,其中实现的思路和技巧非常值得学习。
- sample01:一个简单的职责链的实现,包含了职责链的核心。
### C++版本
- CommandChain_1:一个非常简单的职责链模式的示例,基本上涵盖了职责链模式的核心要素。在这个实现中,基类完成将请求传递给后续职责链对象的操作,这一点应当学习,这样实现的意图在于,在职责链中的对象只做与处理请求相关的事情,其他的所有的管理、操控都在基类中完成。
- CommandChain_2:一个非常简单的职责链模式的示例,基本上涵盖了职责链模式的核心要素。这个实现中测试程序(main函数)比较清晰。
## 14.Command模式(命令模式)
### Java版本
* sample01:一个简单的命令模式的实例,基本涵盖了命令模式的核心。这个示例中,Receiver在ConcreteCommand中创建,此处实现关联。Command与Invoker之间的关联在Client中实现。
* section3:简单的命令模式的示例,基本体现了命令模式的核心要素。在这个示例中,Invoker对Command对象的关联,Command对象与Receiver对象的关联都是在Client中进行。
* section4:简单的命令模式的实例,展示了命令模式的核心要素。实例中,Command对象与Receiver对象之间的关联是在ConcreteCommand类的构造函数中完成,但是可以替换。Invoker与Command对象之间的关联在Client中完成。
* UndoDemo:一个命令模式的实例,展示了如何利用命令模式实现撤销操作动作(Undo)。
### C++版本
* Command_1:一个非常简单的命令模式的示意。Command、Invoker、Receiver之间的关联都是在main函数中完成。
- Command_2:一个非常简单的命令模式的示意。Command、Invoker、Receiver之间的关联都是在main函数中完成。与Command_1不同之处只在于Command_2是将所有类分散到不同的文件当中。
## 15.Interpreter模式(解释器模式)
### Java版本
- sample01:一个解释器模式的实例,通过解释器模式构建一个计算脚本语言。比较完整的展示了解释器模式的核心内容。另外构建抽象语法树并不是解释器模式的关注点,这里也做了一个简单的实现。
- section1:一个解释器模式的实例,同sample01基本相同。
- section2:一个简单的解释器模式的实现框架,增加了Context元素,Context对象一般存储环境信息,作为参数传入解释器类中。
### C++版本
- Interpreter_1:网上找的解释器模式的实现都极为不靠谱,这个实现是《设计模式:可复用面向对象软件的基础》这本书上的例子,这里抄了一遍。自己实现的建立抽象语法树,相当于手写了一个词法分析器和语法分析器,问题很多,但解释器模式的核心不在于建立抽象语法树,所以个人认为这个实现基本展示了解释器模式的核心。
## 16.Iterator模式(迭代器模式)
### Java版本
- JavaIterator:一个简单的使用Java内置迭代器的示例。
- sample01:一个较为复杂的迭代器模式的实例。采用内部类+工厂模式的方式实现具体的迭代器,连同聚集类一同实现。此外,使用XML指定使用哪个具体聚集类,使用Java语言的反射特性新建一个聚集类对象,最后采用工厂模式确定一个具体的迭代器。
- section2:一个基本的迭代器模式的实例,基本体现了迭代器模式的核心要素。其中,具体的Iterator同具体的Project是一一对应的关系,Iterator要了解Project中的具体的数据结构。
- section3:一个基本的迭代器模式的示例,与section2实现的思路基本相同。
- SimpleIterator:一个基本的迭代器模式的实现。但是采用内部类的方式实现具体的迭代器,但是对于客户端的使用没有影响。
### C++版本
- Iterator_1:一个简单的迭代器模式的示例。并没有使用工厂模式,所以只是简单的展示了迭代器模式的核心要素,但是真正的实现扩展性非常差。
- Iterator_2:一个简单的迭代器模式的示例。使用工厂模式。
## 17.Mediator模式(中介者模式)
#### Java版本
- sample01:一个较为复杂的中介者模式的实例。中介者不仅仅进行消息中转,还会有自己的处理逻辑。同事类可以在中介者模式当中进行注册,在注册的同时,也会被告知中介者对象。
- section2:一个简单的中介者模式的实例。在抽象中介者当中声明和初始化所有的同事类,与sample01当中的注册机制相比,不够灵活,可以用于同事类数量较少且可以提前确定的情况。根据传入消息的不同采用不同的处理方式,这里传入的消息其实就是一种协议。
- section3:一个简单的中介者模式的示例。基本涵盖中介者模式的核心思路。
#### C++版本
- Mediator_1:一个中介者模式的实例,基本思路同Java版本中的sample01非常相似。
- Mediator_2:一个中介者模式的实例,基本思路同Mediator_1,编程风格值得学习。
- Mediator_3:一个中介者模式的实例,基本思路同Java版本中的section2。在同事类的构造函数当中通过参数传入中介者对象,而中介者对象当中也保存有所有的同事类对象,通过抽象中介者当中定义的一个方法传入中介者对象当中。
## 18.Memento模式(备忘录模式)
### Java版本
- sample01:一个简单的备忘录模式的实例。基本涵盖了备忘录的所有核心要素。
- section3:一个非常简单的备忘录模式的实例,基本涵盖了备忘录的所有核心要素。
- section4:一个非常简单的备忘录模式的示例框架,实现与 section3 非常相似。
- section6:以 clone 的方式实现的备忘录,是一种原型模式和备忘录模式的结合,省略了 Memento 角色类和 Caretaker 角色类。这种变化使得程序精简了很多, 而且高层模块的依赖也减少了,但是存在原型模式深拷贝和浅拷贝的问题, 在复杂的场景下它会使程序逻辑异常混乱, 出现错误也很难跟踪。因此使用Clone方式实现的备忘录模式, 可以使用在比较简单的场景或者比较单一的场景中, 尽量不要与其他的对象产生严重的耦合关系。
- section7:多状态备忘录模式的实现,是备忘录模式的扩展,是一个对象全状态备份方案,实现一个类中对象的所有状态的备份和还原。其中,BeanUtils 类可能在项目中会经常用到,可以直接作为参考使用,backupProp 是把发起人的所有属性值转换到 HashMap 中, 方便备忘录角色存储; restoreProp 方法则是把 HashMap 中的值返回到发起人角色中。 通过这种方式的改造, 不管发起者类中有多少状态都没有问题, 直接把原有的对象所有属性都备份了一遍。
- section8:多备份的备忘录,备忘录模式的扩展。需要修改 Caretaker 类,把 Caretaker 类中容纳备忘录的容器修改为 Map 类型就可以了。需要注意的是,多备份的备忘录存在内存溢出问题, 该备份一旦产生就装入内存, 没有任何销毁的意向。 因此, 在系统设计时, 要严格限定备忘录的创建, 建议增加 Map 的上限。
- section9:使用内置类实现的备忘录模式,目标是实现备忘录类的宽窄接口:对于发起者类,可以访问到备忘录类的所有成员,对于其他类,只能访问到备忘录对象本身。这里比较精髓的是 IMemento 接口,这是一个空接口,发起者类的内置类 Memento 实现这个接口,其他类(如 Caretaker类)通过 IMemento 接口访问备忘录对象,但无法访问备忘录对象中的成员。
### C++版本
- Memento_1:一个简单的备忘录模式的示例。实现了多状态备忘录模式,Caretaker 使用数组存放备忘录对象。
## 19.Observer模式(观察者模式)
### Java版本
- sample01:一个简单的观察者模式的实例,基本涵盖了观察者模式的核心内容。
- sample02:一个使用观察者模式实现的简单Swing界面。采用基于观察者模式的委派事件模型(DelegationEvent Model,DEM),事件的发布者称为事件源(Event Source),订阅者称为事件监听器(Event Listener),又称为事件处理对象。事件源对象充当观察目标,而事件监听对象充当观察者。

- section3:一个简单的观察者模式的实例。基本涵盖了观察者模式的核心要素。
- section4:一个简单的观察者模式的示例,基本涵盖了观察者模式的核心要素。
### C++版本
- Observer_1:一个简单的观察者模式的示例,基本涵盖观察者模式的核心内涵。观察者 Observer 类中的 Update 接口需要将 Subject 对象本身作为参数传递。这个实现同书上的原版实现有些出入,个人认为这个实现有些问题:Subject 抽象类当中有业务虚函数,个人认为虚函数不应该在 Subject 类当中出现,因为实际当中,目标类不太可能抽象出统一的业务接口。
- Observer_2:一个简单的观察者模式的实例。这个例子比较舒服,与 Observer_1 对比:1)Update 接口传输的是一个信息参数,并不是 Subject 对象本身;2)在抽象类 Subject 当中并没有出现业务接口,业务接口在 ConcreteSubject 类当中定义,这个方式实现比较舒服。
## 20.State模式(状态模式)
### Java版本
- sample01:简单的状态模式的实例。状态转换在 ConcreteState 类当中的一个特定函数中完成。在状态转换时初始化 ConcreteState 对象。这个实例中逻辑设置有问题,但是基本体现了状态模式的特点。
- section3:简单的状态模式的实例,基本体现了状态模式的特点。状态的转换在 ConcreteState 类当中实现。本例中状态比较少,所以在 Context 类当中,将所有的状态初始化,这样就不用在状态转换的时候初始化 ConcreteState 对象,提高了状态转换时的效率。Context 类中有对 State 类的对象的引用,State 类中有对 Context 类的对象的引用。
- section4:简单的状态模式的示例,实际上是一个状态模式的实现框架,实现的思路与 section3 相同。
- ShareState:一个比较好的实例,状态转换在 ConcreteState 类当中完成,Context 当中通过 static 方式引用 State 类的对象,但是 State 当中没有对 Context 类的对象的引用,在 Context 类的构造函数中,将所有状态初始化。本实例主要想要表现共享状态的实现,即多个环境对象可能需要共享同一个状态, 如果希望在系统中实现多个环境对象共享一个或多个状态对象, 那么需要将这些状态对象定义为环境类的静态成员对象。
### C++版本
- State_1:一个非常简单的状态模式的示例,状态转换在 ConcreteState 类当中完成,ConcreteState 使用单例模式创建对象,基本体现了状态模式的特点。
## 21.Strategy模式(策略模式)
### Java版本
- sample01:一个简单的策略模式的实例,展现了策略模式的核心要素。这个例子利用“xml + 反射”机制,通过xml文件配置要加载的排序算法。但是这个例子归根结底还是要在客户端指定需要使用的具体策略。
- section2:一个简单的策略模式框架示例。
### C++版本
- Strategy_1:一个非常简单的策略模式的框架示例,全部类都在一个文件中。
- Strategy_2:一个非常简单的策略模式的框架示例,类分散在不同文件中,这个例子当中 Strategy 基类的构造函数是默认的构造函数,具体策略对象需要利用 Context 的 setStrategy 接口实现,感觉这个实现有些问题,要预防忘记调用 setStrategy 设置具体的策略。
- Strategy_3:一个非常简单的策略模式的实例。
## 22.Template Method模式(模板方法模式)
### Java版本
- HookMethodDemo:一个非常简单的模板方法的实例。其中基类定义了模板方法,全部三类基本方法:抽象方法、具体方法、钩子方法。
- sample01:一个非常简单的模板方法的实例,利用“xml + 反射”机制,通过xml文件配置具体要使用的子类。其中基类定义了模板方法、抽象的基本方法、具体的基本方法。
- sample02:使用模板方法模式模拟使用 JDBC 连接数据库的过程,有一定的借鉴意义,实践当中可以考虑应用此方法。其中基类定义了模板方法、抽象的基本方法、具体的基本方法。
- section2:一个非常简单的模板方法模式的实例,其中基类中定义了模板方法,其他的方法均为抽象的基本方法(元语操作)。
- section3:一个非常简单的模板方法模式的框架示例。其中基类中定义了模板方法,其他的方法均为抽象的元语操作。
- section4:一个非常简单的模板方法的实例,其中基类中定义了模板方法、钩子方法、抽象的基本方法。
### C++版本
- TemplateMethod_1:一个非常简单的模板方法的框架示例,其中基类中定义了模板方法、抽象的基本方法。
- TemplateMethod_2:一个非常简单的模板方法实例。其中基类中定义了模板方法,两类基本操作:具体操作、抽象操作。
## 23.观察者模式
### Java版本
- sample01:一个观察者模式的实例。利用xml+反射的方式确定一个具体的观察者。
- section2:一个简单的观察者模式的实例,对象结构利用一个方法 mockEmployee() 构造并返回,观察者中的 visit 方法采用方法重载的方式实现。
- section3:一个简单的观察者模式的框架示例。观察者中的 visit 方法采用方法重载的方式实现。
- section4:一个简单的观察者模式的实例。这个例子主要体现在观察者模式当中,观察者主要负责实现算法,可以记录算法中间状态,然后在对元素处理完成之后,提供另外的方法统一处理分析结果。
- section5:一个简单的观察者模式的实例。这个例子主要体现一个对象,多个访问者的场景。
- section7:一个非常简单的观察者模式的实例。主要为了说明双分派。
### C++版本
- Visitor_1:一个非常简单的观察者模式框架示例。并没有完全覆盖观察者模式的核心内涵,没有体现对象结构,观察者中的 visit 方法采用不同的方法接口的方式实现。
- Visitor_2:一个简单的观察者模式实例。观察者中的 visit 方法采用方法重载的方式实现。