├── LICENSE ├── README.md └── design-patterns ├── pom.xml └── src ├── main └── java │ └── pers │ └── huangyuhui │ ├── App.java │ ├── abstract_factory_pattern │ ├── README.md │ └── abstract_factory_pattern_1 │ │ ├── Button.java │ │ ├── Client.java │ │ ├── ComboBox.java │ │ ├── SkinFactory.java │ │ ├── SpringButton.java │ │ ├── SpringComboBox.java │ │ ├── SpringSkinFactory.java │ │ ├── SpringTextField.java │ │ ├── SummerButton.java │ │ ├── SummerComboBox.java │ │ ├── SummerSkinFactory.java │ │ ├── SummerTextField.java │ │ └── TextField.java │ ├── adapter_pattern │ ├── README.md │ ├── adapter1 │ │ ├── Banner.java │ │ ├── Main.java │ │ ├── Print.java │ │ └── PrintBanner.java │ ├── adapter2 │ │ ├── Banner.java │ │ ├── Main.java │ │ ├── Print.java │ │ └── PrintBanner.java │ └── adapter3 │ │ ├── MyController.java │ │ ├── MyEventService.java │ │ └── MyWindowAdapter.java │ ├── builder_pattern │ ├── README.md │ ├── builder_pattern_1 │ │ ├── Actor.java │ │ ├── ActorBuilder.java │ │ ├── ActorController.java │ │ ├── AngelBuilder.java │ │ ├── Client.java │ │ └── HeroBuilder.java │ └── builder_pattern_2 │ │ ├── Actor.java │ │ ├── ActorBuilder.java │ │ ├── AngelBuilder.java │ │ ├── Client.java │ │ └── HeroBuilder.java │ ├── command_pattern │ ├── README.md │ ├── command_pattern_1 │ │ ├── Client.java │ │ ├── Command.java │ │ ├── FunctionButton.java │ │ ├── LoginInCommand.java │ │ ├── LoginInSystem.java │ │ ├── LoginOutCommand.java │ │ └── LoginOutSystem.java │ └── command_pattern_2 │ │ ├── Client.java │ │ ├── Command.java │ │ ├── DrawCanvas.java │ │ ├── DrawCommand.java │ │ ├── Drawable.java │ │ └── MacroCommand.java │ ├── composite_pattern │ ├── README.md │ ├── composite_pattern_1 │ │ ├── Client.java │ │ ├── Directory.java │ │ ├── Entry.java │ │ ├── File.java │ │ └── FileTreatMentException.java │ └── composite_pattern_2 │ │ ├── AbstractFile.java │ │ ├── Client.java │ │ ├── FileTreatMentException.java │ │ ├── Folder.java │ │ ├── ImageFile.java │ │ └── TextFile.java │ ├── decorator_pattern │ ├── README.md │ └── decorator_pattern_1 │ │ ├── BlackBorderDecorator.java │ │ ├── Client.java │ │ ├── Component.java │ │ ├── ComponentDecorator.java │ │ ├── ListBox.java │ │ ├── ScrollBarDecorator.java │ │ ├── TextBox.java │ │ └── Window.java │ ├── facade_pattern │ ├── README.md │ ├── facade_pattern_1 │ │ ├── CipherMachine.java │ │ ├── Client.java │ │ ├── EncryptFacade.java │ │ ├── FileReader.java │ │ ├── FileWriter.java │ │ ├── from.txt │ │ └── to.txt │ └── facade_pattern_2 │ │ ├── AbstractEncryptFacade.java │ │ ├── CipherMachine.java │ │ ├── Client.java │ │ ├── EncryptFacade.java │ │ ├── FileReader.java │ │ ├── FileWriter.java │ │ ├── NewCipherMachine.java │ │ ├── NewEncryptFacade.java │ │ ├── from.txt │ │ └── to.txt │ ├── factory_method_pattern │ ├── README.md │ ├── factory_method1 │ │ ├── Client.java │ │ ├── DatabaseLogger.java │ │ ├── DatabaseLoggerFactory.java │ │ ├── FileLogger.java │ │ ├── FileLoggerFactory.java │ │ ├── Logger.java │ │ └── LoggerFactory.java │ ├── factory_method2 │ │ ├── Client.java │ │ ├── DatabaseLogger.java │ │ ├── DatabaseLoggerFactory.java │ │ ├── FileLogger.java │ │ ├── FileLoggerFactory.java │ │ ├── Logger.java │ │ └── LoggerFactory.java │ └── factory_method3 │ │ ├── Client.java │ │ ├── DatabaseLogger.java │ │ ├── DatabaseLoggerFactory.java │ │ ├── FileLogger.java │ │ ├── FileLoggerFactory.java │ │ ├── Logger.java │ │ └── LoggerFactory.java │ ├── froxy_pattern │ ├── README.md │ ├── froxy_pattern_1 │ │ ├── AccessValidator.java │ │ ├── Client.java │ │ ├── Logger.java │ │ ├── ProxySearcher.java │ │ ├── RealSearcher.java │ │ └── Searcher.java │ └── froxy_pattern_2 │ │ ├── AbstractDocumentDao.java │ │ ├── AbstractUserDao.java │ │ ├── Client.java │ │ ├── DAOLogHandler.java │ │ ├── DocumentDao.java │ │ └── UserDao.java │ ├── iterator_pattern │ ├── README.md │ ├── iterator1 │ │ ├── Aggregate.java │ │ ├── Book.java │ │ ├── BookSelf.java │ │ ├── BookShelfIterator.java │ │ ├── Iterator.java │ │ └── Test1.java │ └── iterator2 │ │ ├── AbstractIterator.java │ │ ├── AbstractObjectList.java │ │ ├── ProductList.java │ │ └── Test2.java │ ├── mediator_pattern │ ├── README.md │ ├── mediator_pattern_1 │ │ ├── Button.java │ │ ├── Client.java │ │ ├── ComboBox.java │ │ ├── Component.java │ │ ├── ConcreteMediator.java │ │ ├── List.java │ │ ├── Mediator.java │ │ └── TextBox.java │ └── mediator_pattern_2 │ │ ├── Button.java │ │ ├── Client.java │ │ ├── ComboBox.java │ │ ├── Component.java │ │ ├── ConcreteMediator.java │ │ ├── Label.java │ │ ├── List.java │ │ ├── Mediator.java │ │ ├── SubConcreteMediator.java │ │ └── TextBox.java │ ├── observer_pattern │ ├── README.md │ └── observer_pattern_1 │ │ ├── AllyControllerCenter.java │ │ ├── Client.java │ │ ├── ConcreteAllyControlCenter.java │ │ ├── Observer.java │ │ └── Player.java │ ├── simple_factory_pattern │ ├── README.md │ └── simple_factory_pattern_1 │ │ ├── Chart.java │ │ ├── ChartFactory.java │ │ ├── Client.java │ │ ├── HistogramChart.java │ │ └── PieChart.java │ ├── singleton_pattern │ ├── IoDH_singleton │ │ ├── Client.java │ │ └── Singleton.java │ ├── README.md │ ├── eager_singleton │ │ ├── Client.java │ │ └── EagerSingleton.java │ └── lazy_singleton │ │ ├── Client.java │ │ └── LazySingleton.java │ └── template_method_pattern │ ├── README.md │ ├── template_method1 │ ├── AbstractDisplay.java │ ├── CustomDisplay1.java │ ├── CustomDisplay2.java │ └── Main.java │ └── template_method2 │ ├── CustomDataViewer1.java │ ├── CustomDataViewer2.java │ ├── DataViewer.java │ └── Main.java └── test └── java └── pers └── huangyuhui └── AppTest.java /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 黄宇辉 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 配套博客学习笔记 : https://goog.tech/blog/tags/design-and-pattern 2 | 3 | > 参考书籍( 推荐 ) : `《Java设计模式 - 刘伟》`,`《图解设计模式 - [日]结城浩》` 4 | 5 | 6 | 7 | ### 创建型模式 8 | 9 | :heavy_check_mark: `简单工厂模式( Simple Factor Pattern )` 10 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/06/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BSimple-Factory-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/simple_factory_pattern) 11 | 12 | :heavy_check_mark: `工厂方法模式( Factory Method Pattern )` 13 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/05/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BFactory-Method-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern) 14 | 15 | :heavy_check_mark: `抽象工厂模式( Abstract Factroy Pattern )` 16 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/07/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BAbstract-Factory-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern) 17 | 18 | :heavy_check_mark: `建造者模式( Builder Pattern )` 19 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/17/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BBuilder-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/builder_pattern) 20 | 21 | :heavy_check_mark: `单例模式( Singleton Pattern )` 22 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/06/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BSingleton-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/singleton_pattern) 23 | 24 | :heavy_multiplication_x: `原型模式( Prototype Pattern )` 25 | > :memo: [学习笔记updating](demo) ,[示例程序updating](demo) 26 | 27 | 28 | 29 | ### 结构型模式 30 | 31 | :heavy_check_mark: `适配器模式( Adapter Pattern )` 32 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/03/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BAdapter-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/adapter_pattern) 33 | 34 | :heavy_check_mark: `代理模式( Proxy Pattern )` 35 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/25/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BProxy-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/froxy_pattern) 36 | 37 | :heavy_check_mark: `组合模式( Composite Pattern )` 38 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/11/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BComposite-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/composite_pattern) 39 | 40 | :heavy_check_mark: `装饰模式( Decorator Pattern )` 41 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/08/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BDecorator-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/decorator_pattern) 42 | 43 | :heavy_check_mark: `外观模式( Facade Pattern )` 44 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/12/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BFacade-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/facade_pattern) 45 | 46 | :heavy_multiplication_x: `桥接模式( Bridge Pattern )` 47 | > :memo: [学习笔记updating](demo) ,[示例程序updating](demo) 48 | 49 | :heavy_multiplication_x: `享元模式( Flyweight Pattern )` 50 | > :memo: [学习笔记updating](demo) ,[示例程序updating](demo) 51 | 52 | 53 | 54 | ### 行为型模式 55 | 56 | :heavy_check_mark: `命令模式( Command Pattern )` 57 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/20/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BCommand-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/command_pattern) 58 | 59 | :heavy_check_mark: `迭代器模式( Iterator Pattern )` 60 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/02/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BIterator-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/iterator_pattern) 61 | 62 | :heavy_check_mark: `模板方法模式( Template Method Pattern )` 63 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/04/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BTemplate-Method-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/template_method_pattern) 64 | 65 | :heavy_check_mark: `观察者模式( Observer Pattern )` 66 | > :memo: [学习笔记](https://goog.tech/blog/2019/09/28/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BObserver-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/observer_pattern) 67 | 68 | :heavy_multiplication_x: `中介者模式( Mediator Pattern )` 69 | > :memo: [学习笔记](https://goog.tech/blog/2019/10/10/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BMediator-Pattern/) ,[示例程序](https://github.com/GoogTech/design-patterns-in-java/tree/master/design-patterns/src/main/java/pers/huangyuhui/mediator_pattern) 70 | 71 | :heavy_multiplication_x: `职责链模式( Chain of Responsibility Pattern )` 72 | > :memo: [学习笔记updating](demo) ,[示例程序updating](demo) 73 | 74 | :heavy_multiplication_x: `解释器模式( Interpreter Pattern )` 75 | > :memo: [学习笔记updating](demo) ,[示例程序updating](demo) 76 | 77 | :heavy_multiplication_x: `备忘录模式( Memento Pattern )` 78 | > :memo: [学习笔记updating](demo) ,[示例程序updating](demo) 79 | 80 | :heavy_multiplication_x: `状态模式( State Pattern )` 81 | > :memo: [学习笔记updating](demo) ,[示例程序updating](demo) 82 | 83 | :heavy_multiplication_x: `策略模式( Strategy Pattern )` 84 | > :memo: [学习笔记updating](demo) ,[示例程序updating](demo) 85 | 86 | :heavy_multiplication_x: `访问者模式( Visitor Pattern )` 87 | > :memo: [学习笔记updating](demo) ,[示例程序updating](demo) 88 | -------------------------------------------------------------------------------- /design-patterns/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 4.0.0 7 | pers.huangyuhui 8 | gof 9 | 1.0-SNAPSHOT 10 | 11 | design-patterns-in-java 12 | design patterns implemented in Java 13 | https://yubuntu0109.github.io/tags/design-and-pattern/ 14 | 15 | 16 | UTF-8 17 | 11 18 | 11 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | 4.13.1 26 | test 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | maven-clean-plugin 35 | 3.1.0 36 | 37 | 38 | maven-resources-plugin 39 | 3.0.2 40 | 41 | 42 | maven-compiler-plugin 43 | 3.8.0 44 | 45 | 46 | maven-surefire-plugin 47 | 2.22.1 48 | 49 | 50 | maven-jar-plugin 51 | 3.0.2 52 | 53 | 54 | maven-install-plugin 55 | 2.5.2 56 | 57 | 58 | maven-deploy-plugin 59 | 2.8.2 60 | 61 | 62 | maven-site-plugin 63 | 3.7.1 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/App.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui; 2 | 3 | /** 4 | * Hello world! 5 | */ 6 | public class App { 7 | public static void main(String[] args) { 8 | System.out.println("Hello World!"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Java设计模式之Abstract Factory Pattern 3 | date: 2019-09-07 21:56:25 4 | tags: [Java,design and pattern] 5 | --- 6 | 7 | ## 学习笔记 : Java设计模式之Abstract Factory Pattern 8 | 9 | ### 概述 10 | *`工厂方法模式`通过引入工厂等级结构解决了`简单工厂模式`中工厂类职责太重的问题,但由于工厂方法模式中每个具体工厂只有一个或一组重载的工厂方法,既只能生产一种产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销. 抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形式. 抽象工厂模式与工厂方法模式的最大区别在于 : 工厂方法模式针对的是一个`产品等级结构`,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建. 当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更加简单,更有效率~ 抽象工厂模式的定义为 : 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类( Abstract Factory Pattern : Provide an interface for creating families of related or dependent objects without sprcifying their concrete classes. )* 11 | 12 | 13 | ### 抽象工厂模式中的角色 14 | 1. *`AbstractFactory( 抽象工厂 )` : 它声明了一组用于创建一族产品的方法,每一个方法对应一种产品.* 15 | 2. *`ConcreteFactory( 具体工厂 )` : 它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个`产品族`,每一个产品都位于某个产品等级结构中* 16 | 3. *`AbstractProduct( 抽象产品 )` : 它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法.* 17 | 4. *`ConcreteProduct( 具体产品 )` : 它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法.* 18 | 19 | 20 | ### 示例程序 21 | *下面是一个使用了抽象工厂模式的简单示例程序,其程序功能( 模拟 )描述为 : 开发一套基于 Java 桌面软件的界面皮肤库,用户可以自由切换界面皮肤,例如有 Spring 与 Summer 风格等皮肤~* 22 | 23 | 1. *Button接口 : 接口按钮, 充当抽象产品* 24 | ```java 25 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 26 | 27 | /** 28 | * @project: design-patterns 29 | * @description: 接口按钮, 充当抽象产品 30 | * @author: 黄宇辉 31 | * @date: 9/7/2019-5:18 PM 32 | * @version: 1.0 33 | * @website: https://yubuntu0109.github.io/ 34 | */ 35 | public interface Button { 36 | void display(); 37 | } 38 | ``` 39 | 40 | 2. *SpringButton类 : Spring风格皮肤的按钮类, 充当具体产品* 41 | ```java 42 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 43 | 44 | /** 45 | * @project: design-patterns 46 | * @description: Spring风格皮肤的按钮类, 充当具体产品 47 | * @author: 黄宇辉 48 | * @date: 9/7/2019-5:19 PM 49 | * @version: 1.0 50 | * @website: https://yubuntu0109.github.io/ 51 | */ 52 | public class SpringButton implements Button { 53 | @Override 54 | public void display() { 55 | System.out.println("spring theme———>this is button"); 56 | } 57 | } 58 | ``` 59 | 60 | 3. *SummerButton类 : Summer风格皮肤的按钮类, 充当具体产品* 61 | ```java 62 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 63 | 64 | /** 65 | * @project: design-patterns 66 | * @description: Summer风格皮肤的按钮类, 充当具体产品 67 | * @author: 黄宇辉 68 | * @date: 9/7/2019-5:20 PM 69 | * @version: 1.0 70 | * @website: https://yubuntu0109.github.io/ 71 | */ 72 | public class SummerButton implements Button { 73 | 74 | @Override 75 | public void display() { 76 | System.out.println("Summer theme———>button"); 77 | } 78 | } 79 | ``` 80 | 81 | 4. *TextField接口 : 文本框接口, 充当抽象产品* 82 | ```java 83 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 84 | 85 | /** 86 | * @project: design-patterns 87 | * @description: 文本框接口, 充当抽象产品 88 | * @author: 黄宇辉 89 | * @date: 9/7/2019-5:22 PM 90 | * @version: 1.0 91 | * @website: https://yubuntu0109.github.io/ 92 | */ 93 | public interface TextField { 94 | void display(); 95 | } 96 | ``` 97 | 98 | 5. *SpringTextField类 : Spring风格皮肤的文本框类, 充当具体产品* 99 | ```java 100 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 101 | 102 | /** 103 | * @project: design-patterns 104 | * @description: Spring风格皮肤的文本框类, 充当具体产品 105 | * @author: 黄宇辉 106 | * @date: 9/7/2019-5:22 PM 107 | * @version: 1.0 108 | * @website: https://yubuntu0109.github.io/ 109 | */ 110 | public class SpringTextField implements TextField { 111 | 112 | @Override 113 | public void display() { 114 | System.out.println("Spring theme———>this is text field"); 115 | } 116 | } 117 | ``` 118 | 119 | 6. *SummerTextField类 : Summer风格皮肤的文本框类, 充当具体产品* 120 | ```java 121 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 122 | 123 | /** 124 | * @project: design-patterns 125 | * @description: Summer风格皮肤的文本框类, 充当具体产品 126 | * @author: 黄宇辉 127 | * @date: 9/7/2019-5:23 PM 128 | * @version: 1.0 129 | * @website: https://yubuntu0109.github.io/ 130 | */ 131 | public class SummerTextField implements TextField { 132 | 133 | @Override 134 | public void display() { 135 | System.out.println("Summer theme———>this is text field"); 136 | } 137 | } 138 | ``` 139 | 140 | 7. *ComboBob类 : 组合框接口, 充当抽象产品* 141 | ```java 142 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 143 | 144 | /** 145 | * @project: design-patterns 146 | * @description: 组合框接口, 充当抽象产品 147 | * @author: 黄宇辉 148 | * @date: 9/7/2019-5:24 PM 149 | * @version: 1.0 150 | * @website: https://yubuntu0109.github.io/ 151 | */ 152 | public interface ComboBox { 153 | void display(); 154 | } 155 | ``` 156 | 157 | 8. *SpringComboBox类 : Spring风格皮肤的组合框类, 充当具体产品* 158 | ```java 159 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 160 | 161 | /** 162 | * @project: design-patterns 163 | * @description: Spring风格皮肤的组合框类, 充当具体产品 164 | * @author: 黄宇辉 165 | * @date: 9/7/2019-5:25 PM 166 | * @version: 1.0 167 | * @website: https://yubuntu0109.github.io/ 168 | */ 169 | public class SpringComboBox implements ComboBox { 170 | @Override 171 | public void display() { 172 | System.out.println("Spring theme———>this is comboxBox"); 173 | } 174 | } 175 | ``` 176 | 177 | 9. *SummerComboBox类 : Summer风格皮肤的组合框类, 充当具体产品* 178 | ```java 179 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 180 | 181 | /** 182 | * @project: design-patterns 183 | * @description: Summer风格皮肤的组合框类, 充当具体产品 184 | * @author: 黄宇辉 185 | * @date: 9/7/2019-5:25 PM 186 | * @version: 1.0 187 | * @website: https://yubuntu0109.github.io/ 188 | */ 189 | public class SummerComboBox implements ComboBox { 190 | @Override 191 | public void display() { 192 | System.out.println("Summer theme———>this is comboBox"); 193 | } 194 | } 195 | ``` 196 | 197 | 10. *SkinFactory接口 : 界面皮肤工厂接口, 充当抽象工厂* 198 | ```java 199 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 200 | 201 | /** 202 | * @project: design-patterns 203 | * @description: 界面皮肤工厂接口, 充当抽象工厂 204 | * @author: 黄宇辉 205 | * @date: 9/7/2019-5:26 PM 206 | * @version: 1.0 207 | * @website: https://yubuntu0109.github.io/ 208 | */ 209 | public interface SkinFactory { 210 | Button createButton(); 211 | 212 | TextField createTextField(); 213 | 214 | ComboBox createComboBox(); 215 | } 216 | ``` 217 | 218 | 11. *SpringSkinFactory类 : Spring皮肤风格的工厂类, 充当具体工厂* 219 | ```java 220 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 221 | 222 | /** 223 | * @project: design-patterns 224 | * @description: Spring皮肤风格的工厂类, 充当具体工厂 225 | * @author: 黄宇辉 226 | * @date: 9/7/2019-5:29 PM 227 | * @version: 1.0 228 | * @website: https://yubuntu0109.github.io/ 229 | */ 230 | public class SpringSkinFactory implements SkinFactory { 231 | @Override 232 | public Button createButton() { 233 | return new SpringButton(); 234 | } 235 | 236 | @Override 237 | public TextField createTextField() { 238 | return new SpringTextField(); 239 | } 240 | 241 | @Override 242 | public ComboBox createComboBox() { 243 | return new SpringComboBox(); 244 | } 245 | } 246 | ``` 247 | 248 | 12. *SummerSkinFactory类 : Summer风格皮肤的工厂类, 充当具体工厂* 249 | ```java 250 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 251 | 252 | /** 253 | * @project: design-patterns 254 | * @description: Summer风格皮肤的工厂类, 充当具体工厂 255 | * @author: 黄宇辉 256 | * @date: 9/7/2019-5:33 PM 257 | * @version: 1.0 258 | * @website: https://yubuntu0109.github.io/ 259 | */ 260 | public class SummerSkinFactory implements SkinFactory { 261 | @Override 262 | public Button createButton() { 263 | return new SummerButton(); 264 | } 265 | 266 | @Override 267 | public TextField createTextField() { 268 | return new SummerTextField(); 269 | } 270 | 271 | @Override 272 | public ComboBox createComboBox() { 273 | return new SummerComboBox(); 274 | } 275 | } 276 | ``` 277 | 278 | 13. *Client类 : 客户端测试类* 279 | ```java 280 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory; 281 | 282 | /** 283 | * @project: design-patterns 284 | * @description: 客户端测试类 285 | * @author: 黄宇辉 286 | * @date: 9/7/2019-5:30 PM 287 | * @version: 1.0 288 | * @website: https://yubuntu0109.github.io/ 289 | */ 290 | public class Client { 291 | 292 | public static void main(String[] args) { 293 | SkinFactory skinFactory = new SpringSkinFactory(); 294 | skinFactory.createButton().display(); 295 | skinFactory.createTextField().display(); 296 | skinFactory.createComboBox().display(); 297 | 298 | System.out.println("———————————————————"); 299 | 300 | SkinFactory skinFactory2 = new SummerSkinFactory(); 301 | skinFactory2.createButton().display(); 302 | skinFactory2.createTextField().display(); 303 | skinFactory2.createComboBox().display(); 304 | 305 | } 306 | } 307 | ``` 308 | 309 | 14. *程序运行结果如下所示 :* 310 | ``` 311 | spring theme———>this is button 312 | Spring theme———>this is text field 313 | Spring theme———>this is comboxBox 314 | ——————————————————— 315 | Summer theme———>button 316 | Summer theme———>this is text field 317 | Summer theme———>this is comboBox 318 | ``` 319 | 320 | #### 示例程序的类图 321 | ![ ](https://raw.githubusercontent.com/YUbuntu0109/YUbuntu0109.github.io/HexoBackup/source/_posts/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BAbstract-Factory-Pattern/Abstract-Factory-Pattern-ClassDiagram.png) 322 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/Button.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 接口按钮, 充当抽象产品 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:18 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface Button { 12 | void display(); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:30 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | 15 | SkinFactory skinFactory = new SpringSkinFactory(); 16 | skinFactory.createButton().display(); 17 | skinFactory.createTextField().display(); 18 | skinFactory.createComboBox().display(); 19 | 20 | System.out.println("———————————————————"); 21 | 22 | SkinFactory skinFactory2 = new SummerSkinFactory(); 23 | skinFactory2.createButton().display(); 24 | skinFactory2.createTextField().display(); 25 | skinFactory2.createComboBox().display(); 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/ComboBox.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 组合框接口, 充当抽象产品 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:24 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface ComboBox { 12 | void display(); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/SkinFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 界面皮肤工厂接口, 充当抽象工厂 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:26 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface SkinFactory { 12 | 13 | Button createButton(); 14 | 15 | TextField createTextField(); 16 | 17 | ComboBox createComboBox(); 18 | } 19 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/SpringButton.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: Spring风格皮肤的按钮类, 充当具体产品 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:19 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class SpringButton implements Button { 12 | 13 | @Override 14 | public void display() { 15 | System.out.println("spring theme———>this is button"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/SpringComboBox.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: Spring风格皮肤的组合框类, 充当具体产品 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:25 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class SpringComboBox implements ComboBox { 12 | 13 | @Override 14 | public void display() { 15 | System.out.println("Spring theme———>this is comboxBox"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/SpringSkinFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: Spring皮肤风格的工厂类, 充当具体工厂 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:29 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class SpringSkinFactory implements SkinFactory { 12 | 13 | @Override 14 | public Button createButton() { 15 | return new SpringButton(); 16 | } 17 | 18 | @Override 19 | public TextField createTextField() { 20 | return new SpringTextField(); 21 | } 22 | 23 | @Override 24 | public ComboBox createComboBox() { 25 | return new SpringComboBox(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/SpringTextField.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: Spring风格皮肤的文本框类, 充当具体产品 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:22 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class SpringTextField implements TextField { 12 | 13 | @Override 14 | public void display() { 15 | System.out.println("Spring theme———>this is text field"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/SummerButton.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: Summer风格皮肤的按钮类, 充当具体产品 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:20 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class SummerButton implements Button { 12 | 13 | @Override 14 | public void display() { 15 | System.out.println("Summer theme———>button"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/SummerComboBox.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: Summer风格皮肤的组合框类, 充当具体产品 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:25 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class SummerComboBox implements ComboBox { 12 | 13 | @Override 14 | public void display() { 15 | System.out.println("Summer theme———>this is comboBox"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/SummerSkinFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: Summer风格皮肤的工厂类, 充当具体工厂 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:33 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class SummerSkinFactory implements SkinFactory { 12 | 13 | @Override 14 | public Button createButton() { 15 | return new SummerButton(); 16 | } 17 | 18 | @Override 19 | public TextField createTextField() { 20 | return new SummerTextField(); 21 | } 22 | 23 | @Override 24 | public ComboBox createComboBox() { 25 | return new SummerComboBox(); 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/SummerTextField.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: Summer风格皮肤的文本框类, 充当具体产品 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:23 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class SummerTextField implements TextField { 12 | 13 | @Override 14 | public void display() { 15 | System.out.println("Summer theme———>this is text field"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/abstract_factory_pattern/abstract_factory_pattern_1/TextField.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.abstract_factory_pattern.abstract_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文本框接口, 充当抽象产品 6 | * @author: 黄宇辉 7 | * @date: 9/7/2019-5:22 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface TextField { 12 | void display(); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/adapter_pattern/adapter1/Banner.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.adapter_pattern.adapter1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当Adaptee角色 6 | * @author: 黄宇辉 7 | * @date: 9/3/2019-4:12 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Banner { 12 | private String string; 13 | 14 | public Banner(String string) { 15 | this.string = string; 16 | } 17 | 18 | public void showWithParen() { 19 | System.out.println("(" + string + ")"); 20 | } 21 | 22 | public void showWithAster() { 23 | System.out.println("*" + string + "*"); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/adapter_pattern/adapter1/Main.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.adapter_pattern.adapter1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当Client角色 6 | * @author: 黄宇辉 7 | * @date: 9/3/2019-4:17 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Main { 12 | public static void main(String[] args) { 13 | Print print = new PrintBanner("Hello"); 14 | print.printWeak(); 15 | print.printStrong(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/adapter_pattern/adapter1/Print.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.adapter_pattern.adapter1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当Target角色 6 | * @author: 黄宇辉 7 | * @date: 9/3/2019-4:15 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface Print { 12 | void printWeak(); 13 | 14 | void printStrong(); 15 | } 16 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/adapter_pattern/adapter1/PrintBanner.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.adapter_pattern.adapter1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当Adapter角色 6 | * @author: 黄宇辉 7 | * @date: 9/3/2019-4:16 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class PrintBanner extends Banner implements Print { 12 | 13 | public PrintBanner(String string) { 14 | super(string); 15 | } 16 | 17 | @Override 18 | public void printWeak() { 19 | super.showWithParen(); 20 | } 21 | 22 | @Override 23 | public void printStrong() { 24 | super.showWithAster(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/adapter_pattern/adapter2/Banner.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.adapter_pattern.adapter2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当Adaptee角色 6 | * @author: 黄宇辉 7 | * @date: 9/3/2019-4:23 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Banner { 12 | private String string; 13 | 14 | public Banner(String string) { 15 | this.string = string; 16 | } 17 | 18 | public void showWithParen() { 19 | System.out.println("(" + string + ")"); 20 | } 21 | 22 | public void showWithAster() { 23 | System.out.println("*" + string + "*"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/adapter_pattern/adapter2/Main.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.adapter_pattern.adapter2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当Client角色 6 | * @author: 黄宇辉 7 | * @date: 9/3/2019-4:26 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Main { 12 | 13 | public static void main(String[] args) { 14 | Print print = new PrintBanner("Adapter Pattern"); 15 | print.printWeak(); 16 | print.pintStrong(); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/adapter_pattern/adapter2/Print.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.adapter_pattern.adapter2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当Target角色 6 | * @author: 黄宇辉 7 | * @date: 9/3/2019-4:21 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class Print { 12 | public abstract void printWeak(); 13 | 14 | public abstract void pintStrong(); 15 | } 16 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/adapter_pattern/adapter2/PrintBanner.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.adapter_pattern.adapter2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当Adapter角色 6 | * @author: 黄宇辉 7 | * @date: 9/3/2019-4:22 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class PrintBanner extends Print { 12 | 13 | private Banner banner; 14 | 15 | public PrintBanner(String string) { 16 | this.banner = new Banner(string); 17 | } 18 | 19 | @Override 20 | public void printWeak() { 21 | banner.showWithParen(); 22 | } 23 | 24 | @Override 25 | public void pintStrong() { 26 | banner.showWithAster(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/adapter_pattern/adapter3/MyController.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.adapter_pattern.adapter3; 2 | 3 | import javax.swing.*; 4 | import java.awt.event.MouseAdapter; 5 | import java.awt.event.MouseEvent; 6 | import java.awt.event.WindowAdapter; 7 | import java.awt.event.WindowEvent; 8 | 9 | /** 10 | * @project: design-patterns 11 | * @description: 测试 12 | * @author: 黄宇辉 13 | * @date: 9/3/2019-4:47 PM 14 | * @version: 1.0 15 | * @website: https://yubuntu0109.github.io/ 16 | */ 17 | public class MyController { 18 | public static void main(String[] args) { 19 | MyEventService myEventService = new MyEventService(); 20 | JFrame j = new JFrame("title"); 21 | j.setSize(500, 300); 22 | j.setVisible(true); 23 | j.setLocationRelativeTo(null); 24 | j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 25 | 26 | //绑定事件 27 | j.addWindowListener(new WindowAdapter() { 28 | @Override 29 | public void windowOpened(WindowEvent e) { 30 | myEventService.windowOpened(e); 31 | } 32 | 33 | @Override 34 | public void windowClosing(WindowEvent e) { 35 | myEventService.windowClosing(e); 36 | } 37 | }); 38 | j.addMouseListener(new MouseAdapter() { 39 | @Override 40 | public void mouseClicked(MouseEvent e) { 41 | myEventService.mouseClicked(e); 42 | } 43 | }); 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/adapter_pattern/adapter3/MyEventService.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.adapter_pattern.adapter3; 2 | 3 | import java.awt.event.MouseEvent; 4 | import java.awt.event.WindowEvent; 5 | 6 | /** 7 | * @project: design-patterns 8 | * @description: 充当具体业务类 9 | * @author: 黄宇辉 10 | * @date: 9/3/2019-4:40 PM 11 | * @version: 1.0 12 | * @website: https://yubuntu0109.github.io/ 13 | */ 14 | public class MyEventService extends MyWindowAdapter { 15 | 16 | @Override 17 | public void windowOpened(WindowEvent e) { 18 | System.out.println("windowOpened : Hello"); 19 | } 20 | 21 | @Override 22 | public void windowClosing(WindowEvent e) { 23 | System.out.println("windowClosing : Bye"); 24 | } 25 | 26 | @Override 27 | public void mouseClicked(MouseEvent e) { 28 | System.out.println("mouseClicked : Clicked"); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/adapter_pattern/adapter3/MyWindowAdapter.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.adapter_pattern.adapter3; 2 | 3 | import java.awt.event.MouseEvent; 4 | import java.awt.event.MouseListener; 5 | import java.awt.event.WindowEvent; 6 | import java.awt.event.WindowListener; 7 | 8 | /** 9 | * @project: design-patterns 10 | * @description: 充当缺省适配器类 11 | * @author: 黄宇辉 12 | * @date: 9/3/2019-4:35 PM 13 | * @version: 1.0 14 | * @website: https://yubuntu0109.github.io/ 15 | */ 16 | public abstract class MyWindowAdapter implements WindowListener, MouseListener { 17 | 18 | 19 | @Override 20 | public void mouseClicked(MouseEvent e) { 21 | 22 | } 23 | 24 | @Override 25 | public void mousePressed(MouseEvent e) { 26 | 27 | } 28 | 29 | @Override 30 | public void mouseReleased(MouseEvent e) { 31 | 32 | } 33 | 34 | @Override 35 | public void mouseEntered(MouseEvent e) { 36 | 37 | } 38 | 39 | @Override 40 | public void mouseExited(MouseEvent e) { 41 | 42 | } 43 | 44 | @Override 45 | public void windowOpened(WindowEvent e) { 46 | 47 | } 48 | 49 | @Override 50 | public void windowClosing(WindowEvent e) { 51 | 52 | } 53 | 54 | @Override 55 | public void windowClosed(WindowEvent e) { 56 | 57 | } 58 | 59 | @Override 60 | public void windowIconified(WindowEvent e) { 61 | 62 | } 63 | 64 | @Override 65 | public void windowDeiconified(WindowEvent e) { 66 | 67 | } 68 | 69 | @Override 70 | public void windowActivated(WindowEvent e) { 71 | 72 | } 73 | 74 | @Override 75 | public void windowDeactivated(WindowEvent e) { 76 | 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/builder_pattern/builder_pattern_1/Actor.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.builder_pattern.builder_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 游戏角色类, 充当复杂产品对象 6 | * @author: 黄宇辉 7 | * @date: 9/19/2019-1:30 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Actor { 12 | private String type; //角色类型 13 | private String sex; //性别 14 | private String face; //脸型 15 | private String costume; //服装 16 | 17 | public String getType() { 18 | return type; 19 | } 20 | 21 | public void setType(String type) { 22 | this.type = type; 23 | } 24 | 25 | public String getSex() { 26 | return sex; 27 | } 28 | 29 | public void setSex(String sex) { 30 | this.sex = sex; 31 | } 32 | 33 | public String getFace() { 34 | return face; 35 | } 36 | 37 | public void setFace(String face) { 38 | this.face = face; 39 | } 40 | 41 | public String getCostume() { 42 | return costume; 43 | } 44 | 45 | public void setCostume(String costume) { 46 | this.costume = costume; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return "Actor{" + 52 | "type='" + type + '\'' + 53 | ", sex='" + sex + '\'' + 54 | ", face='" + face + '\'' + 55 | ", costume='" + costume + '\'' + 56 | '}'; 57 | } 58 | } -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/builder_pattern/builder_pattern_1/ActorBuilder.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.builder_pattern.builder_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 游戏角色建造者, 充当抽象建造者 6 | * @author: 黄宇辉 7 | * @date: 9/19/2019-1:39 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class ActorBuilder { 12 | protected Actor actor = new Actor(); 13 | 14 | public abstract void buildType(); 15 | 16 | public abstract void buildSex(); 17 | 18 | public abstract void buildFace(); 19 | 20 | public abstract void buildCostume(); 21 | 22 | //工厂方法,返回一个完整的游戏角色对象 23 | public Actor createActor() { 24 | return actor; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/builder_pattern/builder_pattern_1/ActorController.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.builder_pattern.builder_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 角色控制器, 充当指挥者 6 | * @author: 黄宇辉 7 | * @date: 9/19/2019-1:46 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class ActorController { 12 | 13 | //逐步构建复杂产品对象 14 | public Actor construct(ActorBuilder actorBuilder) { 15 | Actor actor; 16 | actorBuilder.buildType(); 17 | actorBuilder.buildSex(); 18 | actorBuilder.buildFace(); 19 | actorBuilder.buildCostume(); 20 | actor = actorBuilder.createActor(); 21 | return actor; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/builder_pattern/builder_pattern_1/AngelBuilder.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.builder_pattern.builder_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 天使角色建造者, 充当具体建造类 6 | * @author: 黄宇辉 7 | * @date: 9/19/2019-1:44 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class AngelBuilder extends ActorBuilder { 12 | 13 | @Override 14 | public void buildType() { 15 | actor.setType("天使"); 16 | } 17 | 18 | @Override 19 | public void buildSex() { 20 | actor.setSex("女"); 21 | } 22 | 23 | @Override 24 | public void buildFace() { 25 | actor.setFace("漂亮"); 26 | } 27 | 28 | @Override 29 | public void buildCostume() { 30 | actor.setCostume("裙子"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/builder_pattern/builder_pattern_1/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.builder_pattern.builder_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/19/2019-1:49 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | ActorController actorController = new ActorController(); 15 | 16 | ActorBuilder zero = new HeroBuilder(); 17 | Actor actor_zero = actorController.construct(zero); 18 | System.out.println(actor_zero); 19 | 20 | System.out.println("------------------------------"); 21 | 22 | ActorBuilder angel = new AngelBuilder(); 23 | Actor actor_angel = actorController.construct(angel); 24 | System.out.println(actor_angel); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/builder_pattern/builder_pattern_1/HeroBuilder.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.builder_pattern.builder_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 英雄角色建造者, 充当具体建造者 6 | * @author: 黄宇辉 7 | * @date: 9/19/2019-1:42 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class HeroBuilder extends ActorBuilder { 12 | @Override 13 | public void buildType() { 14 | actor.setType("英雄"); 15 | } 16 | 17 | @Override 18 | public void buildSex() { 19 | actor.setSex("男"); 20 | } 21 | 22 | @Override 23 | public void buildFace() { 24 | actor.setFace("英俊"); 25 | } 26 | 27 | @Override 28 | public void buildCostume() { 29 | actor.setCostume("盔甲"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/builder_pattern/builder_pattern_2/Actor.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.builder_pattern.builder_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 游戏角色类, 充当复杂产品对象 6 | * @author: 黄宇辉 7 | * @date: 9/19/2019-1:30 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Actor { 12 | private String type; //角色类型 13 | private String sex; //性别 14 | private String face; //脸型 15 | private String costume; //服装 16 | 17 | public String getType() { 18 | return type; 19 | } 20 | 21 | public void setType(String type) { 22 | this.type = type; 23 | } 24 | 25 | public String getSex() { 26 | return sex; 27 | } 28 | 29 | public void setSex(String sex) { 30 | this.sex = sex; 31 | } 32 | 33 | public String getFace() { 34 | return face; 35 | } 36 | 37 | public void setFace(String face) { 38 | this.face = face; 39 | } 40 | 41 | public String getCostume() { 42 | return costume; 43 | } 44 | 45 | public void setCostume(String costume) { 46 | this.costume = costume; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return "Actor{" + 52 | "type='" + type + '\'' + 53 | ", sex='" + sex + '\'' + 54 | ", face='" + face + '\'' + 55 | ", costume='" + costume + '\'' + 56 | '}'; 57 | } 58 | } -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/builder_pattern/builder_pattern_2/ActorBuilder.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.builder_pattern.builder_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 游戏角色建造者, 充当抽象建造者(省略Director并简化construct方法) 6 | * @author: 黄宇辉 7 | * @date: 9/19/2019-1:39 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class ActorBuilder { 12 | protected Actor actor = new Actor(); 13 | 14 | public abstract void buildType(); 15 | 16 | public abstract void buildSex(); 17 | 18 | public abstract void buildFace(); 19 | 20 | public abstract void buildCostume(); 21 | 22 | //工厂方法,返回一个完整的游戏角色对象 23 | //public Actor createActor() { 24 | // return actor; 25 | //} 26 | 27 | //逐步构建复杂产品对象 28 | public Actor construct() { 29 | this.buildType(); 30 | this.buildSex(); 31 | this.buildFace(); 32 | this.buildCostume(); 33 | return actor; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/builder_pattern/builder_pattern_2/AngelBuilder.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.builder_pattern.builder_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 天使角色建造者, 充当具体建造类 6 | * @author: 黄宇辉 7 | * @date: 9/19/2019-1:44 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class AngelBuilder extends ActorBuilder { 12 | 13 | @Override 14 | public void buildType() { 15 | actor.setType("天使"); 16 | } 17 | 18 | @Override 19 | public void buildSex() { 20 | actor.setSex("女"); 21 | } 22 | 23 | @Override 24 | public void buildFace() { 25 | actor.setFace("漂亮"); 26 | } 27 | 28 | @Override 29 | public void buildCostume() { 30 | actor.setCostume("裙子"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/builder_pattern/builder_pattern_2/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.builder_pattern.builder_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/19/2019-1:49 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | Actor zero = new HeroBuilder().construct(); 15 | System.out.println(zero); 16 | 17 | System.out.println("------------------------------"); 18 | 19 | Actor angel = new AngelBuilder().construct(); 20 | System.out.println(angel); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/builder_pattern/builder_pattern_2/HeroBuilder.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.builder_pattern.builder_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 英雄角色建造者, 充当具体建造者 6 | * @author: 黄宇辉 7 | * @date: 9/19/2019-1:42 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class HeroBuilder extends ActorBuilder { 12 | @Override 13 | public void buildType() { 14 | actor.setType("英雄"); 15 | } 16 | 17 | @Override 18 | public void buildSex() { 19 | actor.setSex("男"); 20 | } 21 | 22 | @Override 23 | public void buildFace() { 24 | actor.setFace("英俊"); 25 | } 26 | 27 | @Override 28 | public void buildCostume() { 29 | actor.setCostume("盔甲"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_1/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/20/2019-9:11 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | FunctionButton functionButton = new FunctionButton(); 15 | Command login_key = new LoginInCommand(); 16 | functionButton.setCommand(login_key); 17 | functionButton.click(); 18 | 19 | System.out.println("--------------------"); 20 | 21 | Command exit_key = new LoginOutCommand(); 22 | functionButton.setCommand(exit_key); 23 | functionButton.click(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_1/Command.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象命令类 6 | * @author: 黄宇辉 7 | * @date: 9/20/2019-9:01 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class Command { 12 | public abstract void execute(); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_1/FunctionButton.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 功能键类, 充当请求调用者(请求发送者) 6 | * @author: 黄宇辉 7 | * @date: 9/20/2019-8:59 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class FunctionButton { 12 | 13 | private Command command; 14 | 15 | //为功能键注入命令 16 | public void setCommand(Command command) { 17 | this.command = command; 18 | } 19 | 20 | //发送请求的方法 21 | public void click() { 22 | command.execute(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_1/LoginInCommand.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 登录命令类, 充当具体命令类 6 | * @author: 黄宇辉 7 | * @date: 9/20/2019-9:07 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class LoginInCommand extends Command { 12 | 13 | private LoginInSystem enterSystem; 14 | 15 | public LoginInCommand() { 16 | this.enterSystem = new LoginInSystem(); 17 | } 18 | 19 | //命令执行方法,将调用请求接收者的业务方法 20 | @Override 21 | public void execute() { 22 | enterSystem.login(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_1/LoginInSystem.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 登录系统的模拟实现类, 充当请求接收者 6 | * @author: 黄宇辉 7 | * @date: 9/20/2019-9:10 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class LoginInSystem { 12 | 13 | public void login() { 14 | System.out.println("login in"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_1/LoginOutCommand.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 退出命令类, 充当具体命令类 6 | * @author: 黄宇辉 7 | * @date: 9/20/2019-9:05 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class LoginOutCommand extends Command { 12 | 13 | private LoginOutSystem exitSystem; 14 | 15 | public LoginOutCommand() { 16 | this.exitSystem = new LoginOutSystem(); 17 | } 18 | 19 | //命令执行方法,将调用请求接受者的业务方法 20 | @Override 21 | public void execute() { 22 | exitSystem.exit(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_1/LoginOutSystem.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 退出系统的模拟实现类, 充当请求接收者 6 | * @author: 黄宇辉 7 | * @date: 9/20/2019-9:08 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class LoginOutSystem { 12 | 13 | public void exit() { 14 | System.out.println("login out"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_2/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_2; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | import java.awt.event.MouseEvent; 6 | import java.awt.event.MouseMotionAdapter; 7 | 8 | /** 9 | * @project: design-patterns 10 | * @description: 客户端测试类 11 | * @author: 黄宇辉 12 | * @date: 9/20/2019-9:48 PM 13 | * @version: 1.0 14 | * @website: https://yubuntu0109.github.io/ 15 | */ 16 | public class Client extends JFrame { 17 | 18 | //绘制的历史记录 19 | private MacroCommand history = new MacroCommand(); 20 | //绘制区域(设置画板大小) 21 | private DrawCanvas canvas = new DrawCanvas(600, 400, history); 22 | //删除按钮 23 | private JButton clearButton = new JButton("clear"); 24 | 25 | public Client(String title) { 26 | super(title); 27 | 28 | /* 29 | 鼠标拖动事件 30 | */ 31 | canvas.addMouseMotionListener(new MouseMotionAdapter() { 32 | @Override 33 | public void mouseDragged(MouseEvent e) { 34 | Command command = new DrawCommand(canvas, e.getPoint()); 35 | history.append(command); 36 | command.execute(); 37 | } 38 | }); 39 | 40 | /* 41 | 动作监听事件 42 | */ 43 | clearButton.addActionListener(e -> { 44 | if (e.getSource() == clearButton) { 45 | history.clear(); 46 | canvas.repaint(); 47 | } 48 | }); 49 | 50 | /* 51 | JFrame面板配置 52 | */ 53 | setLayout(new BorderLayout()); 54 | add(clearButton, BorderLayout.NORTH); 55 | add(canvas, BorderLayout.SOUTH); 56 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 57 | pack(); 58 | setVisible(true); 59 | } 60 | 61 | public static void main(String[] args) { 62 | new Client("a simple drawing board"); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_2/Command.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 表示"命令"的接口,充当(抽象)命令 6 | * @author: 黄宇辉 7 | * @date: 9/20/2019-9:25 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface Command { 12 | void execute(); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_2/DrawCanvas.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_2; 2 | 3 | import java.awt.*; 4 | 5 | /** 6 | * @project: design-patterns 7 | * @description: 实现"绘制对象"的类,充当接收者 8 | * @author: 黄宇辉 9 | * @date: 9/20/2019-9:39 PM 10 | * @version: 1.0 11 | * @website: https://yubuntu0109.github.io/ 12 | */ 13 | public class DrawCanvas extends Canvas implements Drawable { 14 | 15 | //颜色 16 | private Color color = Color.green; 17 | //要绘制的圆点半径 18 | private int redius = 5; 19 | //命令的历史记录 20 | private MacroCommand history; 21 | 22 | //构造函数 23 | public DrawCanvas(int width, int height, MacroCommand history) { 24 | this.setSize(width, height); 25 | this.setBackground(Color.white); 26 | this.history = history; 27 | } 28 | 29 | //重新全部绘制 30 | public void repaint(Graphics graphics) { 31 | history.execute(); 32 | } 33 | 34 | //绘制 35 | @Override 36 | public void draw(int x, int y) { 37 | Graphics graphics = getGraphics(); 38 | graphics.setColor(color); 39 | graphics.fillOval(x - redius, y - redius, redius * 2, redius * 2); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_2/DrawCommand.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_2; 2 | 3 | import java.awt.*; 4 | 5 | /** 6 | * @project: design-patterns 7 | * @description: 表示"绘制一个点的命令"的类,充当具体的命令 8 | * @author: 黄宇辉 9 | * @date: 9/20/2019-9:33 PM 10 | * @version: 1.0 11 | * @website: https://yubuntu0109.github.io/ 12 | */ 13 | public class DrawCommand implements Command { 14 | 15 | //绘制对象 16 | protected Drawable drawable; 17 | 18 | //绘制位置 19 | private Point position; 20 | 21 | //构造函数 22 | public DrawCommand(Drawable drawable, Point position) { 23 | this.drawable = drawable; 24 | this.position = position; 25 | } 26 | 27 | //执行命令 28 | @Override 29 | public void execute() { 30 | drawable.draw(position.x, position.y); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_2/Drawable.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 表示"绘制对象"的接口 6 | * @author: 黄宇辉 7 | * @date: 9/20/2019-9:37 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface Drawable { 12 | void draw(int x, int y); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/command_pattern/command_pattern_2/MacroCommand.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.command_pattern.command_pattern_2; 2 | 3 | import java.util.Stack; 4 | 5 | /** 6 | * @project: design-patterns 7 | * @description: 表示"由多条命令整合成的命令"的类,充当具体的命令 8 | * @author: 黄宇辉 9 | * @date: 9/20/2019-9:27 PM 10 | * @version: 1.0 11 | * @website: https://yubuntu0109.github.io/ 12 | */ 13 | public class MacroCommand implements Command { 14 | 15 | //命令的集合 16 | private Stack commands = new Stack(); 17 | 18 | //执行命令 19 | @Override 20 | public void execute() { 21 | for (Object command : commands) { 22 | ((Command) command).execute(); 23 | } 24 | } 25 | 26 | //添加命令 27 | public void append(Command command) { 28 | if (command != this) { 29 | commands.push(command); 30 | } 31 | } 32 | 33 | //清除命令 34 | public void clear() { 35 | commands.clear(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/composite_pattern/composite_pattern_1/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.composite_pattern.composite_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/11/2019-12:36 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | try { 15 | System.out.println("------ Making Root Entries ------"); 16 | Directory rootdir = new Directory("root"); 17 | Directory bindir = new Directory("bin"); 18 | Directory temdir = new Directory("tmp"); 19 | Directory usrdir = new Directory("usr"); 20 | rootdir.add(bindir); 21 | rootdir.add(temdir); 22 | rootdir.add(usrdir); 23 | bindir.add(new File("demo1.class", 10000)); 24 | bindir.add(new File("demo2.class", 20000)); 25 | rootdir.printList(); 26 | 27 | System.out.println("\n" + "------ Making User Entries ------"); 28 | Directory demoDir1 = new Directory("demoDir1"); 29 | Directory demoDir2 = new Directory("demoDir2"); 30 | Directory demoDir3 = new Directory("demoDir3"); 31 | usrdir.add(demoDir1); 32 | usrdir.add(demoDir2); 33 | usrdir.add(demoDir3); 34 | demoDir1.add(new File("demo.html", 100)); 35 | demoDir1.add(new File("demo.java", 200)); 36 | demoDir2.add(new File("demo.txt", 300)); 37 | demoDir3.add(new File("demo.doc", 400)); 38 | demoDir3.add(new File("demo.mail", 500)); 39 | rootdir.printList(); 40 | } catch (FileTreatMentException e) { 41 | e.printStackTrace(); 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/composite_pattern/composite_pattern_1/Directory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.composite_pattern.composite_pattern_1; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * @project: design-patterns 7 | * @description: 表示文件夹的类, 充当Composite角色 8 | * @author: 黄宇辉 9 | * @date: 9/11/2019-12:25 PM 10 | * @version: 1.0 11 | * @website: https://yubuntu0109.github.io/ 12 | */ 13 | public class Directory extends Entry { 14 | 15 | private String name; 16 | private ArrayList directory = new ArrayList<>(); 17 | 18 | public Directory(String name) { 19 | this.name = name; 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | @Override 28 | public int getSize() { 29 | var size = 0; 30 | for (Entry entry : directory) { 31 | size += entry.getSize(); 32 | } 33 | return size; 34 | } 35 | 36 | @Override 37 | public Entry add(Entry entry) { 38 | directory.add(entry); 39 | return this; 40 | } 41 | 42 | @Override 43 | protected void printList(String prefix) { 44 | System.out.println(prefix + "/" + this.toString()); 45 | for (Entry entry : directory) { 46 | entry.printList(prefix + "/" + name); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/composite_pattern/composite_pattern_1/Entry.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.composite_pattern.composite_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 表示目录条目的抽象类, 充当Component角色 6 | * @author: 黄宇辉 7 | * @date: 9/11/2019-12:16 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class Entry { 12 | 13 | public abstract String getName(); 14 | 15 | public abstract int getSize(); 16 | 17 | public Entry add(Entry entry) throws FileTreatMentException { 18 | throw new FileTreatMentException(); 19 | } 20 | 21 | public void printList() { 22 | printList(""); 23 | } 24 | 25 | protected abstract void printList(String prefix); 26 | 27 | public String toString() { 28 | return getName() + " (" + getSize() + ")"; 29 | } 30 | } -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/composite_pattern/composite_pattern_1/File.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.composite_pattern.composite_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 表示文件的类, 充当Leaf角色 6 | * @author: 黄宇辉 7 | * @date: 9/11/2019-12:22 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class File extends Entry { 12 | 13 | private String name; 14 | private int size; 15 | 16 | public File(String name, int size) { 17 | this.name = name; 18 | this.size = size; 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | @Override 27 | public int getSize() { 28 | return size; 29 | } 30 | 31 | @Override 32 | protected void printList(String prefix) { 33 | System.out.println(prefix + "/" + this.toString()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/composite_pattern/composite_pattern_1/FileTreatMentException.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.composite_pattern.composite_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 自定义异常类 6 | * @author: 黄宇辉 7 | * @date: 9/11/2019-12:19 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class FileTreatMentException extends RuntimeException { 12 | 13 | public FileTreatMentException() { 14 | 15 | } 16 | 17 | public FileTreatMentException(String msg) { 18 | super(msg); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/composite_pattern/composite_pattern_2/AbstractFile.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.composite_pattern.composite_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象文件类, 充当抽象构件类 6 | * @author: 黄宇辉 7 | * @date: 9/11/2019-1:19 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class AbstractFile { 12 | 13 | public abstract String getName(); 14 | 15 | public abstract void killVirus(); 16 | 17 | public void add(AbstractFile file) { 18 | throw new FileTreatMentException(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/composite_pattern/composite_pattern_2/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.composite_pattern.composite_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/11/2019-1:44 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | AbstractFile folder = new Folder("my-folder"); 15 | AbstractFile textFolder = new Folder("text-folder"); 16 | AbstractFile imageFolder = new Folder("image-folder"); 17 | AbstractFile file = new TextFile("demo.text"); 18 | AbstractFile image = new ImageFile("demo.jpg"); 19 | textFolder.add(file); 20 | imageFolder.add(image); 21 | folder.add(textFolder); 22 | folder.add(imageFolder); 23 | folder.killVirus(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/composite_pattern/composite_pattern_2/FileTreatMentException.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.composite_pattern.composite_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 自定义异常类 6 | * @author: 黄宇辉 7 | * @date: 9/11/2019-12:19 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class FileTreatMentException extends RuntimeException { 12 | 13 | public FileTreatMentException() { 14 | 15 | } 16 | 17 | public FileTreatMentException(String msg) { 18 | super(msg); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/composite_pattern/composite_pattern_2/Folder.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.composite_pattern.composite_pattern_2; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * @project: design-patterns 7 | * @description: 文件夹类, 充当容器构件类 8 | * @author: 黄宇辉 9 | * @date: 9/11/2019-1:38 PM 10 | * @version: 1.0 11 | * @website: https://yubuntu0109.github.io/ 12 | */ 13 | public class Folder extends AbstractFile { 14 | 15 | private String name; 16 | private ArrayList directory = new ArrayList<>(); 17 | 18 | public Folder(String name) { 19 | this.name = name; 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | @Override 28 | public void add(AbstractFile file) { 29 | directory.add(file); 30 | } 31 | 32 | @Override 33 | public void killVirus() { 34 | System.out.println("======> 对文件夹[ " + name + " ]进行杀毒"); 35 | //递归调用成员构件的killVirus方法 36 | for (AbstractFile abstractFile : directory) { 37 | abstractFile.killVirus(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/composite_pattern/composite_pattern_2/ImageFile.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.composite_pattern.composite_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 图像文件类, 充当叶子构件类 6 | * @author: 黄宇辉 7 | * @date: 9/11/2019-1:27 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class ImageFile extends AbstractFile { 12 | 13 | private String name; 14 | 15 | public ImageFile(String name) { 16 | this.name = name; 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | @Override 25 | public void killVirus() { 26 | System.out.println("——————> 对图像文件[ " + name + " ]进行杀毒"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/composite_pattern/composite_pattern_2/TextFile.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.composite_pattern.composite_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文本文件类, 充当叶子构件类 6 | * @author: 黄宇辉 7 | * @date: 9/11/2019-1:31 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class TextFile extends AbstractFile { 12 | 13 | private String name; 14 | 15 | public TextFile(String name) { 16 | this.name = name; 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | @Override 25 | public void killVirus() { 26 | System.out.println("——————> 对文本文件[ " + name + " ]进行杀毒"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/decorator_pattern/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Java设计模式之Decorator Pattern 3 | date: 2019-09-08 21:47:30 4 | tags: [Java,design and pattern] 5 | --- 6 | 7 | ## 学习笔记 : Java设计模式之Decorator Pattern 8 | 9 | ### 概述 10 | *装饰设计模式( 对象结构型模式 )是一种用于替代继承的技术,它通过一种无须定义子类的方式来给对象动态增加职责,使用对象之间的关联关系取代类之间的继承关系. 装饰设计模式的定位为 : 动态地给一个对象增加一些额外的职责. 就扩展而言,装饰模式提供了一种比使用子类更加灵活的替代方案. ( Decorator Pattern : Attach additonal responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality )* 11 | 12 | 13 | ### 装饰设计模式中的角色 14 | 1. *`Component ( 抽象构件 )` : 它是`具体构件`和`抽象装饰类`的共同父类,声明了在具体构件中实现的业务方法,它的引入可以使客户端以一致的方式处理未被装饰的对象及装饰之后的对象,实现客户端的透明操作.* 15 | 2. *`ConcreteComponent ( 具体构件 )` : 它是`抽象构件类`的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰类可以给它增加额外的职责( 方法 )* 16 | 3. *`Decorator ( 抽象装饰类 )` : 它也是`抽象构件类`的子类,用于给`具体构件`增加职责,但是具体职责在其子类中实现. 它维护一个指向抽象构件的引用,通过该引用可以调用装饰之前构件对象的方法,并通过子类扩展该方法,继而达到装饰的目的.* 17 | 4. *`ConcreteDecorator ( 具体装饰类 )` : 它是`抽象装饰类`的子类,负责向构件添加新的职责. 每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用于扩展对象的行为.* 18 | 19 | 20 | ### 示例程序-透明装饰模式 21 | *下面是一个使用了装饰设计模式的简单示例程序,其示例说明为 : 使用面向对象技术开发了一套图形界面构件库,该构件库提供了大量的基本结构,如窗体,文本框,列表框等,由于在使用时用户经常要求定制一些特殊的显示效果,如带滚动条的窗体,或带黑色边框的文本框等. 因此经常需要对该构件库进行扩展以增强其功能,既而可以使用装饰设计模式来设计该界面构件库哟~* 22 | 23 | 1. *Component接口 : 抽象界面构件类, 充当抽象构件类* 24 | ```java 25 | package pers.huangyuhui.decorator_pattern; 26 | 27 | /** 28 | * @project: design-patterns 29 | * @description: 抽象界面构件类, 充当抽象构件类 30 | * @author: 黄宇辉 31 | * @date: 9/9/2019-2:47 PM 32 | * @version: 1.0 33 | * @website: https://yubuntu0109.github.io/ 34 | */ 35 | public abstract class Component { 36 | 37 | public abstract void display(); 38 | } 39 | ``` 40 | 41 | 2. *Window类 : 窗体类, 充当具体构件类* 42 | ```java 43 | package pers.huangyuhui.decorator_pattern; 44 | 45 | /** 46 | * @project: design-patterns 47 | * @description: 窗体类, 充当具体构件类 48 | * @author: 黄宇辉 49 | * @date: 9/9/2019-2:48 PM 50 | * @version: 1.0 51 | * @website: https://yubuntu0109.github.io/ 52 | */ 53 | public class Window extends Component { 54 | 55 | @Override 56 | public void display() { 57 | System.out.println("显示窗体 !"); 58 | } 59 | } 60 | ``` 61 | 62 | 3. *TextBox类 : 文本框类, 充当具体构件类* 63 | ```java 64 | package pers.huangyuhui.decorator_pattern; 65 | 66 | /** 67 | * @project: design-patterns 68 | * @description: 文本框类, 充当具体构件类 69 | * @author: 黄宇辉 70 | * @date: 9/9/2019-2:50 PM 71 | * @version: 1.0 72 | * @website: https://yubuntu0109.github.io/ 73 | */ 74 | public class TextBox extends Component { 75 | @Override 76 | public void display() { 77 | System.out.println("显示文本框 !"); 78 | } 79 | } 80 | ``` 81 | 82 | 4. *ListBox类 : 列表框类, 充当具体构件类* 83 | ```java 84 | package pers.huangyuhui.decorator_pattern; 85 | 86 | /** 87 | * @project: design-patterns 88 | * @description: 列表框类, 充当具体构件类 89 | * @author: 黄宇辉 90 | * @date: 9/9/2019-2:51 PM 91 | * @version: 1.0 92 | * @website: https://yubuntu0109.github.io/ 93 | */ 94 | public class ListBox extends Component { 95 | 96 | @Override 97 | public void display() { 98 | System.out.println("显示列表框 !"); 99 | } 100 | } 101 | ``` 102 | 103 | 5. *ComponentDecorator类 : 构件装饰类, 充当抽象装饰类* 104 | ```java 105 | package pers.huangyuhui.decorator_pattern; 106 | 107 | /** 108 | * @project: design-patterns 109 | * @description: 构件装饰类, 充当抽象装饰类 110 | * @author: 黄宇辉 111 | * @date: 9/9/2019-2:52 PM 112 | * @version: 1.0 113 | * @website: https://yubuntu0109.github.io/ 114 | */ 115 | public class ComponentDecorator extends Component { 116 | 117 | //维持对抽象构件类型对象的引用 118 | private Component component; 119 | 120 | //注入抽象构件类型的对象 121 | public ComponentDecorator(Component component) { 122 | this.component = component; 123 | } 124 | 125 | @Override 126 | public void display() { 127 | component.display(); 128 | } 129 | } 130 | ``` 131 | 132 | 6. *ScrollBarDecorator类 : 滚动条装饰类, 充当具体装饰类* 133 | ```java 134 | package pers.huangyuhui.decorator_pattern; 135 | 136 | /** 137 | * @project: design-patterns 138 | * @description: 滚动条装饰类, 充当具体装饰类 139 | * @author: 黄宇辉 140 | * @date: 9/9/2019-2:54 PM 141 | * @version: 1.0 142 | * @website: https://yubuntu0109.github.io/ 143 | */ 144 | public class ScrollBarDecorator extends ComponentDecorator { 145 | 146 | public ScrollBarDecorator(Component component) { 147 | super(component); 148 | } 149 | 150 | @Override 151 | public void display() { 152 | this.setScrollBar(); 153 | super.display(); 154 | } 155 | 156 | private void setScrollBar() { 157 | System.out.println("为构件添加滚动条 !"); 158 | } 159 | } 160 | ``` 161 | 162 | 7. *BlackBorderDecorator类 : 黑色边框装饰类, 充当具体装饰类* 163 | ```java 164 | package pers.huangyuhui.decorator_pattern; 165 | 166 | /** 167 | * @project: design-patterns 168 | * @description: 黑色边框装饰类, 充当具体装饰类 169 | * @author: 黄宇辉 170 | * @date: 9/9/2019-2:59 PM 171 | * @version: 1.0 172 | * @website: https://yubuntu0109.github.io/ 173 | */ 174 | public class BlackBorderDecorator extends ComponentDecorator { 175 | 176 | public BlackBorderDecorator(Component component) { 177 | super(component); 178 | } 179 | 180 | @Override 181 | public void display() { 182 | this.setBlackBorder(); 183 | super.display(); 184 | } 185 | 186 | private void setBlackBorder() { 187 | System.out.println("为构件添加黑色边框 !"); 188 | } 189 | } 190 | ``` 191 | 192 | 8. *Client类 : 客户端测试类* 193 | ```java 194 | package pers.huangyuhui.decorator_pattern; 195 | 196 | /** 197 | * @project: design-patterns 198 | * @description: 客户端测试类 199 | * @author: 黄宇辉 200 | * @date: 9/9/2019-3:03 PM 201 | * @version: 1.0 202 | * @website: https://yubuntu0109.github.io/ 203 | */ 204 | public class Client { 205 | 206 | public static void main(String[] args) { 207 | Component component = new Window(); 208 | component.display(); 209 | 210 | System.out.println("------------------"); 211 | 212 | Component component2 = new ScrollBarDecorator(component); 213 | component2.display(); 214 | } 215 | } 216 | ``` 217 | 218 | #### 示例程序的类图 219 | ![ ](https://raw.githubusercontent.com/YUbuntu0109/YUbuntu0109.github.io/HexoBackup/source/_posts/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BDecorator-Pattern/Decorator-Pattern-ClassDiagram.png) 220 | 221 | 222 | 223 | ### 示例程序-半透明装饰模式 224 | *暂略 · · ·* 225 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/decorator_pattern/decorator_pattern_1/BlackBorderDecorator.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.decorator_pattern.decorator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 黑色边框装饰类, 充当具体装饰类 6 | * @author: 黄宇辉 7 | * @date: 9/9/2019-2:59 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class BlackBorderDecorator extends ComponentDecorator { 12 | 13 | public BlackBorderDecorator(Component component) { 14 | super(component); 15 | } 16 | 17 | @Override 18 | public void display() { 19 | this.setBlackBorder(); 20 | super.display(); 21 | } 22 | 23 | private void setBlackBorder() { 24 | System.out.println("为构件添加黑色边框 !"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/decorator_pattern/decorator_pattern_1/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.decorator_pattern.decorator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/9/2019-3:03 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | Component component = new Window(); 15 | component.display(); 16 | 17 | System.out.println("------------------"); 18 | 19 | Component component2 = new ScrollBarDecorator(component); 20 | component2.display(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/decorator_pattern/decorator_pattern_1/Component.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.decorator_pattern.decorator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象界面构件类, 充当抽象构件类 6 | * @author: 黄宇辉 7 | * @date: 9/9/2019-2:47 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class Component { 12 | public abstract void display(); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/decorator_pattern/decorator_pattern_1/ComponentDecorator.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.decorator_pattern.decorator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 构件装饰类, 充当抽象装饰类 6 | * @author: 黄宇辉 7 | * @date: 9/9/2019-2:52 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class ComponentDecorator extends Component { 12 | 13 | //维持对抽象构件类型对象的引用 14 | private Component component; 15 | 16 | //注入抽象构件类型的对象 17 | public ComponentDecorator(Component component) { 18 | this.component = component; 19 | } 20 | 21 | @Override 22 | public void display() { 23 | component.display(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/decorator_pattern/decorator_pattern_1/ListBox.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.decorator_pattern.decorator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 列表框类, 充当具体构件类 6 | * @author: 黄宇辉 7 | * @date: 9/9/2019-2:51 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class ListBox extends Component { 12 | 13 | @Override 14 | public void display() { 15 | System.out.println("显示列表框 !"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/decorator_pattern/decorator_pattern_1/ScrollBarDecorator.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.decorator_pattern.decorator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 滚动条装饰类, 充当具体装饰类 6 | * @author: 黄宇辉 7 | * @date: 9/9/2019-2:54 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class ScrollBarDecorator extends ComponentDecorator { 12 | 13 | public ScrollBarDecorator(Component component) { 14 | super(component); 15 | } 16 | 17 | @Override 18 | public void display() { 19 | this.setScrollBar(); 20 | super.display(); 21 | } 22 | 23 | private void setScrollBar() { 24 | System.out.println("为构件添加滚动条 !"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/decorator_pattern/decorator_pattern_1/TextBox.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.decorator_pattern.decorator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文本框类, 充当具体构件类 6 | * @author: 黄宇辉 7 | * @date: 9/9/2019-2:50 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class TextBox extends Component { 12 | 13 | @Override 14 | public void display() { 15 | System.out.println("显示文本框 !"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/decorator_pattern/decorator_pattern_1/Window.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.decorator_pattern.decorator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 窗体类, 充当具体构件类 6 | * @author: 黄宇辉 7 | * @date: 9/9/2019-2:48 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Window extends Component { 12 | 13 | @Override 14 | public void display() { 15 | System.out.println("显示窗体 !"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_1/CipherMachine.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 数据加密类(求模运算), 充当子系统类 6 | * @author: 黄宇辉 7 | * @date: 9/12/2019-9:42 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class CipherMachine { 12 | 13 | public String encrypt(String text) { 14 | var result = new StringBuilder(); 15 | for (int i = 0; i < text.length(); i++) { 16 | var s = String.valueOf(text.charAt(i) % 7); 17 | result.append(s); 18 | } 19 | return result.toString(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_1/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/14/2019-6:05 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | private static final String FROM_PATH = "src\\main\\java\\pers\\huangyuhui\\facade_pattern\\facade_pattern_1\\from.txt"; 14 | private static final String TO_PATH = "src\\main\\java\\pers\\huangyuhui\\facade_pattern\\facade_pattern_1\\to.txt"; 15 | 16 | public static void main(String[] args) { 17 | EncryptFacade encryptFacade = new EncryptFacade(); 18 | encryptFacade.fileEncrypt(FROM_PATH, TO_PATH); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_1/EncryptFacade.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 加密外观类, 充当外观类 6 | * @author: 黄宇辉 7 | * @date: 9/12/2019-9:59 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class EncryptFacade { 12 | 13 | //维持对子系统对象的引用 14 | private FileReader fileReader; 15 | private CipherMachine cipherMachine; 16 | private FileWriter fileWriter; 17 | 18 | public EncryptFacade() { 19 | fileReader = new FileReader(); 20 | cipherMachine = new CipherMachine(); 21 | fileWriter = new FileWriter(); 22 | } 23 | 24 | //调用子系统对象的业务方法 25 | public void fileEncrypt(String fromPath, String toPath) { 26 | var text = fileReader.read(fromPath); 27 | System.out.println(">>>>>>>>>> : 读取文件[ " + fromPath + " ]中的明文数据 : " + text); 28 | var encryptStr = cipherMachine.encrypt(text); 29 | System.out.println(">>>>>>>>>> : 明文数据加密后的结果 : " + encryptStr); 30 | fileWriter.write(encryptStr, toPath); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_1/FileReader.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_1; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | 6 | /** 7 | * @project: design-patterns 8 | * @description: 文件读取类, 充当子系统类 9 | * @author: 黄宇辉 10 | * @date: 9/12/2019-9:36 PM 11 | * @version: 1.0 12 | * @website: https://yubuntu0109.github.io/ 13 | */ 14 | public class FileReader { 15 | 16 | public String read(String path) { 17 | var stringBuffer = new StringBuilder(); 18 | try (var fileInputStream = new FileInputStream(path)) { 19 | var data = 0; 20 | while ((data = fileInputStream.read()) != -1) { 21 | stringBuffer.append((char) data); //char 22 | } 23 | } catch (IOException e) { 24 | e.printStackTrace(); 25 | } 26 | return stringBuffer.toString(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_1/FileWriter.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_1; 2 | 3 | import java.io.FileOutputStream; 4 | import java.io.IOException; 5 | 6 | /** 7 | * @project: design-patterns 8 | * @description: 文件保存类, 充当子类系统类 9 | * @author: 黄宇辉 10 | * @date: 9/12/2019-9:56 PM 11 | * @version: 1.0 12 | * @website: https://yubuntu0109.github.io/ 13 | */ 14 | public class FileWriter { 15 | 16 | public void write(String encryptStr, String path) { 17 | try (var fileOutputStream = new FileOutputStream(path)) { 18 | fileOutputStream.write(encryptStr.getBytes()); 19 | } catch (IOException e) { 20 | e.printStackTrace(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_1/from.txt: -------------------------------------------------------------------------------- 1 | YUbuntu0109 -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_1/to.txt: -------------------------------------------------------------------------------- 1 | 51055456061 -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_2/AbstractEncryptFacade.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 明文加密抽象类, 充当抽象外观类 6 | * @author: 黄宇辉 7 | * @date: 9/14/2019-6:54 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class AbstractEncryptFacade { 12 | public abstract void fileEncrypt(String fromPath, String toPath); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_2/CipherMachine.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 数据加密类(求模运算), 充当子系统类 6 | * @author: 黄宇辉 7 | * @date: 9/12/2019-9:42 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class CipherMachine { 12 | 13 | public String encrypt(String text) { 14 | var result = new StringBuilder(); 15 | for (int i = 0; i < text.length(); i++) { 16 | var s = String.valueOf(text.charAt(i) % 7); 17 | result.append(s); 18 | } 19 | return result.toString(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_2/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/14/2019-6:05 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | private static final String FROM_PATH = "src\\main\\java\\pers\\huangyuhui\\facade_pattern\\facade_pattern_2\\from.txt"; 14 | private static final String TO_PATH = "src\\main\\java\\pers\\huangyuhui\\facade_pattern\\facade_pattern_2\\to.txt"; 15 | 16 | public static void main(String[] args) { 17 | //取模运算加密 18 | AbstractEncryptFacade encryptFacade = new EncryptFacade(); 19 | encryptFacade.fileEncrypt(FROM_PATH, TO_PATH); 20 | //移位运算加密 21 | AbstractEncryptFacade newEncryptFacade = new NewEncryptFacade(); 22 | newEncryptFacade.fileEncrypt(FROM_PATH, TO_PATH); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_2/EncryptFacade.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 加密外观类, 充当外观类 6 | * @author: 黄宇辉 7 | * @date: 9/12/2019-9:59 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class EncryptFacade extends AbstractEncryptFacade { 12 | 13 | //维持对子系统对象的引用 14 | private FileReader fileReader; 15 | private CipherMachine cipherMachine; 16 | private FileWriter fileWriter; 17 | 18 | public EncryptFacade() { 19 | fileReader = new FileReader(); 20 | cipherMachine = new CipherMachine(); 21 | fileWriter = new FileWriter(); 22 | } 23 | 24 | //调用子系统对象的业务方法 25 | public void fileEncrypt(String fromPath, String toPath) { 26 | var text = fileReader.read(fromPath); 27 | System.out.println(">>>>>>>>>> : 读取文件[ " + fromPath + " ]中的明文数据 : " + text); 28 | var encryptStr = cipherMachine.encrypt(text); 29 | System.out.println(">>>>>>>>>> : 明文数据加密后的结果 : " + encryptStr); 30 | fileWriter.write(encryptStr, toPath); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_2/FileReader.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_2; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | 6 | /** 7 | * @project: design-patterns 8 | * @description: 文件读取类, 充当子系统类 9 | * @author: 黄宇辉 10 | * @date: 9/12/2019-9:36 PM 11 | * @version: 1.0 12 | * @website: https://yubuntu0109.github.io/ 13 | */ 14 | public class FileReader { 15 | 16 | public String read(String path) { 17 | var stringBuffer = new StringBuilder(); 18 | try (var fileInputStream = new FileInputStream(path)) { 19 | var data = 0; 20 | while ((data = fileInputStream.read()) != -1) { 21 | stringBuffer.append((char) data); //char 22 | } 23 | } catch (IOException e) { 24 | e.printStackTrace(); 25 | } 26 | return stringBuffer.toString(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_2/FileWriter.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_2; 2 | 3 | import java.io.FileOutputStream; 4 | import java.io.IOException; 5 | 6 | /** 7 | * @project: design-patterns 8 | * @description: 文件保存类, 充当子类系统类 9 | * @author: 黄宇辉 10 | * @date: 9/12/2019-9:56 PM 11 | * @version: 1.0 12 | * @website: https://yubuntu0109.github.io/ 13 | */ 14 | public class FileWriter { 15 | 16 | public void write(String encryptStr, String path) { 17 | try (var fileOutputStream = new FileOutputStream(path)) { 18 | fileOutputStream.write(encryptStr.getBytes()); 19 | } catch (IOException e) { 20 | e.printStackTrace(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_2/NewCipherMachine.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 数据加密类(移位运算), 充当子系统类 6 | * @author: 黄宇辉 7 | * @date: 9/14/2019-6:59 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class NewCipherMachine { 12 | 13 | public String encrypt(String text) { 14 | var result = ""; 15 | var key = 10; //设置密钥,移位数为10 16 | for (int i = 0; i < text.length(); i++) { 17 | var c = text.charAt(i); 18 | //小写字母移位 19 | if (c >= 'a' && c <= 'z') { 20 | c += key % 26; 21 | if (c > 'z') { 22 | c -= 26; 23 | } 24 | if (c < 'a') { 25 | c += 26; 26 | } 27 | } 28 | //大写字母移位 29 | if (c >= 'A' && c <= 'Z') { 30 | c += key % 26; 31 | if (c > 'Z') { 32 | c -= 26; 33 | } 34 | if (c < 'A') { 35 | c += 26; 36 | } 37 | result += c; 38 | } 39 | } 40 | return result; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_2/NewEncryptFacade.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.facade_pattern.facade_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 加密外观类, 充当外观类 6 | * @author: 黄宇辉 7 | * @date: 9/14/2019-6:57 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class NewEncryptFacade extends AbstractEncryptFacade { 12 | 13 | private FileReader reader; 14 | private NewCipherMachine newCipherMachine; 15 | private FileWriter writer; 16 | 17 | public NewEncryptFacade() { 18 | reader = new FileReader(); 19 | newCipherMachine = new NewCipherMachine(); 20 | writer = new FileWriter(); 21 | } 22 | 23 | //调用子系统对象的业务方法 24 | @Override 25 | public void fileEncrypt(String fromPath, String toPath) { 26 | String text = reader.read(fromPath); 27 | System.out.println(">>>>>>>>>> : 读取文件[ " + fromPath + " ]中的明文数据 : " + text); 28 | String encryptStr = newCipherMachine.encrypt(text); 29 | System.out.println(">>>>>>>>>> : 明文数据加密后的结果 : " + encryptStr); 30 | writer.write(encryptStr, toPath); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_2/from.txt: -------------------------------------------------------------------------------- 1 | YUbuntu0109 -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/facade_pattern/facade_pattern_2/to.txt: -------------------------------------------------------------------------------- 1 | IE -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Java设计模式之Factory Method模式 3 | date: 2019-09-05 09:23:20 4 | tags: [Java,design and pattern] 5 | --- 6 | 7 | ## 学习笔记 : Java设计模式之Factory Method模式 8 | 9 | ### 概述 10 | *工厂方法模式 : 定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化. 工厂方法模式让一个类的实例化延迟到其子类. ( Factory Method Pattern : Definde an interface for creating an object,but let subclasses decides which class to instantiate. Factory Method lets a class defer instantiation to sublclasses )* 11 | 12 | * 工厂方法模式是简单工厂模式的延伸,它继承了简单工厂模式的优点,同时还弥补了简单工厂模式的缺陷,使其更好地符合开闭原则的要求. 工厂方法模式简称为工厂模式( Factory Pattern ),又可称为虚拟构造器模式( Virtual Constructor Pattern )或多态工厂模式( Polymorphic Factory Pattern ). 其为一种类创建型模式哟 ~ 13 | 14 | ### Factory Method模式中的角色 15 | 1. *`Product (抽象产品)` : 它是定义产品的接口,是工厂方法模式所创建对象的超类型,也是产品对象的公共父类.* 16 | 2. *`ConcreteProduct (具体产品)` : 它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品间一一对象.* 17 | 3. *`Factory (抽象工厂)` : 在抽象工厂类中声明了工厂方法( Factory Method ),用于返回一个产品. 抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口.* 18 | 4. *`ConcreteFactory (具体工厂)` : 它是抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法,并由客户端调用,返回一个具体产品类的实例.* 19 | 20 | 21 | ### 程序示例-简洁版 22 | *下面是一个实现了Factory Method模式的简单示例程序,该示例程序的功能( 模拟 )是为了提高多种日志记录器之间切换的灵活性.* 23 | 24 | 1. *Logger接口 : 日志记录器接口, 充当抽象产品角色* 25 | ```java 26 | package pers.huangyuhui.factory_method.factory_method1; 27 | 28 | /** 29 | * @project: design-patterns 30 | * @description: 日志记录器接口, 充当抽象产品角色 31 | * @author: 黄宇辉 32 | * @date: 9/5/2019-9:26 AM 33 | * @version: 1.0 34 | * @website: https://yubuntu0109.github.io/ 35 | */ 36 | public interface Logger { 37 | void writeLog(); 38 | } 39 | ``` 40 | 41 | 2. *DatabaseLogger类 : 数据库日志记录器, 充当具体产品角色* 42 | ```java 43 | package pers.huangyuhui.factory_method.factory_method1; 44 | 45 | /** 46 | * @project: design-pattern 47 | * @description: 数据库日志记录器, 充当具体产品角色 48 | * @author: 黄宇辉 49 | * @date: 9/5/2019-9:27 AM 50 | * @version: 1.0 51 | * @website: https://yubuntu0109.github.io/ 52 | */ 53 | public class DatabaseLogger implements Logger { 54 | 55 | @Override 56 | public void writeLog() { 57 | System.out.println("this is some logs about database"); 58 | } 59 | } 60 | ``` 61 | 62 | 3. *FileLogger类 : 文件日志记录器, 充当具体产品角色* 63 | ```java 64 | package pers.huangyuhui.factory_method.factory_method1; 65 | 66 | /** 67 | * @project: design-patterns 68 | * @description: 文件日志记录器, 充当具体产品角色 69 | * @author: 黄宇辉 70 | * @date: 9/5/2019-9:30 AM 71 | * @version: 1.0 72 | * @website: https://yubuntu0109.github.io/ 73 | */ 74 | public class FileLogger implements Logger { 75 | 76 | @Override 77 | public void writeLog() { 78 | System.out.println("this is some logs about file"); 79 | } 80 | } 81 | ``` 82 | 83 | 4. *LoggerFactory类 : 日志记录器工厂接口, 充当抽象工厂角色* 84 | ```java 85 | package pers.huangyuhui.factory_method.factory_method1; 86 | 87 | /** 88 | * @project: design-patterns 89 | * @description: 日志记录器工厂接口, 充当抽象工厂角色 90 | * @author: 黄宇辉 91 | * @date: 9/5/2019-9:33 AM 92 | * @version: 1.0 93 | * @website: https://yubuntu0109.github.io/ 94 | */ 95 | public interface LoggerFactory { 96 | Logger createLogger(); 97 | } 98 | ``` 99 | 100 | 5. *DatabaseLoggerFactory类 : 数据库日志记录器工厂类, 充当具体工厂角色* 101 | ```java 102 | package pers.huangyuhui.factory_method.factory_method1; 103 | 104 | 105 | /** 106 | * @project: design-patterns 107 | * @description: 数据库日志记录器工厂类, 充当具体工厂角色 108 | * @author: 黄宇辉 109 | * @date: 9/5/2019-9:36 AM 110 | * @version: 1.0 111 | * @website: https://yubuntu0109.github.io/ 112 | */ 113 | public class DatabaseLoggerFactory implements LoggerFactory { 114 | 115 | @Override 116 | public Logger createLogger() { 117 | return new DatabaseLogger(); 118 | } 119 | } 120 | ``` 121 | 122 | 6. *FileLoggerFactory类 : 文件日志记录器工厂类, 充当具体工厂角色* 123 | ```java 124 | package pers.huangyuhui.factory_method.factory_method1; 125 | 126 | /** 127 | * @project: design-patterns 128 | * @description: 文件日志记录器工厂类, 充当具体工厂角色 129 | * @author: 黄宇辉 130 | * @date: 9/5/2019-9:38 AM 131 | * @version: 1.0 132 | * @website: https://yubuntu0109.github.io/ 133 | */ 134 | public class FileLoggerFactory implements LoggerFactory { 135 | 136 | @Override 137 | public Logger createLogger() { 138 | return new FileLogger(); 139 | } 140 | } 141 | ``` 142 | 143 | 7. *Client类 : 客户端测试类* 144 | ```java 145 | package pers.huangyuhui.factory_method.factory_method1; 146 | 147 | /** 148 | * @project: design-patterns 149 | * @description: 客户端测试类 150 | * @author: 黄宇辉 151 | * @date: 9/5/2019-9:39 AM 152 | * @version: 1.0 153 | * @website: https://yubuntu0109.github.io/ 154 | */ 155 | public class Client { 156 | 157 | public static void main(String[] args) { 158 | LoggerFactory databaseLoggerFactory = new DatabaseLoggerFactory(); 159 | Logger databaseLogger = databaseLoggerFactory.createLogger(); 160 | databaseLogger.writeLog(); 161 | 162 | LoggerFactory fileLoggerFactory = new FileLoggerFactory(); 163 | Logger fileLogger = fileLoggerFactory.createLogger(); 164 | fileLogger.writeLog(); 165 | } 166 | } 167 | ``` 168 | 169 | 8. *程序运行结果如下所示 :* 170 | ``` 171 | this is some logs about database 172 | this is some logs about file 173 | ``` 174 | 175 | #### 示例程序的类图 176 | ![ ](https://raw.githubusercontent.com/YUbuntu0109/YUbuntu0109.github.io/HexoBackup/source/_posts/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BFactory-Method-Pattern/Factory-Method-Pattern-ClassDiagram1.png) 177 | 178 | 179 | 180 | ### 示例程序-工厂方法的重载 181 | *下述示例代码文件同上述`示例程序-简洁版`,既只需修改部分代码即可哟~* 182 | 183 | 1. *LoggerFactory接口 : 日志记录器工厂接口, 充当抽象工厂角色(工厂方法的重载)* 184 | ```java 185 | package pers.huangyuhui.factory_method.factory_method2; 186 | 187 | /** 188 | * @project: design-patterns 189 | * @description: 日志记录器工厂接口, 充当抽象工厂角色(工厂方法的重载) 190 | * @author: 黄宇辉 191 | * @date: 9/5/2019-9:33 AM 192 | * @version: 1.0 193 | * @website: https://yubuntu0109.github.io/ 194 | */ 195 | public interface LoggerFactory { 196 | Logger createLogger(); 197 | 198 | Logger createLogger(String args); 199 | 200 | Logger createLogger(Object obj); 201 | } 202 | ``` 203 | 204 | 2. *DatabaseLoggerFactory类 : 数据库日志记录器工厂类, 充当具体工厂角色(工厂方法的重载)* 205 | ```java 206 | package pers.huangyuhui.factory_method.factory_method2; 207 | 208 | /** 209 | * @project: design-patterns 210 | * @description: 数据库日志记录器工厂类, 充当具体工厂角色(工厂方法的重载) 211 | * @author: 黄宇辉 212 | * @date: 9/5/2019-9:36 AM 213 | * @version: 1.0 214 | * @website: https://yubuntu0109.github.io/ 215 | */ 216 | public class DatabaseLoggerFactory implements LoggerFactory { 217 | 218 | @Override 219 | public Logger createLogger() { 220 | return new DatabaseLogger(); 221 | } 222 | 223 | @Override 224 | public pers.huangyuhui.factory_method.factory_method2.Logger createLogger(String args) { 225 | System.out.println("使用参数" + args + "作为连接字符串来连接数据库,代码省略 ···"); 226 | Logger logger = new DatabaseLogger(); 227 | //初始化数据库日志记录器,代码省略 ··· 228 | return new DatabaseLogger(); 229 | } 230 | 231 | @Override 232 | public pers.huangyuhui.factory_method.factory_method2.Logger createLogger(Object obj) { 233 | System.out.println("使用封装在" + obj.toString() + "中的连接字符串来连接数据库,代码省略 ···"); 234 | Logger logger = new DatabaseLogger(); 235 | //使用封装在参数obj中的数据来初始化数据库日志记录器,代码省略 ··· 236 | return logger; 237 | } 238 | } 239 | ``` 240 | 241 | 3. *Client类 : 客户端测试类-(工厂方法的重载)* 242 | ```java 243 | package pers.huangyuhui.factory_method.factory_method2; 244 | 245 | /** 246 | * @project: design-patterns 247 | * @description: 客户端测试类-(工厂方法的重载) 248 | * @author: 黄宇辉 249 | * @date: 9/5/2019-9:39 AM 250 | * @version: 1.0 251 | * @website: https://yubuntu0109.github.io/ 252 | */ 253 | public class Client { 254 | 255 | public static void main(String[] args) { 256 | LoggerFactory databaseLoggerFactory = new DatabaseLoggerFactory(); 257 | Logger databaseLogger = databaseLoggerFactory.createLogger("database-connection-info"); 258 | databaseLogger.writeLog(); 259 | 260 | LoggerFactory fileLoggerFactory = new FileLoggerFactory(); 261 | Logger fileLogger = fileLoggerFactory.createLogger(); 262 | fileLogger.writeLog(); 263 | } 264 | } 265 | ``` 266 | 267 | 4. *程序运行结果如下所示 :* 268 | ``` 269 | 使用参数database-connection-info作为连接字符串来连接数据库,代码省略 ··· 270 | this is some logs about database 271 | this is some logs about file 272 | ``` 273 | 274 | #### 示例程序的类图 275 | ![ ](https://raw.githubusercontent.com/YUbuntu0109/YUbuntu0109.github.io/HexoBackup/source/_posts/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BFactory-Method-Pattern/Factory-Method-Pattern-ClassDiagram2.png) 276 | 277 | 278 | 279 | ### 示例程序-工厂方法的隐藏 280 | *下述示例代码文件同上述`示例程序-简洁版`,既只需修改部分代码即可哟~* 281 | 282 | 1. *LoggerFactory类 : 日志记录器工厂接口, 充当抽象工厂角色(工厂方法的隐藏)* 283 | ```java 284 | package pers.huangyuhui.factory_method.factory_method3; 285 | 286 | /** 287 | * @project: design-patterns 288 | * @description: 日志记录器工厂接口, 充当抽象工厂角色(工厂方法的隐藏) 289 | * @author: 黄宇辉 290 | * @date: 9/5/2019-9:33 AM 291 | * @version: 1.0 292 | * @website: https://yubuntu0109.github.io/ 293 | */ 294 | public abstract class LoggerFactory { 295 | 296 | //工厂方法的隐藏 297 | public void writeLog() { 298 | Logger logger = this.createLogger(); 299 | logger.writeLog(); 300 | } 301 | 302 | public abstract Logger createLogger(); 303 | } 304 | ``` 305 | 306 | 2. *DatabaseLoggerFactory类 : 数据库日志记录器工厂类, 充当具体工厂角色* 307 | ```java 308 | public class DatabaseLoggerFactory extends LoggerFactory { · · · · · · 309 | ``` 310 | 311 | 3. *FileLoggerFactory类 : 文件日志记录器工厂类, 充当具体工厂角色* 312 | ```java 313 | public class FileLoggerFactory extends LoggerFactory { · · · · · · 314 | ``` 315 | 316 | 4. *Client类 : 客户端测试类(工厂方法的隐藏)* 317 | ```java 318 | package pers.huangyuhui.factory_method.factory_method3; 319 | 320 | /** 321 | * @project: design-patterns 322 | * @description: 客户端测试类(工厂方法的隐藏) 323 | * @author: 黄宇辉 324 | * @date: 9/5/2019-9:39 AM 325 | * @version: 1.0 326 | * @website: https://yubuntu0109.github.io/ 327 | */ 328 | public class Client { 329 | 330 | public static void main(String[] args) { 331 | new DatabaseLoggerFactory().writeLog(); 332 | //LoggerFactory databaseLoggerFactory = new DatabaseLoggerFactory(); 333 | //Logger databaseLogger = databaseLoggerFactory.createLogger(); 334 | //databaseLogger.writeLog(); 335 | 336 | new FileLoggerFactory().writeLog(); 337 | //LoggerFactory fileLoggerFactory = new FileLoggerFactory(); 338 | //Logger fileLogger = fileLoggerFactory.createLogger(); 339 | //fileLogger.writeLog(); 340 | } 341 | } 342 | ``` 343 | 344 | 5. *程序运行结果如下所示 :* 345 | ``` 346 | this is some logs about database 347 | this is some logs about file 348 | ``` 349 | 350 | #### 示例程序的类图 351 | ![ ](https://raw.githubusercontent.com/YUbuntu0109/YUbuntu0109.github.io/HexoBackup/source/_posts/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BFactory-Method-Pattern/Factory-Method-Pattern-ClassDiagram3.png) 352 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method1/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:39 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | LoggerFactory databaseLoggerFactory = new DatabaseLoggerFactory(); 15 | Logger databaseLogger = databaseLoggerFactory.createLogger(); 16 | databaseLogger.writeLog(); 17 | 18 | LoggerFactory fileLoggerFactory = new FileLoggerFactory(); 19 | Logger fileLogger = fileLoggerFactory.createLogger(); 20 | fileLogger.writeLog(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method1/DatabaseLogger.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method1; 2 | 3 | /** 4 | * @project: design-pattern 5 | * @description: 数据库日志记录器, 充当具体产品角色 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:27 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class DatabaseLogger implements Logger { 12 | 13 | @Override 14 | public void writeLog() { 15 | System.out.println("this is some logs about database"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method1/DatabaseLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method1; 2 | 3 | 4 | /** 5 | * @project: design-patterns 6 | * @description: 数据库日志记录器工厂类, 充当具体工厂角色 7 | * @author: 黄宇辉 8 | * @date: 9/5/2019-9:36 AM 9 | * @version: 1.0 10 | * @website: https://yubuntu0109.github.io/ 11 | */ 12 | public class DatabaseLoggerFactory implements LoggerFactory { 13 | 14 | @Override 15 | public Logger createLogger() { 16 | return new DatabaseLogger(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method1/FileLogger.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文件日志记录器, 充当具体产品角色 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:30 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class FileLogger implements Logger { 12 | 13 | @Override 14 | public void writeLog() { 15 | System.out.println("this is some logs about file"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method1/FileLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文件日志记录器工厂类, 充当具体工厂角色 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:38 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class FileLoggerFactory implements LoggerFactory { 12 | 13 | @Override 14 | public Logger createLogger() { 15 | return new FileLogger(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method1/Logger.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 日志记录器接口, 充当抽象产品角色 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:26 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface Logger { 12 | void writeLog(); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method1/LoggerFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 日志记录器工厂接口, 充当抽象工厂角色 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:33 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface LoggerFactory { 12 | Logger createLogger(); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method2/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类-(工厂方法的重载) 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:39 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | LoggerFactory databaseLoggerFactory = new DatabaseLoggerFactory(); 15 | Logger databaseLogger = databaseLoggerFactory.createLogger("database-connection-info"); 16 | databaseLogger.writeLog(); 17 | 18 | LoggerFactory fileLoggerFactory = new FileLoggerFactory(); 19 | Logger fileLogger = fileLoggerFactory.createLogger(); 20 | fileLogger.writeLog(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method2/DatabaseLogger.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method2; 2 | 3 | /** 4 | * @project: design-pattern 5 | * @description: 数据库日志记录器, 充当具体产品角色 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:27 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class DatabaseLogger implements Logger { 12 | 13 | @Override 14 | public void writeLog() { 15 | System.out.println("this is some logs about database"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method2/DatabaseLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 数据库日志记录器工厂类, 充当具体工厂角色(工厂方法的重载) 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:36 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class DatabaseLoggerFactory implements LoggerFactory { 12 | 13 | @Override 14 | public Logger createLogger() { 15 | return new DatabaseLogger(); 16 | } 17 | 18 | @Override 19 | public pers.huangyuhui.factory_method_pattern.factory_method2.Logger createLogger(String args) { 20 | System.out.println("使用参数" + args + "作为连接字符串来连接数据库,代码省略 ···"); 21 | Logger logger = new DatabaseLogger(); 22 | //初始化数据库日志记录器,代码省略 ··· 23 | return new DatabaseLogger(); 24 | } 25 | 26 | @Override 27 | public pers.huangyuhui.factory_method_pattern.factory_method2.Logger createLogger(Object obj) { 28 | System.out.println("使用封装在" + obj.toString() + "中的连接字符串来连接数据库,代码省略 ···"); 29 | Logger logger = new DatabaseLogger(); 30 | //使用封装在参数obj中的数据来初始化数据库日志记录器,代码省略 ··· 31 | return logger; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method2/FileLogger.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文件日志记录器,充当具体产品角色 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:30 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class FileLogger implements Logger { 12 | 13 | @Override 14 | public void writeLog() { 15 | System.out.println("this is some logs about file"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method2/FileLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文件日志记录器工厂类, 充当具体工厂角色-工厂方法模式之工厂方法的重载 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:38 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class FileLoggerFactory implements LoggerFactory { 12 | 13 | @Override 14 | public Logger createLogger() { 15 | return new FileLogger(); 16 | } 17 | 18 | @Override 19 | public Logger createLogger(String args) { 20 | return null; 21 | } 22 | 23 | @Override 24 | public Logger createLogger(Object obj) { 25 | return null; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method2/Logger.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当产品角色 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:26 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface Logger { 12 | void writeLog(); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method2/LoggerFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 日志记录器工厂接口, 充当抽象工厂角色(工厂方法的重载) 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:33 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface LoggerFactory { 12 | Logger createLogger(); 13 | 14 | Logger createLogger(String args); 15 | 16 | Logger createLogger(Object obj); 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method3/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method3; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类(工厂方法的隐藏) 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:39 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | new DatabaseLoggerFactory().writeLog(); 15 | //LoggerFactory databaseLoggerFactory = new DatabaseLoggerFactory(); 16 | //Logger databaseLogger = databaseLoggerFactory.createLogger(); 17 | //databaseLogger.writeLog(); 18 | 19 | new FileLoggerFactory().writeLog(); 20 | //LoggerFactory fileLoggerFactory = new FileLoggerFactory(); 21 | //Logger fileLogger = fileLoggerFactory.createLogger(); 22 | //fileLogger.writeLog(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method3/DatabaseLogger.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method3; 2 | 3 | /** 4 | * @project: design-pattern 5 | * @description: 数据库日志记录器, 充当具体产品角色 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:27 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class DatabaseLogger implements Logger { 12 | 13 | @Override 14 | public void writeLog() { 15 | System.out.println("this is some logs about database"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method3/DatabaseLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method3; 2 | 3 | 4 | /** 5 | * @project: design-patterns 6 | * @description: 数据库日志记录器工厂类, 充当具体工厂角色 7 | * @author: 黄宇辉 8 | * @date: 9/5/2019-9:36 AM 9 | * @version: 1.0 10 | * @website: https://yubuntu0109.github.io/ 11 | */ 12 | public class DatabaseLoggerFactory extends LoggerFactory { 13 | 14 | @Override 15 | public Logger createLogger() { 16 | return new DatabaseLogger(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method3/FileLogger.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method3; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文件日志记录器, 充当具体产品角色- 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:30 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class FileLogger implements Logger { 12 | 13 | @Override 14 | public void writeLog() { 15 | System.out.println("this is some logs about file"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method3/FileLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method3; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文件日志记录器工厂类, 充当具体工厂角色 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:38 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class FileLoggerFactory extends LoggerFactory { 12 | 13 | @Override 14 | public Logger createLogger() { 15 | return new FileLogger(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method3/Logger.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method3; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当产品角色 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:26 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface Logger { 12 | void writeLog(); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/factory_method_pattern/factory_method3/LoggerFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.factory_method_pattern.factory_method3; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 日志记录器工厂接口, 充当抽象工厂角色(工厂方法的隐藏) 6 | * @author: 黄宇辉 7 | * @date: 9/5/2019-9:33 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class LoggerFactory { 12 | 13 | //工厂方法的隐藏 14 | public void writeLog() { 15 | Logger logger = this.createLogger(); 16 | logger.writeLog(); 17 | } 18 | 19 | public abstract Logger createLogger(); 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/froxy_pattern/froxy_pattern_1/AccessValidator.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.froxy_pattern.froxy_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 身份验证类(业务类), 它提供validate()方法来实现用户身份的验证 6 | * @author: 黄宇辉 7 | * @date: 9/25/2019-12:53 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class AccessValidator { 12 | 13 | //模拟实现登录验证 14 | public boolean validate(String userId) { 15 | if (userId.equalsIgnoreCase("yubuntu0109")) { 16 | System.out.println("ID为:[ " + userId + " ]的用户登录成功"); 17 | return true; 18 | } else { 19 | System.out.println("ID为:[ " + userId + " ]的用户登录失败"); 20 | return false; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/froxy_pattern/froxy_pattern_1/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.froxy_pattern.froxy_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/25/2019-1:13 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | Searcher searcher = new ProxySearcher(); 15 | System.out.println(searcher.doSearch("yubuntu0109", "design-patterns-in-java")); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/froxy_pattern/froxy_pattern_1/Logger.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.froxy_pattern.froxy_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 日志记录类(业务类), 提供一个log()方法来保存日志信息 6 | * @author: 黄宇辉 7 | * @date: 9/25/2019-12:57 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Logger { 12 | 13 | //模拟实现日志记录 14 | public void log(String userId) { 15 | System.out.println("成功更新数据库信息,ID为:[ " + userId + "+ ]的用户查询次数+1"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/froxy_pattern/froxy_pattern_1/ProxySearcher.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.froxy_pattern.froxy_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 代理查询类, 充当代码主题角色, 它是查询代理, 维持了对RealSearcher, AccessValidator, 及Logger对象的引用 6 | * @author: 黄宇辉 7 | * @date: 9/25/2019-1:05 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class ProxySearcher implements Searcher { 12 | 13 | private RealSearcher realSearcher = new RealSearcher(); //维持一个对真实主题的引用 14 | private AccessValidator accessValidator; 15 | private Logger logger; 16 | 17 | @Override 18 | public String doSearch(String userId, String keyWord) { 19 | //如果身份验证成功,则执行查询操作 20 | if (this.validate(userId)) { 21 | String result = realSearcher.doSearch(userId, keyWord); //调用真实主题的查询方法 22 | this.log(userId); //记录查询日志 23 | return result; 24 | } else { 25 | return null; 26 | } 27 | } 28 | 29 | //创建访问验证对象并调用其validate()方法来实现身份验证 30 | public boolean validate(String userId) { 31 | accessValidator = new AccessValidator(); 32 | return accessValidator.validate(userId); 33 | } 34 | 35 | //创建日志记录对象并调用其log()方法来实现日志记录 36 | public void log(String userId) { 37 | logger = new Logger(); 38 | logger.log(userId); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/froxy_pattern/froxy_pattern_1/RealSearcher.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.froxy_pattern.froxy_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 具体查询类, 充当真实主题角色, 它实现了查询功能 6 | * @author: 黄宇辉 7 | * @date: 9/25/2019-1:01 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class RealSearcher implements Searcher { 12 | 13 | //模拟查询商务信息 14 | @Override 15 | public String doSearch(String userId, String keyWord) { 16 | System.out.println("ID为:[ " + userId + " ]的用户使用关键字:[ " + keyWord + " ]查询了商务信息"); 17 | return "[ 这是用户所查询的商务信息结果 ]"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/froxy_pattern/froxy_pattern_1/Searcher.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.froxy_pattern.froxy_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象查询类, 充当抽象主题角色 6 | * @author: 黄宇辉 7 | * @date: 9/25/2019-1:00 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface Searcher { 12 | String doSearch(String userId, String keyWord); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/froxy_pattern/froxy_pattern_2/AbstractDocumentDao.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.froxy_pattern.froxy_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象文档DAO类, 充当抽象主题角色 6 | * @author: 黄宇辉 7 | * @date: 9/25/2019-1:17 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface AbstractDocumentDao { 12 | boolean deleteDocumentById(String documentId); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/froxy_pattern/froxy_pattern_2/AbstractUserDao.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.froxy_pattern.froxy_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象用户DAO类, 充当抽象主题角色 6 | * @author: 黄宇辉 7 | * @date: 9/25/2019-1:16 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface AbstractUserDao { 12 | boolean findUserById(String userId); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/froxy_pattern/froxy_pattern_2/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.froxy_pattern.froxy_pattern_2; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Proxy; 5 | 6 | /** 7 | * @project: design-patterns 8 | * @description: 客户端测试类 9 | * @author: 黄宇辉 10 | * @date: 9/25/2019-1:29 PM 11 | * @version: 1.0 12 | * @website: https://yubuntu0109.github.io/ 13 | */ 14 | public class Client { 15 | 16 | public static void main(String[] args) { 17 | InvocationHandler handler = new DAOLogHandler(new UserDao()); 18 | AbstractUserDao proxy = (AbstractUserDao) Proxy.newProxyInstance(AbstractUserDao.class.getClassLoader(), new Class[]{AbstractUserDao.class}, handler); 19 | proxy.findUserById("yubuntu0109"); 20 | 21 | System.out.println("------------------------------"); 22 | 23 | InvocationHandler handler2 = new DAOLogHandler(new DocumentDao()); 24 | AbstractDocumentDao proxy2 = (AbstractDocumentDao) Proxy.newProxyInstance(AbstractDocumentDao.class.getClassLoader(), new Class[]{AbstractDocumentDao.class}, handler2); 25 | proxy2.deleteDocumentById("Y001"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/froxy_pattern/froxy_pattern_2/DAOLogHandler.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.froxy_pattern.froxy_pattern_2; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | import java.util.Date; 6 | import java.util.Timer; 7 | 8 | /** 9 | * @project: design-patterns 10 | * @description: 自定义请求处理程序类 11 | * @author: 黄宇辉 12 | * @date: 9/25/2019-1:24 PM 13 | * @version: 1.0 14 | * @website: https://yubuntu0109.github.io/ 15 | */ 16 | public class DAOLogHandler implements InvocationHandler { 17 | 18 | private Object object; 19 | 20 | public DAOLogHandler() { 21 | } 22 | 23 | //注入一个需要提供代理的真实主题对象 24 | public DAOLogHandler(Object object) { 25 | this.object = object; 26 | } 27 | 28 | public void beforeInvoke() { 29 | System.out.println("------> invoke before: " + new Date().toString()); 30 | } 31 | 32 | public void afterInvoke() { 33 | System.out.println("------> invoke after: " + new Date().toString()); 34 | } 35 | 36 | //实现invoke()方法,调用在真实主题类中定义的方法 37 | @Override 38 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 39 | beforeInvoke(); 40 | Object result = method.invoke(object, args); //转发调用 41 | afterInvoke(); 42 | return result; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/froxy_pattern/froxy_pattern_2/DocumentDao.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.froxy_pattern.froxy_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文档DAO类, 充当具体主题角色 6 | * @author: 黄宇辉 7 | * @date: 9/25/2019-1:21 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class DocumentDao implements AbstractDocumentDao { 12 | 13 | @Override 14 | public boolean deleteDocumentById(String documentId) { 15 | if (documentId.equalsIgnoreCase("Y001")) { 16 | System.out.println("成功删除ID为:[ " + documentId + " ]的文档信息"); 17 | return true; 18 | } else { 19 | System.out.println("并未找到ID为:[ " + documentId + " ]的文档信息"); 20 | return false; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/froxy_pattern/froxy_pattern_2/UserDao.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.froxy_pattern.froxy_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 用户DAO类, 充当具体主题角色 6 | * @author: 黄宇辉 7 | * @date: 9/25/2019-1:18 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class UserDao implements AbstractUserDao { 12 | 13 | @Override 14 | public boolean findUserById(String userId) { 15 | if (userId.equalsIgnoreCase("yubuntu0109")) { 16 | System.out.println("成功查询ID为:[ " + userId + " ]的用户信息"); 17 | return true; 18 | } else { 19 | System.out.println("并未查询ID为:[" + userId + " ]的用户信息"); 20 | return false; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/iterator_pattern/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Java设计模式之Iterator模式 3 | date: 2019-09-02 21:50:06 4 | tags: [Java,design and pattern] 5 | --- 6 | 7 | ## 学习笔记 : Java设计模式之Iterator模式 8 | 9 | ### 概述 10 | *迭代器模式 : 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示. 迭代器模式又称( Cursor )模式,它是一种对象行为型模式( Iterator Pattern : Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation )* 11 | 12 | ### 示例程序-详细版 13 | *下面是一个实现了`Iterator模式`的示例程序,其作用是将书籍信息( Book )放到存储书籍信息的书架( BookSelf )上,并将书的名字按顺序显示出来* 14 | 15 | 1. *Book : 图书信息类* 16 | ```java 17 | package pers.huangyuhui.iterator; 18 | 19 | /** 20 | * @project: design-patterns 21 | * @description: Book信息 22 | * @author: 黄宇辉 23 | * @date: 9/2/2019-4:59 PM 24 | * @version: 1.0 25 | * @website: https://yubuntu0109.github.io/ 26 | */ 27 | public class Book { 28 | 29 | private String name; 30 | 31 | public Book(String name) { 32 | this.name = name; 33 | } 34 | 35 | public String getName() { 36 | return name; 37 | } 38 | 39 | } 40 | ``` 41 | 42 | 2. *Aggregate接口 : 充当集合角色* 43 | ```java 44 | package pers.huangyuhui.iterator; 45 | 46 | 47 | /** 48 | * @project: design-patterns 49 | * @description: 集合 50 | * @author: 黄宇辉 51 | * @date: 9/2/2019-5:00 PM 52 | * @version: 1.0 53 | * @website: https://yubuntu0109.github.io/ 54 | */ 55 | public interface Aggregate { 56 | 57 | Iterator iterator(); 58 | } 59 | ``` 60 | 61 | 3. *BookSelf类 : 充当具体的集合角色* 62 | ```java 63 | package pers.huangyuhui.iterator; 64 | 65 | /** 66 | * @project: design-patterns 67 | * @description: 具体的集合 68 | * @author: 黄宇辉 69 | * @date: 9/2/2019-5:03 PM 70 | * @version: 1.0 71 | * @website: https://yubuntu0109.github.io/ 72 | */ 73 | public class BookSelf implements Aggregate { 74 | private Book[] books; 75 | private int last = 0; 76 | 77 | public BookSelf(int maxsize) { 78 | this.books = new Book[maxsize]; 79 | } 80 | 81 | public Book getBookByIndex(int index) { 82 | return books[index]; 83 | } 84 | 85 | public void appendBook(Book book) { 86 | this.books[last++] = book; 87 | } 88 | 89 | public int getLength() { 90 | return last; 91 | } 92 | 93 | @Override 94 | public Iterator iterator() { 95 | return new BookShelfIterator(this); 96 | } 97 | } 98 | ``` 99 | 100 | 4. *Iterator接口 : 充当迭代器角色* 101 | ```java 102 | package pers.huangyuhui.iterator; 103 | 104 | /** 105 | * @project: design-patterns 106 | * @description: 迭代器 107 | * @author: 黄宇辉 108 | * @date: 9/2/2019-5:01 PM 109 | * @version: 1.0 110 | * @website: https://yubuntu0109.github.io/ 111 | */ 112 | public interface Iterator { 113 | boolean hasNext(); 114 | 115 | Object next(); 116 | } 117 | ``` 118 | 119 | 5. *BookShelfIterator类 : 充当具体的迭代器角色* 120 | ```java 121 | package pers.huangyuhui.iterator; 122 | 123 | /** 124 | * @project: design-patterns 125 | * @description: 集体的迭代器 126 | * @author: 黄宇辉 127 | * @date: 9/2/2019-5:07 PM 128 | * @version: 1.0 129 | * @website: https://yubuntu0109.github.io/ 130 | */ 131 | public class BookShelfIterator implements Iterator { 132 | 133 | private BookSelf bookSelf; 134 | private int index; 135 | 136 | public BookShelfIterator(BookSelf bookSelf) { 137 | this.bookSelf = bookSelf; 138 | this.index = 0; 139 | } 140 | 141 | @Override 142 | public boolean hasNext() { 143 | return index < bookSelf.getLength(); 144 | } 145 | 146 | @Override 147 | public Object next() { 148 | return bookSelf.getBookByIndex(index++); 149 | } 150 | } 151 | ``` 152 | 153 | 6. *Test测试类* 154 | ```java 155 | package pers.huangyuhui.iterator; 156 | 157 | /** 158 | * @project: design-patterns 159 | * @description: 测试类 160 | * @author: 黄宇辉 161 | * @date: 9/2/2019-5:09 PM 162 | * @version: 1.0 163 | * @website: https://yubuntu0109.github.io/ 164 | */ 165 | public class Test { 166 | 167 | //demo 168 | public static void main(String[] args) { 169 | BookSelf bookSelf = new BookSelf(5); 170 | bookSelf.appendBook(new Book("A-BOOK")); 171 | bookSelf.appendBook(new Book("B-BOOK")); 172 | bookSelf.appendBook(new Book("C-BOOK")); 173 | bookSelf.appendBook(new Book("D-BOOK")); 174 | bookSelf.appendBook(new Book("E-BOOK")); 175 | Iterator iterator = bookSelf.iterator(); 176 | while (iterator.hasNext()) { 177 | Book book = (Book) iterator.next(); 178 | System.out.println(book.getName()); 179 | } 180 | } 181 | } 182 | ``` 183 | 184 | 7. *程序运行结果如下所示 :* 185 | ``` 186 | A-BOOK 187 | B-BOOK 188 | C-BOOK 189 | D-BOOK 190 | E-BOOK 191 | ``` 192 | 193 | #### 示例程序的类图 194 | ![ ](https://raw.githubusercontent.com/YUbuntu0109/YUbuntu0109.github.io/HexoBackup/source/_posts/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BIterator-Pattern/Iterator1-ClassDiagram.png) 195 | 196 | #### Iterator模式中的角色分析 197 | * `Iterator( 迭代器 )` : 该角色负责定义按顺序逐个遍历元素的接口( API ),在上述程序中,由`Iterator接口`扮演此角色. 198 | * `ConcreteIterator( 具体的迭代器 )` : 该角色负责实现`Iterator角色`所定义的接口( API ). 在上述程序中,由`BookShelfIterator类`扮演此角色. 199 | * `Aggregate( 集合 / 抽象聚合类 )` : 该角色负责定义创建`Iterator角色`的接口( API ),在上述程序中,由`Aggregate接口`扮演此角色. 200 | * `ConcreteAggregate( 具体的集合 / 具体聚合类 )` : 该角色负责实现`Aggregate角色`所定义的接口( API ),它会创建出具体的`Iterator角色`. 在上述程序中,由`BookSelf类`扮演了此角色. 201 | 202 | 203 | 204 | ### 示例程序-简洁版 205 | *下面同样是一个实现了`Iterator模式`的示例程序( 同上 ),其作用是将商品数据存储到商品集合( ProductList )中,并将商品的名字按顺序显示出来* 206 | 207 | 1. *AbstractObjectList : 抽象聚合类* 208 | ```java 209 | package pers.huangyuhui.iterator2; 210 | 211 | import java.util.List; 212 | 213 | /** 214 | * @project: design-patterns 215 | * @description: 抽象聚合类 216 | * @author: 黄宇辉 217 | * @date: 9/2/2019-5:51 PM 218 | * @version: 1.0 219 | * @website: https://yubuntu0109.github.io/ 220 | */ 221 | public abstract class AbstractObjectList { 222 | 223 | protected List objects; 224 | 225 | public AbstractObjectList(List objects) { 226 | this.objects = objects; 227 | } 228 | 229 | public void addObject(Object object) { 230 | this.objects.add(object); 231 | } 232 | 233 | public void removeObject(Object object) { 234 | this.objects.remove(object); 235 | } 236 | 237 | public List getObjects() { 238 | return objects; 239 | } 240 | 241 | //创建迭代器的抽象工厂方法 242 | public abstract AbstractIterator iterator(); 243 | 244 | } 245 | ``` 246 | 247 | 2. *ProductList : 商品数据类,充当具体聚合类. ProductIterator(内部类) : 商品迭代器,充当具体迭代器* 248 | ```java 249 | package pers.huangyuhui.iterator2; 250 | 251 | import java.util.List; 252 | 253 | /** 254 | * @project: design-patterns 255 | * @description: 商品书籍类, 充当具体聚合类 256 | * @author: 黄宇辉 257 | * @date: 9/2/2019-5:56 PM 258 | * @version: 1.0 259 | * @website: https://yubuntu0109.github.io/ 260 | */ 261 | public class ProductList extends AbstractObjectList { 262 | 263 | public ProductList(List objects) { 264 | super(objects); 265 | } 266 | 267 | @Override 268 | public AbstractIterator iterator() { 269 | return new ProductIterator(); 270 | } 271 | 272 | /* 273 | ProductIterator:商品迭代器,充当具体迭代器(使用内部类实现迭代器,与jdk中的迭代器实现原理相同) 274 | */ 275 | public class ProductIterator implements AbstractIterator { 276 | 277 | private int cursor; 278 | 279 | public ProductIterator() { 280 | cursor = 0; 281 | } 282 | 283 | @Override 284 | public boolean hasNext() { 285 | return cursor < objects.size(); 286 | } 287 | 288 | @Override 289 | public Object next() { 290 | return objects.get(cursor++); 291 | } 292 | } 293 | 294 | } 295 | ``` 296 | 297 | 3. *AbstractIterator : 抽象迭代器* 298 | ```java 299 | package pers.huangyuhui.iterator2; 300 | 301 | /** 302 | * @project: design-patterns 303 | * @description: 抽象迭代器 304 | * @author: 黄宇辉 305 | * @date: 9/2/2019-5:55 PM 306 | * @version: 1.0 307 | * @website: https://yubuntu0109.github.io/ 308 | */ 309 | public interface AbstractIterator { 310 | 311 | boolean hasNext(); 312 | 313 | Object next(); 314 | } 315 | ``` 316 | 317 | 4. *Test : 测试类* 318 | ```java 319 | package pers.huangyuhui.iterator2; 320 | 321 | import java.util.ArrayList; 322 | import java.util.List; 323 | 324 | /** 325 | * @project: design-patterns 326 | * @description: 测试类 327 | * @author: 黄宇辉 328 | * @date: 9/2/2019-6:13 PM 329 | * @version: 1.0 330 | * @website: https://yubuntu0109.github.io/ 331 | */ 332 | public class Test { 333 | 334 | //demo 335 | public static void main(String[] args) { 336 | List arrayList = new ArrayList<>(); 337 | arrayList.add("A-BOOK"); 338 | arrayList.add("B-BOOK"); 339 | arrayList.add("C-BOOK"); 340 | 341 | ProductList productList = new ProductList(arrayList); 342 | productList.addObject("D-BOOK"); 343 | productList.addObject("E-BOOK"); 344 | productList.removeObject("A-BOOK"); 345 | 346 | AbstractIterator iterator = productList.iterator(); 347 | while (iterator.hasNext()) { 348 | System.out.println(iterator.next()); 349 | } 350 | System.out.println("all datas : " + productList.getObjects().toString()); 351 | 352 | } 353 | } 354 | ``` 355 | 356 | 5. *程序运行结果如下所示 :* 357 | ``` 358 | B-BOOK 359 | C-BOOK 360 | D-BOOK 361 | E-BOOK 362 | all datas : [B-BOOK, C-BOOK, D-BOOK, E-BOOK] 363 | ``` 364 | 365 | #### 示例程序的类图 366 | ![ ](https://raw.githubusercontent.com/YUbuntu0109/YUbuntu0109.github.io/HexoBackup/source/_posts/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BIterator-Pattern/Iterator2-ClassDiagram.png) 367 | 368 | 369 | 370 | *📚参与书籍 : 《图解设计模式 - [日]结诚浩 · 著》, 《Java设计模式 - 刘伟编 · 著》* -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/iterator_pattern/iterator1/Aggregate.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.iterator_pattern.iterator1; 2 | 3 | 4 | /** 5 | * @project: design-patterns 6 | * @description: 集合 7 | * @author: 黄宇辉 8 | * @date: 9/2/2019-5:00 PM 9 | * @version: 1.0 10 | * @website: https://yubuntu0109.github.io/ 11 | */ 12 | public interface Aggregate { 13 | Iterator iterator(); 14 | } 15 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/iterator_pattern/iterator1/Book.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.iterator_pattern.iterator1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: Book信息 6 | * @author: 黄宇辉 7 | * @date: 9/2/2019-4:59 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Book { 12 | 13 | private String name; 14 | 15 | public Book(String name) { 16 | this.name = name; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/iterator_pattern/iterator1/BookSelf.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.iterator_pattern.iterator1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 具体的集合 6 | * @author: 黄宇辉 7 | * @date: 9/2/2019-5:03 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class BookSelf implements Aggregate { 12 | private Book[] books; 13 | private int last = 0; 14 | 15 | public BookSelf(int maxsize) { 16 | this.books = new Book[maxsize]; 17 | } 18 | 19 | public Book getBookByIndex(int index) { 20 | return books[index]; 21 | } 22 | 23 | public void appendBook(Book book) { 24 | this.books[last++] = book; 25 | } 26 | 27 | public int getLength() { 28 | return last; 29 | } 30 | 31 | @Override 32 | public Iterator iterator() { 33 | return new BookShelfIterator(this); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/iterator_pattern/iterator1/BookShelfIterator.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.iterator_pattern.iterator1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 集体的迭代器 6 | * @author: 黄宇辉 7 | * @date: 9/2/2019-5:07 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class BookShelfIterator implements Iterator { 12 | 13 | private BookSelf bookSelf; 14 | private int index; 15 | 16 | public BookShelfIterator(BookSelf bookSelf) { 17 | this.bookSelf = bookSelf; 18 | this.index = 0; 19 | } 20 | 21 | @Override 22 | public boolean hasNext() { 23 | return index < bookSelf.getLength(); 24 | } 25 | 26 | @Override 27 | public Object next() { 28 | return bookSelf.getBookByIndex(index++); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/iterator_pattern/iterator1/Iterator.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.iterator_pattern.iterator1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 迭代器 6 | * @author: 黄宇辉 7 | * @date: 9/2/2019-5:01 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface Iterator { 12 | boolean hasNext(); 13 | 14 | Object next(); 15 | } 16 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/iterator_pattern/iterator1/Test1.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.iterator_pattern.iterator1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 测试类 6 | * @author: 黄宇辉 7 | * @date: 9/2/2019-5:09 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Test1 { 12 | 13 | //adapter_pattern 14 | public static void main(String[] args) { 15 | BookSelf bookSelf = new BookSelf(5); 16 | bookSelf.appendBook(new Book("A-BOOK")); 17 | bookSelf.appendBook(new Book("B-BOOK")); 18 | bookSelf.appendBook(new Book("C-BOOK")); 19 | bookSelf.appendBook(new Book("D-BOOK")); 20 | bookSelf.appendBook(new Book("E-BOOK")); 21 | Iterator iterator = bookSelf.iterator(); 22 | while (iterator.hasNext()) { 23 | Book book = (Book) iterator.next(); 24 | System.out.println(book.getName()); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/iterator_pattern/iterator2/AbstractIterator.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.iterator_pattern.iterator2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象迭代器 6 | * @author: 黄宇辉 7 | * @date: 9/2/2019-5:55 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface AbstractIterator { 12 | 13 | boolean hasNext(); 14 | 15 | Object next(); 16 | } 17 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/iterator_pattern/iterator2/AbstractObjectList.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.iterator_pattern.iterator2; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @project: design-patterns 7 | * @description: 抽象聚合类 8 | * @author: 黄宇辉 9 | * @date: 9/2/2019-5:51 PM 10 | * @version: 1.0 11 | * @website: https://yubuntu0109.github.io/ 12 | */ 13 | public abstract class AbstractObjectList { 14 | 15 | protected List objects; 16 | 17 | public AbstractObjectList(List objects) { 18 | this.objects = objects; 19 | } 20 | 21 | public void addObject(Object object) { 22 | this.objects.add(object); 23 | } 24 | 25 | public void removeObject(Object object) { 26 | this.objects.remove(object); 27 | } 28 | 29 | public List getObjects() { 30 | return objects; 31 | } 32 | 33 | //创建迭代器的抽象工厂方法 34 | public abstract AbstractIterator iterator(); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/iterator_pattern/iterator2/ProductList.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.iterator_pattern.iterator2; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @project: design-patterns 7 | * @description: 商品书籍类, 充当具体聚合类 8 | * @author: 黄宇辉 9 | * @date: 9/2/2019-5:56 PM 10 | * @version: 1.0 11 | * @website: https://yubuntu0109.github.io/ 12 | */ 13 | public class ProductList extends AbstractObjectList { 14 | 15 | public ProductList(List objects) { 16 | super(objects); 17 | } 18 | 19 | @Override 20 | public AbstractIterator iterator() { 21 | return new ProductIterator(); 22 | } 23 | 24 | /* 25 | ProductIterator:商品迭代器,充当具体迭代器(使用内部类实现迭代器,与jdk中的迭代器实现原理相同) 26 | */ 27 | public class ProductIterator implements AbstractIterator { 28 | 29 | private int cursor; 30 | 31 | public ProductIterator() { 32 | cursor = 0; 33 | } 34 | 35 | @Override 36 | public boolean hasNext() { 37 | return cursor < objects.size(); 38 | } 39 | 40 | @Override 41 | public Object next() { 42 | return objects.get(cursor++); 43 | } 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/iterator_pattern/iterator2/Test2.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.iterator_pattern.iterator2; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @project: design-patterns 8 | * @description: 测试类 9 | * @author: 黄宇辉 10 | * @date: 9/2/2019-6:13 PM 11 | * @version: 1.0 12 | * @website: https://yubuntu0109.github.io/ 13 | */ 14 | public class Test2 { 15 | 16 | //adapter_pattern 17 | public static void main(String[] args) { 18 | List arrayList = new ArrayList<>(); 19 | arrayList.add("A-BOOK"); 20 | arrayList.add("B-BOOK"); 21 | arrayList.add("C-BOOK"); 22 | 23 | ProductList productList = new ProductList(arrayList); 24 | productList.addObject("D-BOOK"); 25 | productList.addObject("E-BOOK"); 26 | productList.removeObject("A-BOOK"); 27 | 28 | AbstractIterator iterator = productList.iterator(); 29 | while (iterator.hasNext()) { 30 | System.out.println(iterator.next()); 31 | } 32 | System.out.println("all datas : " + productList.getObjects().toString()); 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_1/Button.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 按钮类, 充当具体同事类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:51 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Button extends Component { 12 | public void update() { 13 | //System.out.println("点击添加信息按钮"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_1/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:58 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | //定义中介者对象 15 | ConcreteMediator mediator = new ConcreteMediator(); 16 | 17 | //定义同事对象 18 | List list = new List(); 19 | Button addButton = new Button(); 20 | ComboBox comboBox = new ComboBox(); 21 | TextBox userNameTextBox = new TextBox(); 22 | 23 | //关联中介者 24 | list.setMediator(mediator); 25 | comboBox.setMediator(mediator); 26 | addButton.setMediator(mediator); 27 | userNameTextBox.setMediator(mediator); 28 | 29 | //初始化具体同事类 30 | mediator.list = list; 31 | mediator.comboBox = comboBox; 32 | mediator.addButton = addButton; 33 | mediator.userNameTextBox = userNameTextBox; 34 | 35 | //通过中介者进行通信 36 | addButton.changed(); //点击添加客户信息按钮 37 | list.changed(); //从列表框中选择客户 38 | comboBox.changed(); //从组合框中选择客户 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_1/ComboBox.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 组合框类, 充当具体同事类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:55 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class ComboBox extends Component { 12 | 13 | public void update() { 14 | System.out.println("组合框增加一项: 黄宇辉"); 15 | } 16 | 17 | public void select() { 18 | System.out.println("组合框选中项: 黄浩然"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_1/Component.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象组件类, 充当抽象同事类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:51 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class Component { 12 | 13 | protected Mediator mediator; 14 | 15 | public void setMediator(Mediator mediator) { 16 | this.mediator = mediator; 17 | } 18 | 19 | //转发调用 20 | public void changed() { 21 | mediator.componentChanged(this); 22 | } 23 | 24 | public abstract void update(); 25 | } 26 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_1/ConcreteMediator.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 具体中介者类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:50 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class ConcreteMediator extends Mediator { 12 | 13 | //维持对各个同事对象的引用 14 | public List list; 15 | public Button addButton; 16 | public TextBox userNameTextBox; 17 | public ComboBox comboBox; 18 | 19 | //封装同事对象之间的交互 20 | @Override 21 | public void componentChanged(Component component) { 22 | //单击按钮 23 | if (component == addButton) { 24 | System.out.println("--- 点击增加信息按钮 ---"); 25 | list.update(); 26 | comboBox.update(); 27 | userNameTextBox.update(); 28 | } 29 | //从列表框选择客户 30 | else if (component == list) { 31 | System.out.println("\n--- 从列表框选择客户 ---"); 32 | list.select(); 33 | userNameTextBox.setText(); 34 | } 35 | //从组合框选择客户 36 | else if (component == comboBox) { 37 | System.out.println("\n--- 从组合框选择客户 ---"); 38 | comboBox.select(); 39 | userNameTextBox.setText(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_1/List.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 列表框类, 充当具体同事类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:52 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class List extends Component { 12 | 13 | public void update() { 14 | System.out.println("列表框增加一项: 黄宇辉"); 15 | } 16 | 17 | public void select() { 18 | System.out.println("列表框选中项: 黄浩然"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_1/Mediator.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象中介者类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:49 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class Mediator { 12 | public abstract void componentChanged(Component component); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_1/TextBox.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文本框, 充当具体同事类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:56 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class TextBox extends Component { 12 | 13 | public void update() { 14 | System.out.println("客户信息增加成功后文本框被清空"); 15 | } 16 | 17 | public void setText() { 18 | System.out.println("文本框显示: 黄浩然"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_2/Button.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 按钮类, 充当具体同事类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:51 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Button extends Component { 12 | public void update() { 13 | //System.out.println("点击增加信息按钮"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_2/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:58 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | //定义中介者对象 15 | SubConcreteMediator mediator = new SubConcreteMediator(); 16 | 17 | //定义同事对象 18 | List list = new List(); 19 | Label label = new Label(); 20 | Button addButton = new Button(); 21 | ComboBox comboBox = new ComboBox(); 22 | TextBox userNameTextBox = new TextBox(); 23 | 24 | //关联中介者 25 | list.setMediator(mediator); 26 | label.setMediator(mediator); 27 | comboBox.setMediator(mediator); 28 | addButton.setMediator(mediator); 29 | userNameTextBox.setMediator(mediator); 30 | 31 | //初始化具体同事类 32 | mediator.list = list; 33 | mediator.label = label; 34 | mediator.comboBox = comboBox; 35 | mediator.addButton = addButton; 36 | mediator.userNameTextBox = userNameTextBox; 37 | 38 | //通过中介者进行通信 39 | addButton.changed(); //点击添加客户按钮 40 | list.changed(); //从列表框中选择客户 41 | comboBox.changed(); //从组合框中选择客户 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_2/ComboBox.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 组合框类, 充当具体同事类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:55 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class ComboBox extends Component { 12 | 13 | public void update() { 14 | System.out.println("组合框增加一项: 黄宇辉"); 15 | } 16 | 17 | public void select() { 18 | System.out.println("组合框选中项: 赵艳春"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_2/Component.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象组件类, 充当抽象同事类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:51 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class Component { 12 | 13 | protected Mediator mediator; 14 | 15 | public void setMediator(Mediator mediator) { 16 | this.mediator = mediator; 17 | } 18 | 19 | //转发调用 20 | public void changed() { 21 | mediator.componentChanged(this); 22 | } 23 | 24 | public abstract void update(); 25 | } 26 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_2/ConcreteMediator.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 具体中介者类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:50 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class ConcreteMediator extends Mediator { 12 | 13 | //维持对各个同事对象的引用 14 | public List list; 15 | public Button addButton; 16 | public ComboBox comboBox; 17 | public TextBox userNameTextBox; 18 | 19 | //封装同事对象之间的交互 20 | @Override 21 | public void componentChanged(Component component) { 22 | //单击按钮 23 | if (component == addButton) { 24 | System.out.println("--- 单击增加同事按钮 ---"); 25 | list.update(); 26 | comboBox.update(); 27 | userNameTextBox.update(); 28 | } 29 | //从列表框选择客户 30 | else if (component == list) { 31 | System.out.println("\n--- 从列表框选择客户 ---"); 32 | list.select(); 33 | userNameTextBox.setText(); 34 | } 35 | //从组合框选择客户 36 | else if (component == comboBox) { 37 | System.out.println("\n--- 从组合框选择客户 ---"); 38 | comboBox.select(); 39 | userNameTextBox.setText(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_2/Label.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文本标签类, 具体同事类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-1:30 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Label extends Component { 12 | 13 | public void update() { 14 | System.out.println("[ 文本标签内容改变,客户信息总数: +1 ]"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_2/List.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 列表框类, 充当具体同事类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:52 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class List extends Component { 12 | 13 | public void update() { 14 | System.out.println("列表框增加一项: 黄宇辉"); 15 | } 16 | 17 | public void select() { 18 | System.out.println("列表框选中项: 赵艳春"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_2/Mediator.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象中介者类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:49 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class Mediator { 12 | public abstract void componentChanged(Component component); 13 | } 14 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_2/SubConcreteMediator.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 在新增的该中介者类, 通过覆写componentChanged()方法来实现所有组件(包括新增Label组件)之间的交互 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-1:30 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class SubConcreteMediator extends ConcreteMediator { 12 | 13 | //增加对Label对象的引用 14 | public Label label; 15 | 16 | @Override 17 | public void componentChanged(Component component) { 18 | //super.componentChanged(component); 19 | //单击按钮 20 | if (component == addButton) { 21 | System.out.println("--- 点击增加信息按钮 ---"); 22 | list.update(); 23 | comboBox.update(); 24 | userNameTextBox.update(); 25 | label.update(); //更新文本标签 26 | } 27 | //从列表框选择客户 28 | else if (component == list) { 29 | System.out.println("\n--- 从列表框选择客户 ---"); 30 | list.select(); 31 | userNameTextBox.setText(); 32 | } 33 | //从组合框选择客户 34 | else if (component == comboBox) { 35 | System.out.println("\n--- 从组合框选择客户 ---"); 36 | comboBox.select(); 37 | userNameTextBox.setText(); 38 | } 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/mediator_pattern/mediator_pattern_2/TextBox.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.mediator_pattern.mediator_pattern_2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 文本框, 充当具体同事类 6 | * @author: 黄宇辉 7 | * @date: 10/10/2019-12:56 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class TextBox extends Component { 12 | 13 | public void update() { 14 | System.out.println("客户信息增加成功后文本被清空"); 15 | } 16 | 17 | public void setText() { 18 | System.out.println("文本框显示: 赵艳春"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/observer_pattern/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Java设计模式之Observer Pattern 3 | date: 2019-09-28 13:39:33 4 | tags: [Java,design and pattern] 5 | --- 6 | 7 | ## 学习笔记 : Java设计模式之Observer Pattern 8 | 9 | ### 定义 10 | *观察者设计模式 : 定义对象之间的一种一对多的依赖关系,使得每当一个对象状态发生改变时其相关依赖对象皆得到通知并被自动更新. ( Observer Pattern : Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically )* 11 | 12 | ### 概述 13 | *观察者模式的别名有发布-订阅( Publish-Subscribe )模式,模型-视图( Model-View )模式,源-监听器( Source-Listener )模式,从属者( Dependents )模式. 观察者模式是一种对象行为模式. 其用于描述对象之间的依赖关系,为实现多个对象之间的联动提供了一种解决方案,是一种对象行为型模式.* 14 | 15 | ### 角色分析 16 | 1. *`Subject( 目标 )` : 目标又称为主题,它是指被观察的对象. 在目标中定义了一个观察者集合,一个观察者目标可以接收任意数量的观察者来观察,它提供了一系列方法来增加和删除观察者对象,同时它定义了通知方法 notify(). 目标类可以是接口,也可以是抽象类或具体类.* 17 | 2. *`ConcreteSubject( 具体目标 )` : 具体目标是目标类的子类,它通常包含有经常方法改变的数据,当它的状态发生改变时将向它的各个观察者发出通知,同时还可以实现了在目标类中定义的抽象业务逻辑方法. 如果无需扩展目标类,则具体目标类可以省略.* 18 | 3. *`Observer( 观察者 )` : 观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的 update() 方法,因此又称为抽象观察者.* 19 | 4. *`ConcreteObserver( 具体观察者 )` : 在具体观察者中维护了一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和目标的状态保持一致. 它实现了在抽象观察者 Observer 中定义的 update() 方法. 通常在实现时可以调用具体目标类的 attach() 方法将自己添加到目标类的集合中或通过 detach() 方法将自己从目标类的集合中删除.* 20 | 21 | ### 示例程序 22 | *下面是一个使用观察者设计模式的简单示例程序,模拟功能 : 在某多人联机对战游戏中,多个玩家可以加入同一战队组成联盟,当战队中的某一成员被敌人攻击时,其可以向其它队友发送求救通知,队友接收通知后作出相应的反应,既而来实现战队成员之间的联动~* 23 | 24 | 1. *AllyControllerCenter抽象类 : 指挥部(战队控制中心)类, 充当抽象目标类* 25 | ```java 26 | package pers.huangyuhui.observer_pattern.observer_pattern_1; 27 | 28 | import java.util.ArrayList; 29 | 30 | /** 31 | * @project: design-patterns 32 | * @description: 指挥部(战队控制中心)类, 充当抽象目标类 33 | * @author: 黄宇辉 34 | * @date: 9/29/2019-12:02 PM 35 | * @version: 1.0 36 | * @website: https://yubuntu0109.github.io/ 37 | */ 38 | public abstract class AllyControllerCenter { 39 | 40 | protected String allyName; 41 | 42 | //定义一个集合用于存储战队成员 43 | protected ArrayList players = new ArrayList<>(); 44 | 45 | public void setAllyName(String allyName) { 46 | this.allyName = allyName; 47 | } 48 | 49 | public String getAllyName(String allyName) { 50 | return allyName; 51 | } 52 | 53 | //注册方法 54 | public void join(Observer observer) { 55 | System.out.println("玩家: [ " + observer.getName() + " ]加入战队"); 56 | players.add(observer); 57 | } 58 | 59 | //注销方法 60 | public void quit(Observer observer) { 61 | System.out.println("玩家: [ " + observer.getName() + " ]退出战队"); 62 | players.remove(observer); 63 | } 64 | 65 | //声明抽象通知方法 66 | public abstract void noifyObserver(String name); 67 | } 68 | ``` 69 | 70 | 2. *ConcreteAllyControlCenter类 : 具体指挥部类, 充当具体目标类* 71 | ```java 72 | package pers.huangyuhui.observer_pattern.observer_pattern_1; 73 | 74 | /** 75 | * @project: design-patterns 76 | * @description: 具体指挥部类, 充当具体目标类 77 | * @author: 黄宇辉 78 | * @date: 9/29/2019-12:16 PM 79 | * @version: 1.0 80 | * @website: https://yubuntu0109.github.io/ 81 | */ 82 | public class ConcreteAllyControlCenter extends AllyControllerCenter { 83 | 84 | public ConcreteAllyControlCenter(String allyName) { 85 | this.allyName = allyName; 86 | System.out.println("------ 战队: [ " + allyName + " ]组建成功 ------"); 87 | } 88 | 89 | //实现通知方法 90 | @Override 91 | public void noifyObserver(String name) { 92 | System.out.println("战队: [ " + this.allyName + " ]指挥部发送的紧急通知 : 队友[ " + name + " ]正在遭受敌人攻击"); 93 | //遍历观察者集合,调用每一个队友(除自己)的支援方法 94 | for (Observer player : players) { 95 | if (!(player.getName().equalsIgnoreCase(name))) { 96 | player.help(); 97 | } 98 | } 99 | } 100 | } 101 | ``` 102 | 103 | 3. *Observer接口 : 抽象观察者类* 104 | ```java 105 | package pers.huangyuhui.observer_pattern.observer_pattern_1; 106 | 107 | /** 108 | * @project: design-patterns 109 | * @description: 抽象观察者类 110 | * @author: 黄宇辉 111 | * @date: 9/29/2019-12:05 PM 112 | * @version: 1.0 113 | * @website: https://yubuntu0109.github.io/ 114 | */ 115 | public interface Observer { 116 | 117 | String getName(); 118 | 119 | void setName(String name); 120 | 121 | void help(); //声明支援盟友的方法 122 | 123 | void beAttacked(AllyControllerCenter allyControllerCenter); //声明遭受攻击的方法 124 | } 125 | ``` 126 | 127 | 4. *Player类 : 战队成员类, 充当具体观察者类* 128 | ```java 129 | package pers.huangyuhui.observer_pattern.observer_pattern_1; 130 | 131 | /** 132 | * @project: design-patterns 133 | * @description: 战队成员类, 充当具体观察者类 134 | * @author: 黄宇辉 135 | * @date: 9/29/2019-12:21 PM 136 | * @version: 1.0 137 | * @website: https://yubuntu0109.github.io/ 138 | */ 139 | public class Player implements Observer { 140 | 141 | private String name; 142 | 143 | public Player(String name) { 144 | this.name = name; 145 | } 146 | 147 | @Override 148 | public String getName() { 149 | return name; 150 | } 151 | 152 | @Override 153 | public void setName(String name) { 154 | this.name = name; 155 | } 156 | 157 | //支援盟友方法的实现 158 | @Override 159 | public void help() { 160 | System.out.println("坚持住! 队友:[ " + this.name + " ]前来支援你"); 161 | } 162 | 163 | //遭受攻击方法的实现,当遭受攻击时将调用战队控制中心类的通知方法noifyObserver()来通知各个盟友 164 | @Override 165 | public void beAttacked(AllyControllerCenter allyControllerCenter) { 166 | System.out.println("队友: [ " + this.name + " ]正在被敌人攻击"); 167 | allyControllerCenter.noifyObserver(name); 168 | } 169 | 170 | } 171 | ``` 172 | 173 | 5. *Client类 : 客户端测试类* 174 | ```java 175 | package pers.huangyuhui.observer_pattern.observer_pattern_1; 176 | 177 | /** 178 | * @project: design-patterns 179 | * @description: 客户端测试类 180 | * @author: 黄宇辉 181 | * @date: 9/29/2019-12:31 PM 182 | * @version: 1.0 183 | * @website: https://yubuntu0109.github.io/ 184 | */ 185 | public class Client { 186 | 187 | public static void main(String[] args) { 188 | //定义观察目标对象 189 | AllyControllerCenter allyControllerCenter = new ConcreteAllyControlCenter("YU"); 190 | 191 | //定义四个观察者对象 192 | Observer player1, player2, player3, player4; 193 | player1 = new Player("player-A"); 194 | allyControllerCenter.join(player1); 195 | player2 = new Player("player-B"); 196 | allyControllerCenter.join(player2); 197 | player3 = new Player("player-C"); 198 | allyControllerCenter.join(player3); 199 | player4 = new Player("player-D"); 200 | allyControllerCenter.join(player4); 201 | 202 | //player-A队友遭受敌人攻击 203 | player1.beAttacked(allyControllerCenter); 204 | 205 | } 206 | } 207 | ``` 208 | 209 | 6. *示例程序的运行结果如下所示 :* 210 | ``` 211 | ------ 战队: [ YU ]组建成功 ------ 212 | 玩家: [ player-A ]加入战队 213 | 玩家: [ player-B ]加入战队 214 | 玩家: [ player-C ]加入战队 215 | 玩家: [ player-D ]加入战队 216 | 队友: [ player-A ]正在被敌人攻击 217 | 战队: [ YU ]指挥部发送的紧急通知 : 队友[ player-A ]正在遭受敌人攻击 218 | 坚持住! 队友:[ player-B ]前来支援你 219 | 坚持住! 队友:[ player-C ]前来支援你 220 | 坚持住! 队友:[ player-D ]前来支援你 221 | ``` 222 | 223 | #### 示例程序的类图 224 | ![ ](https://raw.githubusercontent.com/YUbuntu0109/YUbuntu0109.github.io/623c45823d184ed7385a9d83cbc35f97727c835c/source/_posts/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BObserver-Pattern/Observer-Pattern-ClassDiagram1.png) 225 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/observer_pattern/observer_pattern_1/AllyControllerCenter.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.observer_pattern.observer_pattern_1; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * @project: design-patterns 7 | * @description: 指挥部(战队控制中心)类, 充当抽象目标类 8 | * @author: 黄宇辉 9 | * @date: 9/29/2019-12:02 PM 10 | * @version: 1.0 11 | * @website: https://yubuntu0109.github.io/ 12 | */ 13 | public abstract class AllyControllerCenter { 14 | 15 | protected String allyName; 16 | 17 | //定义一个集合用于存储战队成员 18 | protected ArrayList players = new ArrayList<>(); 19 | 20 | public void setAllyName(String allyName) { 21 | this.allyName = allyName; 22 | } 23 | 24 | public String getAllyName(String allyName) { 25 | return allyName; 26 | } 27 | 28 | //注册方法 29 | public void join(Observer observer) { 30 | System.out.println("玩家: [ " + observer.getName() + " ]加入战队"); 31 | players.add(observer); 32 | } 33 | 34 | //注销方法 35 | public void quit(Observer observer) { 36 | System.out.println("玩家: [ " + observer.getName() + " ]退出战队"); 37 | players.remove(observer); 38 | } 39 | 40 | //声明抽象通知方法 41 | public abstract void noifyObserver(String name); 42 | } 43 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/observer_pattern/observer_pattern_1/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.observer_pattern.observer_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/29/2019-12:31 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | //定义观察目标对象 15 | AllyControllerCenter allyControllerCenter = new ConcreteAllyControlCenter("YU"); 16 | 17 | //定义四个观察者对象 18 | Observer player1, player2, player3, player4; 19 | player1 = new Player("player-A"); 20 | allyControllerCenter.join(player1); 21 | player2 = new Player("player-B"); 22 | allyControllerCenter.join(player2); 23 | player3 = new Player("player-C"); 24 | allyControllerCenter.join(player3); 25 | player4 = new Player("player-D"); 26 | allyControllerCenter.join(player4); 27 | 28 | //player-A队友遭受敌人攻击 29 | player1.beAttacked(allyControllerCenter); 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/observer_pattern/observer_pattern_1/ConcreteAllyControlCenter.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.observer_pattern.observer_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 具体指挥部类, 充当具体目标类 6 | * @author: 黄宇辉 7 | * @date: 9/29/2019-12:16 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class ConcreteAllyControlCenter extends AllyControllerCenter { 12 | 13 | public ConcreteAllyControlCenter(String allyName) { 14 | this.allyName = allyName; 15 | System.out.println("------ 战队: [ " + allyName + " ]组建成功 ------"); 16 | } 17 | 18 | //实现通知方法 19 | @Override 20 | public void noifyObserver(String name) { 21 | System.out.println("战队: [ " + this.allyName + " ]指挥部发送的紧急通知 : 队友[ " + name + " ]正在遭受敌人攻击"); 22 | //遍历观察者集合,调用每一个队友(除自己)的支援方法 23 | for (Observer player : players) { 24 | if (!(player.getName().equalsIgnoreCase(name))) { 25 | player.help(); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/observer_pattern/observer_pattern_1/Observer.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.observer_pattern.observer_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象观察者类 6 | * @author: 黄宇辉 7 | * @date: 9/29/2019-12:05 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface Observer { 12 | 13 | String getName(); 14 | 15 | void setName(String name); 16 | 17 | void help(); //声明支援盟友的方法 18 | 19 | void beAttacked(AllyControllerCenter allyControllerCenter); //声明遭受攻击的方法 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/observer_pattern/observer_pattern_1/Player.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.observer_pattern.observer_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 战队成员类, 充当具体观察者类 6 | * @author: 黄宇辉 7 | * @date: 9/29/2019-12:21 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Player implements Observer { 12 | 13 | private String name; 14 | 15 | public Player(String name) { 16 | this.name = name; 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | @Override 25 | public void setName(String name) { 26 | this.name = name; 27 | } 28 | 29 | //支援盟友方法的实现 30 | @Override 31 | public void help() { 32 | System.out.println("坚持住! 队友:[ " + this.name + " ]前来支援你"); 33 | } 34 | 35 | //遭受攻击方法的实现,当遭受攻击时将调用战队控制中心类的通知方法noifyObserver()来通知各个盟友 36 | @Override 37 | public void beAttacked(AllyControllerCenter allyControllerCenter) { 38 | System.out.println("队友: [ " + this.name + " ]正在被敌人攻击"); 39 | allyControllerCenter.noifyObserver(name); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/simple_factory_pattern/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Java设计模式之Simple Factory Pattern 3 | date: 2019-09-06 09:35:53 4 | tags: [Java,design and pattern] 5 | --- 6 | 7 | ## 学习笔记 : Java设计模式之Simple Factory Pattern 8 | 9 | ### 概述 10 | *简单工厂模式( Simple Factory Pattern) : 定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类. 其是一种创建型模式,需注意 : 简单工厂模式并不属于23种经典设计模式,但通常将它作为学习其他工厂模式的基础.* 11 | 12 | ### 简单工厂模式中的角色 13 | 1. *`Factory( 工厂角色 )` : 工厂角色既工厂类,它是简单工厂模式的核心,负责实现创建所有产品实例的内部结构. 工厂类可以被外界访问直接调用,创建所需的产品对象. 在工厂类中提供了静态的工厂方法,其返回类型为抽象产品类型.* 14 | 2. *`Product( 抽象产品角色 )` : 它是工厂类创建的所有对象的父类,封装了各种对象的公有方法,它的引入提高了系统的灵活性.* 15 | 3. *`ConcreteProduct( 具体产品角色 )` : 它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例. 每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中的抽象方法.* 16 | 17 | ### 程序示例 18 | *下面是一个使用简单工厂模式的简单程序示例,其功能( 模拟 )描述 : 通过设置不同的参数即可得到不同类型的图表,而且可以较为方便地对图表进行扩展,以便能够在将来增加一些新类型的图表.* 19 | 20 | 1. *Chart接口 : 抽象图表接口, 充当抽象产品类* 21 | ```java 22 | package pers.huangyuhui.simple_factory_pattern; 23 | 24 | /** 25 | * @project: design-patterns 26 | * @description: 抽象图表接口, 充当抽象产品类 27 | * @author: 黄宇辉 28 | * @date: 9/6/2019-9:36 AM 29 | * @version: 1.0 30 | * @website: https://yubuntu0109.github.io/ 31 | */ 32 | public interface Chart { 33 | 34 | void display(); 35 | } 36 | ``` 37 | 38 | 2. *HistogramChart类 : 柱状图类, 充当具体产品类* 39 | ```java 40 | package pers.huangyuhui.simple_factory_pattern; 41 | 42 | /** 43 | * @project: design-patterns 44 | * @description: 柱状图类, 充当具体产品类 45 | * @author: 黄宇辉 46 | * @date: 9/6/2019-9:37 AM 47 | * @version: 1.0 48 | * @website: https://yubuntu0109.github.io/ 49 | */ 50 | public class HistogramChart implements Chart { 51 | 52 | public HistogramChart() { 53 | System.out.println("创建柱状图"); 54 | } 55 | 56 | @Override 57 | public void display() { 58 | System.out.println("显示柱状图"); 59 | } 60 | } 61 | ``` 62 | 63 | 3. *PieChart类 : 饼状图类, 充当具体产品类* 64 | ```java 65 | package pers.huangyuhui.simple_factory_pattern; 66 | 67 | /** 68 | * @project: design-patterns 69 | * @description: 饼状图类, 充当具体产品类 70 | * @author: 黄宇辉 71 | * @date: 9/6/2019-9:38 AM 72 | * @version: 1.0 73 | * @website: https://yubuntu0109.github.io/ 74 | */ 75 | public class PieChart implements Chart { 76 | 77 | public PieChart() { 78 | System.out.println("创建饼状图"); 79 | } 80 | 81 | @Override 82 | public void display() { 83 | System.out.println("显示饼状图"); 84 | } 85 | } 86 | ``` 87 | 88 | 4. *ChartFactory类 : 图表工厂类, 充当工厂类* 89 | ```java 90 | package pers.huangyuhui.simple_factory_pattern; 91 | 92 | /** 93 | * @project: design-patterns 94 | * @description: 图表工厂类, 充当工厂类 95 | * @author: 黄宇辉 96 | * @date: 9/6/2019-9:40 AM 97 | * @version: 1.0 98 | * @website: https://yubuntu0109.github.io/ 99 | */ 100 | public class ChartFactory { 101 | 102 | //静态工厂方法 103 | public static Chart getChar(String type) { 104 | Chart chart = null; 105 | if (type.equalsIgnoreCase("histogram")) { 106 | chart = new HistogramChart(); 107 | System.out.println("初始化柱状图"); 108 | } else if (type.equalsIgnoreCase("pie")) { 109 | chart = new PieChart(); 110 | System.out.println("初始化饼状图"); 111 | } else { 112 | System.out.println("error : not found the object for the specified parameter"); 113 | } 114 | return chart; 115 | } 116 | } 117 | ``` 118 | 119 | 5. *Client类 : 客户端测试类* 120 | ```java 121 | package pers.huangyuhui.simple_factory_pattern; 122 | 123 | /** 124 | * @project: design-patterns 125 | * @description: 客户端测试类 126 | * @author: 黄宇辉 127 | * @date: 9/6/2019-9:47 AM 128 | * @version: 1.0 129 | * @website: https://yubuntu0109.github.io/ 130 | */ 131 | public class Client { 132 | public static void main(String[] args) { 133 | Chart histogram = ChartFactory.getChar("histogram"); 134 | histogram.display(); 135 | } 136 | } 137 | ``` 138 | 139 | 5. *程序运行结果如下所示 :* 140 | ``` 141 | 创建柱状图 142 | 初始化柱状图 143 | 显示柱状图 144 | ``` 145 | 146 | #### 示例程序类图 147 | ![ ](https://raw.githubusercontent.com/YUbuntu0109/YUbuntu0109.github.io/HexoBackup/source/_posts/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BSimple-Factory-Pattern/Simple-Factory-Pattern-ClassDiagram.png) 148 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/simple_factory_pattern/simple_factory_pattern_1/Chart.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.simple_factory_pattern.simple_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 抽象图表接口, 充当抽象产品类 6 | * @author: 黄宇辉 7 | * @date: 9/6/2019-9:36 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public interface Chart { 12 | 13 | void display(); 14 | } 15 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/simple_factory_pattern/simple_factory_pattern_1/ChartFactory.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.simple_factory_pattern.simple_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 图表工厂类, 充当工厂类 6 | * @author: 黄宇辉 7 | * @date: 9/6/2019-9:40 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class ChartFactory { 12 | 13 | //静态工厂方法 14 | public static Chart getChar(String type) { 15 | Chart chart = null; 16 | if (type.equalsIgnoreCase("histogram")) { 17 | chart = new HistogramChart(); 18 | System.out.println("初始化柱状图"); 19 | } else if (type.equalsIgnoreCase("pie")) { 20 | chart = new PieChart(); 21 | System.out.println("初始化饼状图"); 22 | } else { 23 | System.out.println("error : not found the object for the specified parameter"); 24 | } 25 | return chart; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/simple_factory_pattern/simple_factory_pattern_1/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.simple_factory_pattern.simple_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/6/2019-9:47 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | public static void main(String[] args) { 13 | Chart histogram = ChartFactory.getChar("histogram"); 14 | histogram.display(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/simple_factory_pattern/simple_factory_pattern_1/HistogramChart.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.simple_factory_pattern.simple_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 柱状图类, 充当具体产品类 6 | * @author: 黄宇辉 7 | * @date: 9/6/2019-9:37 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class HistogramChart implements Chart { 12 | 13 | public HistogramChart() { 14 | System.out.println("创建柱状图"); 15 | } 16 | 17 | @Override 18 | public void display() { 19 | System.out.println("显示柱状图"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/simple_factory_pattern/simple_factory_pattern_1/PieChart.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.simple_factory_pattern.simple_factory_pattern_1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 饼状图类, 充当具体产品类 6 | * @author: 黄宇辉 7 | * @date: 9/6/2019-9:38 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class PieChart implements Chart { 12 | 13 | public PieChart() { 14 | System.out.println("创建饼状图"); 15 | } 16 | 17 | @Override 18 | public void display() { 19 | System.out.println("显示饼状图"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/singleton_pattern/IoDH_singleton/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.singleton_pattern.IoDH_singleton; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/6/2019-11:14 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | System.out.println(Singleton.getInstance() == Singleton.getInstance()); //ture 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/singleton_pattern/IoDH_singleton/Singleton.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.singleton_pattern.IoDH_singleton; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 单例模式-内部类实现单例类 6 | * @author: 黄宇辉 7 | * @date: 9/6/2019-11:11 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Singleton { 12 | private Singleton() { 13 | 14 | } 15 | 16 | //静态内部类 17 | public static class HolderClass { 18 | private final static Singleton instance = new Singleton(); 19 | } 20 | 21 | public static Singleton getInstance() { 22 | return HolderClass.instance; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/singleton_pattern/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Java设计模式之Singleton Pattern 3 | date: 2019-09-06 13:32:05 4 | tags: [Java,design and pattern] 5 | --- 6 | 7 | ## 学习笔记 : Java设计模式之Singleton Pattern 8 | 9 | ### 概念 10 | *单例设计模式 : 确保一个类只能有一个实例,并提供一个全局访问点来访问这个实例. (Singleton Pattern : Ensure a class has only one intance,and provide a global point of access to it. ). 单例设计模式是一种对象创建型模式,其主要有三个要点 :* 11 | 1. *某个类只能有一个实例* 12 | 2. *必须自行创建这个实例* 13 | 3. *必须自行向系统提供这个实例* 14 | 15 | 16 | ### 示例程序-饿汉式单例 17 | *饿汉式单例类( Eager Singleton )是最简单的单例类,既类被加载时静态变量 instance 就会被初始化,程序示例如下所示 :* 18 | ```java 19 | package pers.huangyuhui.singleton_pattern.eager_singleton; 20 | 21 | /** 22 | * @project: design-patterns 23 | * @description: 单例模式-饿汉式单例类 24 | * @author: 黄宇辉 25 | * @date: 9/6/2019-10:44 AM 26 | * @version: 1.0 27 | * @website: https://yubuntu0109.github.io/ 28 | */ 29 | public class EagerSingleton { 30 | 31 | private static final EagerSingleton instance = new EagerSingleton(); 32 | 33 | private EagerSingleton() { 34 | 35 | } 36 | 37 | public static EagerSingleton getInstance() { 38 | return instance; 39 | } 40 | } 41 | ``` 42 | 43 | *注 : 从资源利用效率的角度来讲饿汉式单例不及懒汉式单例,而且系统加载时由于需要创建饿汉式单例对象,加载时间可能比较长.* 44 | 45 | 46 | ### 程序示例-懒汉式单例 47 | *与饿汉式单例不同的是,懒汉式单例类( Lazy Singleton )在第一次被引用时才会将自己实例化,当单例类被加载时并不会将自己实例化, 示例程序如下所示 :* 48 | ```java 49 | package pers.huangyuhui.singleton_pattern.lazy_singleton; 50 | 51 | /** 52 | * @project: design-patterns 53 | * @description: 单例模式-懒汉式单例类 54 | * @author: 黄宇辉 55 | * @date: 9/6/2019-10:50 AM 56 | * @version: 1.0 57 | * @website: https://yubuntu0109.github.io/ 58 | */ 59 | public class LazySingleton { 60 | 61 | //被volatile修饰的成员变量可以确保多个线程都能够正确处理 62 | private volatile static LazySingleton instance = null; 63 | 64 | private LazySingleton() { 65 | 66 | } 67 | 68 | public static LazySingleton getInstance() { 69 | //第一重判断 70 | if (instance == null) { 71 | //锁定代码块:确保任何时刻只有一个线程可执行此代码块 72 | synchronized (LazySingleton.class) { 73 | //第二重判断:防止产生多个单例对象 74 | if (instance == null) { 75 | instance = new LazySingleton(); 76 | } 77 | } 78 | } 79 | return instance; 80 | } 81 | } 82 | ``` 83 | 84 | *注 : 由于`volatile`关键字会屏蔽Java虚拟机所做的一切代码优化,继而可能会导致系统的运行效率降低,因此即使使用双重检查锁定来实现单例模式也不是一种完美的实现方法哟~* 85 | 86 | 87 | ### 示例程序-内部类实现单例 88 | *饿汉式单例不能实现延迟加载,不管将来用不用始终占据内存. 懒汉式单例类线程安全控制繁琐,而且性能受影响. 为了克服这些问题,在Java语言中可以通过使用 Initialization on Demand Holder( `IoDH` )技术来实现单例模式,示例程序如下所示 :* 89 | ```java 90 | package pers.huangyuhui.singleton_pattern.IoDH_singleton; 91 | 92 | /** 93 | * @project: design-patterns 94 | * @description: 单例模式-内部类实现单例类 95 | * @author: 黄宇辉 96 | * @date: 9/6/2019-11:11 AM 97 | * @version: 1.0 98 | * @website: https://yubuntu0109.github.io/ 99 | */ 100 | public class Singleton { 101 | private Singleton() { 102 | 103 | } 104 | 105 | //静态内部类 106 | public static class HolderClass { 107 | private final static Singleton instance = new Singleton(); 108 | } 109 | 110 | public static Singleton getInstance() { 111 | return HolderClass.instance; 112 | } 113 | 114 | } 115 | ``` 116 | 117 | *注 : 通过使用`IoDH`既可以实现延迟加载,又可以保证线程安全,不影响系统性能,既其为一种最好的Java语言单例模式实现方式,其缺点为很多面向对象语言并不支持IoDH哟~* 118 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/singleton_pattern/eager_singleton/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.singleton_pattern.eager_singleton; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/6/2019-10:47 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | System.out.println(EagerSingleton.getInstance() == EagerSingleton.getInstance()); //true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/singleton_pattern/eager_singleton/EagerSingleton.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.singleton_pattern.eager_singleton; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 单例模式-饿汉式单例类 6 | * @author: 黄宇辉 7 | * @date: 9/6/2019-10:44 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class EagerSingleton { 12 | 13 | private static final EagerSingleton instance = new EagerSingleton(); 14 | 15 | private EagerSingleton() { 16 | 17 | } 18 | 19 | public static EagerSingleton getInstance() { 20 | return instance; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/singleton_pattern/lazy_singleton/Client.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.singleton_pattern.lazy_singleton; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 客户端测试类 6 | * @author: 黄宇辉 7 | * @date: 9/6/2019-10:52 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Client { 12 | 13 | public static void main(String[] args) { 14 | System.out.println(LazySingleton.getInstance() == LazySingleton.getInstance()); //true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/singleton_pattern/lazy_singleton/LazySingleton.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.singleton_pattern.lazy_singleton; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 单例模式-懒汉式单例类 6 | * @author: 黄宇辉 7 | * @date: 9/6/2019-10:50 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class LazySingleton { 12 | 13 | //被volatile修饰的成员变量可以确保多个线程都能够正确处理 14 | private volatile static LazySingleton instance = null; 15 | 16 | private LazySingleton() { 17 | 18 | } 19 | 20 | public static LazySingleton getInstance() { 21 | //第一重判断 22 | if (instance == null) { 23 | //锁定代码块:确保任何时刻只有一个线程可执行此代码块 24 | synchronized (LazySingleton.class) { 25 | //第二重判断:防止产生多个单例对象 26 | if (instance == null) { 27 | instance = new LazySingleton(); 28 | } 29 | } 30 | } 31 | return instance; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/template_method_pattern/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Java设计模式之Template Method模式 3 | date: 2019-09-04 13:31:23 4 | tags: [Java,design and pattern] 5 | --- 6 | 7 | ## 学习笔记 : Java设计模式之Template Method模式 8 | 9 | ### 概述 10 | *模板设计模式 : 定义一个操作中算法的框架,而将这一些步骤延迟到子类中. 模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤,简单点说既在父类中定义处理流程的框架,在子类中实现具体的处理. ( Template Method Pattern : Define the skeleton of an algorithm in an operation,deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure )* 11 | 12 | * 其是一种基于继承的代码复用技术,它是一种行为型模式,当然也是最简单的行为设计模式 ~ 13 | 14 | 15 | ### 模板方法模式的实现分类 16 | *模板方法模式的实现可划分为 : 模板方法( 基本方法的集合 )和基本方法( 实现具体的逻辑步骤 )* 17 | 18 | #### 模板方法 19 | *模板方法是指定义在抽象类中,把基本操作方法组合在一起形成一个总算法或一个总行为的方法. 模板方法是一个具体方法,其逻辑的组成步骤在抽象类中可以是具体方法,也可以是抽象方法( 可将模板方法定义为 final 方法哟 )* 20 | 21 | #### 基本方法 22 | *基本方法是实现算法各个步骤的方法,是模板方法的组成部分. 其可划分为 :* 23 | * 抽象方法 : 一个抽象方法由抽象类声明,由其具体子类实现. 24 | * 具体方法 : 一个具体方法由是一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以进行直接继承 25 | * 钩子方法 : 一个钩子方法由一个抽象类或者具体类声明并实现,而其子类可能会加以扩展. 26 | 27 | 28 | ### 示例程序-简洁版 29 | *下面是一个使用模板方法模式的简单示例程序 : 通过自定义模板样式来打印不同包裹字符的效果~* 30 | 31 | 1. *AbstractDisplay抽象类 : 充当抽象类角色* 32 | ```java 33 | package pers.huangyuhui.template_method.template_method1; 34 | 35 | /** 36 | * @project: design-patterns 37 | * @description: 充当抽象类角色 38 | * @author: 黄宇辉 39 | * @date: 9/4/2019-10:46 AM 40 | * @version: 1.0 41 | * @website: https://yubuntu0109.github.io/ 42 | */ 43 | public abstract class AbstractDisplay { 44 | 45 | //基本方法-抽象方法 46 | public abstract void open(); 47 | 48 | //基本方法-抽象方法 49 | public abstract void print(); 50 | 51 | //基本方法-抽象方法 52 | public abstract void close(); 53 | 54 | //模板方法:为具体方法,其逻辑的组成步骤可以是具体方法或抽象方法.. 55 | public /*final*/ void disply() { 56 | open(); 57 | for (int i = 0; i < 5; i++) { 58 | print(); 59 | } 60 | close(); 61 | } 62 | 63 | //基本方法-具体方法 64 | //略······ 65 | 66 | //基本方法-钩子方法 67 | //略······ 68 | } 69 | ``` 70 | 71 | 2. *CustomDisplay1类 : 充当具体类角色* 72 | ```java 73 | package pers.huangyuhui.template_method.template_method1; 74 | 75 | /** 76 | * @project: design-patterns 77 | * @description: 充当具体类角色 78 | * @author: 黄宇辉 79 | * @date: 9/4/2019-10:44 AM 80 | * @version: 1.0 81 | * @website: https://yubuntu0109.github.io/ 82 | */ 83 | public class CustomDisplay1 extends AbstractDisplay { 84 | 85 | private String string; 86 | private int width; 87 | 88 | public CustomDisplay1(String string) { 89 | this.string = string; 90 | width = string.getBytes().length; 91 | } 92 | 93 | @Override 94 | public void open() { 95 | printLine(); 96 | } 97 | 98 | @Override 99 | public void print() { 100 | System.out.println("█" + string + "█"); 101 | } 102 | 103 | @Override 104 | public void close() { 105 | printLine(); 106 | } 107 | 108 | private void printLine() { 109 | System.out.print("●"); 110 | for (int i = 0; i < width; i++) { 111 | System.out.print("■"); 112 | } 113 | System.out.println("●"); 114 | } 115 | 116 | } 117 | ``` 118 | 119 | 3. *CustomDisplay2类 : 充当具体类角色* 120 | ```java 121 | package pers.huangyuhui.template_method.template_method1; 122 | 123 | /** 124 | * @project: design-patterns 125 | * @description: 充当具体类角色 126 | * @author: 黄宇辉 127 | * @date: 9/4/2019-11:03 AM 128 | * @version: 1.0 129 | * @website: https://yubuntu0109.github.io/ 130 | */ 131 | public class CustomDisplay2 extends AbstractDisplay { 132 | 133 | private String string; 134 | private int width; 135 | 136 | public CustomDisplay2(String string) { 137 | this.string = string; 138 | this.width = string.getBytes().length; 139 | } 140 | 141 | @Override 142 | public void open() { 143 | printLine(); 144 | } 145 | 146 | @Override 147 | public void print() { 148 | System.out.println("|" + string + "|"); 149 | } 150 | 151 | @Override 152 | public void close() { 153 | printLine(); 154 | } 155 | 156 | private void printLine() { 157 | System.out.print("+"); 158 | for (int i = 0; i < width; i++) { 159 | System.out.print("-"); 160 | } 161 | System.out.println("+"); 162 | } 163 | } 164 | ``` 165 | 166 | 4. *Main类 : 程序测试* 167 | ```java 168 | package pers.huangyuhui.template_method.template_method1; 169 | 170 | /** 171 | * @project: design-patterns 172 | * @description: 测试类 173 | * @author: 黄宇辉 174 | * @date: 9/4/2019-10:54 AM 175 | * @version: 1.0 176 | * @website: https://yubuntu0109.github.io/ 177 | */ 178 | public class Main { 179 | 180 | public static void main(String[] args) { 181 | AbstractDisplay abstractDisplay = new CustomDisplay1("Template Method Pattern"); 182 | AbstractDisplay abstractDisplay2 = new CustomDisplay2("Template Method Pattern"); 183 | abstractDisplay.disply(); 184 | abstractDisplay2.disply(); 185 | } 186 | 187 | } 188 | ``` 189 | 190 | 5. *程序运行结果如下所示 :* 191 | ``` 192 | ●■■■■■■■■■■■■■■■■■■■■■■■● 193 | █Template Method Pattern█ 194 | █Template Method Pattern█ 195 | █Template Method Pattern█ 196 | █Template Method Pattern█ 197 | █Template Method Pattern█ 198 | ●■■■■■■■■■■■■■■■■■■■■■■■● 199 | +-----------------------+ 200 | |Template Method Pattern| 201 | |Template Method Pattern| 202 | |Template Method Pattern| 203 | |Template Method Pattern| 204 | |Template Method Pattern|s 205 | +-----------------------+ 206 | ``` 207 | 208 | #### Template Method模式中登场的角色 209 | * `AbstractClass( 抽象类 )` : AbstractClass角色不仅负责实现模板方法,还负责声明在模板方法中所使用到的抽象方法,这些抽象方法由子类ConcreteClass角色负责实现. 210 | * `ConcreteClass( 具体类 )` : 该类负责实现AbstrctClass中定义的抽象方法,`这些实现的方法将会在AbstractClass角色的模板方法中别调用.` 211 | 212 | #### 示例程序的类图 213 | ![ ](https://raw.githubusercontent.com/YUbuntu0109/YUbuntu0109.github.io/HexoBackup/source/_posts/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BTemplate-Method-Pattern/Template-Method1-ClassDiagram.png) 214 | 215 | 216 | 217 | ### 示例程序-详细版 218 | *下面是一个使用方法模板模式的简单示例程序 : 该程序的功能( 模拟 )为支持多种数据源及图表的显示方式,但所有的图表实现操作都需基于XML格式的数据,因此可能需要对数据进行转换,如果从数据源中获取的数据已经是XML数据则无需进行转换,所以这里需要用到`钩子方法`哟* 219 | 220 | 1. *DataViewer抽象类 : 充当抽象类角色* 221 | ```java 222 | package pers.huangyuhui.template_method.template_method2; 223 | 224 | /** 225 | * @project: design-patterns 226 | * @description: 充当抽象类角色 227 | * @author: 黄宇辉 228 | * @date: 9/4/2019-12:59 PM 229 | * @version: 1.0 230 | * @website: https://yubuntu0109.github.io/ 231 | */ 232 | public abstract class DataViewer { 233 | 234 | //抽象方法:获取数据 235 | public abstract void getData(); 236 | 237 | //具体方法:转换数据 238 | private void convertData() { 239 | System.out.println("将数据转换为XML格式"); 240 | } 241 | 242 | //抽象方法:显示数据 243 | public abstract void displayData(); 244 | 245 | //钩子方法:判断是否为XML格式的数据 246 | public boolean isNotXMLData() { 247 | return true; 248 | } 249 | 250 | //模板方法 251 | public final void process() { 252 | getData(); 253 | //如果不是xml格式的数据,则需将其转换为xml格式的数据 254 | if (isNotXMLData()) { 255 | convertData(); 256 | } 257 | displayData(); 258 | } 259 | } 260 | ``` 261 | 262 | 2. *CustomDataViewer1类 : 充当具体类角色* 263 | ```java 264 | package pers.huangyuhui.template_method.template_method2; 265 | 266 | /** 267 | * @project: design-patterns 268 | * @description: 充当具体类角色 269 | * @author: 黄宇辉 270 | * @date: 9/4/2019-1:05 PM 271 | * @version: 1.0 272 | * @website: https://yubuntu0109.github.io/ 273 | */ 274 | public class CustomDataViewer1 extends DataViewer { 275 | 276 | @Override 277 | public void getData() { 278 | System.out.println("从XML文件中获取数据"); 279 | } 280 | 281 | @Override 282 | public void displayData() { 283 | System.out.println("以柱状图的方式显示数据"); 284 | } 285 | 286 | //覆盖父类的钩子方法 287 | @Override 288 | public boolean isNotXMLData() { 289 | //return super.isNotXMLData(); 290 | return false; 291 | } 292 | } 293 | ``` 294 | 295 | 3. *CustomDataViewer2类 : 充当具体类角色* 296 | ```java 297 | package pers.huangyuhui.template_method.template_method2; 298 | 299 | /** 300 | * @project: design-patterns 301 | * @description: 充当具体类角色 302 | * @author: 黄宇辉 303 | * @date: 9/4/2019-1:08 PM 304 | * @version: 1.0 305 | * @website: https://yubuntu0109.github.io/ 306 | */ 307 | public class CustomDataViewer2 extends DataViewer { 308 | 309 | @Override 310 | public void getData() { 311 | System.out.println("从XML文件中获取数据"); 312 | } 313 | 314 | @Override 315 | public void displayData() { 316 | System.out.println("以圆饼图的方式显示数据"); 317 | } 318 | 319 | } 320 | ``` 321 | 322 | 4. *Main类 : 程序测试* 323 | ```java 324 | package pers.huangyuhui.template_method.template_method2; 325 | 326 | /** 327 | * @project: design-patterns 328 | * @description: 测试类 329 | * @author: 黄宇辉 330 | * @date: 9/4/2019-1:10 PM 331 | * @version: 1.0 332 | * @website: https://yubuntu0109.github.io/ 333 | */ 334 | public class Main { 335 | public static void main(String[] args) { 336 | DataViewer dataViewer = new CustomDataViewer1(); 337 | DataViewer dataViewer2 = new CustomDataViewer2(); 338 | dataViewer.process(); 339 | System.out.println("--------------------"); 340 | dataViewer2.process(); 341 | } 342 | } 343 | ``` 344 | 345 | 5. *程序运行结果如下所示 :* 346 | ``` 347 | 从XML文件中获取数据 348 | 以柱状图的方式显示数据 349 | -------------------- 350 | 从XML文件中获取数据 351 | 将数据转换为XML格式 352 | 以圆饼图的方式显示数据 353 | ``` 354 | 355 | #### 示例程序的类图 356 | ![ ](https://raw.githubusercontent.com/YUbuntu0109/YUbuntu0109.github.io/HexoBackup/source/_posts/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BTemplate-Method-Pattern/Template-Method2-ClassDiagram.png) 357 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/template_method_pattern/template_method1/AbstractDisplay.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.template_method_pattern.template_method1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当抽象类角色 6 | * @author: 黄宇辉 7 | * @date: 9/4/2019-10:46 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class AbstractDisplay { 12 | 13 | //基本方法-抽象方法 14 | public abstract void open(); 15 | 16 | //基本方法-抽象方法 17 | public abstract void print(); 18 | 19 | //基本方法-抽象方法 20 | public abstract void close(); 21 | 22 | //模板方法:为具体方法,其逻辑的组成步骤可以是具体方法或抽象方法.. 23 | public /*final*/ void disply() { 24 | open(); 25 | for (int i = 0; i < 5; i++) { 26 | print(); 27 | } 28 | close(); 29 | } 30 | 31 | //基本方法-具体方法 32 | //略······ 33 | 34 | //基本方法-钩子方法 35 | //略······ 36 | } 37 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/template_method_pattern/template_method1/CustomDisplay1.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.template_method_pattern.template_method1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当具体类角色 6 | * @author: 黄宇辉 7 | * @date: 9/4/2019-10:44 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class CustomDisplay1 extends AbstractDisplay { 12 | 13 | private String string; 14 | private int width; 15 | 16 | public CustomDisplay1(String string) { 17 | this.string = string; 18 | width = string.getBytes().length; 19 | } 20 | 21 | @Override 22 | public void open() { 23 | printLine(); 24 | } 25 | 26 | @Override 27 | public void print() { 28 | System.out.println("█" + string + "█"); 29 | } 30 | 31 | @Override 32 | public void close() { 33 | printLine(); 34 | } 35 | 36 | private void printLine() { 37 | System.out.print("●"); 38 | for (int i = 0; i < width; i++) { 39 | System.out.print("■"); 40 | } 41 | System.out.println("●"); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/template_method_pattern/template_method1/CustomDisplay2.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.template_method_pattern.template_method1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当具体类角色 6 | * @author: 黄宇辉 7 | * @date: 9/4/2019-11:03 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class CustomDisplay2 extends AbstractDisplay { 12 | 13 | private String string; 14 | private int width; 15 | 16 | public CustomDisplay2(String string) { 17 | this.string = string; 18 | this.width = string.getBytes().length; 19 | } 20 | 21 | @Override 22 | public void open() { 23 | printLine(); 24 | } 25 | 26 | @Override 27 | public void print() { 28 | System.out.println("|" + string + "|"); 29 | } 30 | 31 | @Override 32 | public void close() { 33 | printLine(); 34 | } 35 | 36 | private void printLine() { 37 | System.out.print("+"); 38 | for (int i = 0; i < width; i++) { 39 | System.out.print("-"); 40 | } 41 | System.out.println("+"); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/template_method_pattern/template_method1/Main.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.template_method_pattern.template_method1; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 测试类 6 | * @author: 黄宇辉 7 | * @date: 9/4/2019-10:54 AM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Main { 12 | 13 | public static void main(String[] args) { 14 | AbstractDisplay abstractDisplay = new CustomDisplay1("Template Method Pattern"); 15 | AbstractDisplay abstractDisplay2 = new CustomDisplay2("Template Method Pattern"); 16 | abstractDisplay.disply(); 17 | abstractDisplay2.disply(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/template_method_pattern/template_method2/CustomDataViewer1.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.template_method_pattern.template_method2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当具体类 6 | * @author: 黄宇辉 7 | * @date: 9/4/2019-1:05 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class CustomDataViewer1 extends DataViewer { 12 | 13 | @Override 14 | public void getData() { 15 | System.out.println("从XML文件中获取数据"); 16 | } 17 | 18 | @Override 19 | public void displayData() { 20 | System.out.println("以柱状图的方式显示数据"); 21 | } 22 | 23 | //覆盖父类的钩子方法 24 | @Override 25 | public boolean isNotXMLData() { 26 | //return super.isNotXMLData(); 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/template_method_pattern/template_method2/CustomDataViewer2.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.template_method_pattern.template_method2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当具体类 6 | * @author: 黄宇辉 7 | * @date: 9/4/2019-1:08 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class CustomDataViewer2 extends DataViewer { 12 | 13 | @Override 14 | public void getData() { 15 | System.out.println("从XML文件中获取数据"); 16 | } 17 | 18 | @Override 19 | public void displayData() { 20 | System.out.println("以圆饼图的方式显示数据"); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/template_method_pattern/template_method2/DataViewer.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.template_method_pattern.template_method2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 充当抽象类角色 6 | * @author: 黄宇辉 7 | * @date: 9/4/2019-12:59 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public abstract class DataViewer { 12 | 13 | //抽象方法:获取数据 14 | public abstract void getData(); 15 | 16 | //具体方法:转换数据 17 | private void convertData() { 18 | System.out.println("将数据转换为XML格式"); 19 | } 20 | 21 | //抽象方法:显示数据 22 | public abstract void displayData(); 23 | 24 | //钩子方法:判断是否为XML格式的数据 25 | public boolean isNotXMLData() { 26 | return true; 27 | } 28 | 29 | //模板方法 30 | public final void process() { 31 | getData(); 32 | //如果不是xml格式的数据,则需将其转换为xml格式的数据 33 | if (isNotXMLData()) { 34 | convertData(); 35 | } 36 | displayData(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /design-patterns/src/main/java/pers/huangyuhui/template_method_pattern/template_method2/Main.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui.template_method_pattern.template_method2; 2 | 3 | /** 4 | * @project: design-patterns 5 | * @description: 测试类 6 | * @author: 黄宇辉 7 | * @date: 9/4/2019-1:10 PM 8 | * @version: 1.0 9 | * @website: https://yubuntu0109.github.io/ 10 | */ 11 | public class Main { 12 | public static void main(String[] args) { 13 | DataViewer dataViewer = new CustomDataViewer1(); 14 | DataViewer dataViewer2 = new CustomDataViewer2(); 15 | dataViewer.process(); 16 | System.out.println("--------------------"); 17 | dataViewer2.process(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /design-patterns/src/test/java/pers/huangyuhui/AppTest.java: -------------------------------------------------------------------------------- 1 | package pers.huangyuhui; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest { 11 | /** 12 | * Rigorous Test1 :-) 13 | */ 14 | @Test 15 | public void shouldAnswerWithTrue() { 16 | assertTrue(true); 17 | } 18 | } 19 | --------------------------------------------------------------------------------