CREATE DATABASE  IF NOT EXISTS `vueblog` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
USE `vueblog`;
-- MySQL dump 10.13  Distrib 8.0.11, for Win64 (x86_64)
--
-- Host: localhost    Database: vueblog
-- ------------------------------------------------------
-- Server version	8.0.11

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
 SET NAMES utf8 ;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `m_blog`
--

DROP TABLE IF EXISTS `m_blog`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
 SET character_set_client = utf8mb4 ;
CREATE TABLE `m_blog` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL,
  `title` varchar(255) NOT NULL,
  `description` varchar(255) NOT NULL,
  `content` longtext,
  `created` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
  `status` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `m_blog`
--

LOCK TABLES `m_blog` WRITE;
/*!40000 ALTER TABLE `m_blog` DISABLE KEYS */;
INSERT INTO `m_blog` VALUES (15,1,'Java设计模式之Abstract Factory Pattern','工厂方法模式通过引入工厂等级结构解决了简单工厂模式中工厂类职责太重的问题，但由于工厂方法模式中每个具体工厂只有一个或一组重载的工厂方法，既只能生产一种产品，可能会导致系统中存在大量的工厂类，势必会增加系统的开销...','> *本文摘自我的博客 : ishacker.net*\n\n## 学习笔记 : Java设计模式之Abstract Factory Pattern\n\n### 概述\n*`工厂方法模式`通过引入工厂等级结构解决了`简单工厂模式`中工厂类职责太重的问题,但由于工厂方法模式中每个具体工厂只有一个或一组重载的工厂方法,既只能生产一种产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销. 抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形式. 抽象工厂模式与工厂方法模式的最大区别在于 : 工厂方法模式针对的是一个`产品等级结构`,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建. 当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更加简单,更有效率~ 抽象工厂模式的定义为 : 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类( Abstract Factory Pattern : Provide an interface for creating families of related or dependent objects without sprcifying their concrete classes. )*\n\n\n### 抽象工厂模式中的角色\n1. *`AbstractFactory( 抽象工厂 )` : 它声明了一组用于创建一族产品的方法,每一个方法对应一种产品.*\n2. *`ConcreteFactory( 具体工厂 )` : 它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个`产品族`,每一个产品都位于某个产品等级结构中*\n3. *`AbstractProduct( 抽象产品 )` : 它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法.*\n4. *`ConcreteProduct( 具体产品 )` : 它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法.*\n\n\n### 示例程序\n*下面是一个使用了抽象工厂模式的简单示例程序,其程序功能( 模拟 )描述为 : 开发一套基于 Java 桌面软件的界面皮肤库,用户可以自由切换界面皮肤,例如有 Spring 与 Summer 风格等皮肤~*\n\n1. *Button接口 : 接口按钮, 充当抽象产品*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: 接口按钮, 充当抽象产品\n * @author: 黄宇辉\n * @date: 9/7/2019-5:18 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic interface Button {\n    void display();\n}\n```\n\n2. *SpringButton类 : Spring风格皮肤的按钮类, 充当具体产品*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: Spring风格皮肤的按钮类, 充当具体产品\n * @author: 黄宇辉\n * @date: 9/7/2019-5:19 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class SpringButton implements Button {\n    @Override\n    public void display() {\n        System.out.println(\"spring theme———>this is button\");\n    }\n}\n```\n\n3. *SummerButton类 : Summer风格皮肤的按钮类, 充当具体产品*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: Summer风格皮肤的按钮类, 充当具体产品\n * @author: 黄宇辉\n * @date: 9/7/2019-5:20 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class SummerButton implements Button {\n\n    @Override\n    public void display() {\n        System.out.println(\"Summer theme———>button\");\n    }\n}\n```\n\n4. *TextField接口 : 文本框接口, 充当抽象产品*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: 文本框接口, 充当抽象产品\n * @author: 黄宇辉\n * @date: 9/7/2019-5:22 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic interface TextField {\n    void display();\n}\n```\n\n5. *SpringTextField类 : Spring风格皮肤的文本框类, 充当具体产品*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: Spring风格皮肤的文本框类, 充当具体产品\n * @author: 黄宇辉\n * @date: 9/7/2019-5:22 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class SpringTextField implements TextField {\n\n    @Override\n    public void display() {\n        System.out.println(\"Spring theme———>this is text field\");\n    }\n}\n```\n\n6. *SummerTextField类 : Summer风格皮肤的文本框类, 充当具体产品*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: Summer风格皮肤的文本框类, 充当具体产品\n * @author: 黄宇辉\n * @date: 9/7/2019-5:23 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class SummerTextField implements TextField {\n\n    @Override\n    public void display() {\n        System.out.println(\"Summer theme———>this is text field\");\n    }\n}\n```\n\n7. *ComboBob类 : 组合框接口, 充当抽象产品*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: 组合框接口, 充当抽象产品\n * @author: 黄宇辉\n * @date: 9/7/2019-5:24 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic interface ComboBox {\n    void display();\n}\n```\n\n8. *SpringComboBox类 : Spring风格皮肤的组合框类, 充当具体产品*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: Spring风格皮肤的组合框类, 充当具体产品\n * @author: 黄宇辉\n * @date: 9/7/2019-5:25 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class SpringComboBox implements ComboBox {\n    @Override\n    public void display() {\n        System.out.println(\"Spring theme———>this is comboxBox\");\n    }\n}\n```\n\n9. *SummerComboBox类 : Summer风格皮肤的组合框类, 充当具体产品*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: Summer风格皮肤的组合框类, 充当具体产品\n * @author: 黄宇辉\n * @date: 9/7/2019-5:25 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class SummerComboBox implements ComboBox {\n    @Override\n    public void display() {\n        System.out.println(\"Summer theme———>this is comboBox\");\n    }\n}\n```\n\n10. *SkinFactory接口 : 界面皮肤工厂接口, 充当抽象工厂*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: 界面皮肤工厂接口, 充当抽象工厂\n * @author: 黄宇辉\n * @date: 9/7/2019-5:26 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic interface SkinFactory {\n    Button createButton();\n\n    TextField createTextField();\n\n    ComboBox createComboBox();\n}\n```\n\n11. *SpringSkinFactory类 : Spring皮肤风格的工厂类, 充当具体工厂*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: Spring皮肤风格的工厂类, 充当具体工厂\n * @author: 黄宇辉\n * @date: 9/7/2019-5:29 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class SpringSkinFactory implements SkinFactory {\n    @Override\n    public Button createButton() {\n        return new SpringButton();\n    }\n\n    @Override\n    public TextField createTextField() {\n        return new SpringTextField();\n    }\n\n    @Override\n    public ComboBox createComboBox() {\n        return new SpringComboBox();\n    }\n}\n```\n\n12. *SummerSkinFactory类 : Summer风格皮肤的工厂类, 充当具体工厂*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: Summer风格皮肤的工厂类, 充当具体工厂\n * @author: 黄宇辉\n * @date: 9/7/2019-5:33 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class SummerSkinFactory implements SkinFactory {\n    @Override\n    public Button createButton() {\n        return new SummerButton();\n    }\n\n    @Override\n    public TextField createTextField() {\n        return new SummerTextField();\n    }\n\n    @Override\n    public ComboBox createComboBox() {\n        return new SummerComboBox();\n    }\n}\n```\n\n13. *Client类 : 客户端测试类*\n```java\npackage pers.huangyuhui.abstract_factory_pattern.abstract_factory;\n\n/**\n * @project: design-patterns\n * @description: 客户端测试类\n * @author: 黄宇辉\n * @date: 9/7/2019-5:30 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Client {\n\n    public static void main(String[] args) {\n        SkinFactory skinFactory = new SpringSkinFactory();\n        skinFactory.createButton().display();\n        skinFactory.createTextField().display();\n        skinFactory.createComboBox().display();\n\n        System.out.println(\"———————————————————\");\n\n        SkinFactory skinFactory2 = new SummerSkinFactory();\n        skinFactory2.createButton().display();\n        skinFactory2.createTextField().display();\n        skinFactory2.createComboBox().display();\n\n    }\n}\n```\n\n14. *程序运行结果如下所示 :*\n```\nspring theme———>this is button\nSpring theme———>this is text field\nSpring theme———>this is comboxBox\n———————————————————\nSummer theme———>button\nSummer theme———>this is text field\nSummer theme———>this is comboBox\n```\n\n#### 示例程序的类图\n![](https://github.com/YUbuntu0109/YUbuntu0109.github.io/blob/HexoBackup/public/2019/09/07/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BAbstract-Factory-Pattern/Abstract-Factory-Pattern-ClassDiagram.png?raw=true)\n','2020-06-19 17:18:51',0),(16,1,'Java设计模式之Adapter模式','适配器模式也称为Wrapper模式，其作用是将一个类的接口转换为客户希望的另一个接口，让那些接口不兼容的的类可以在一起工作...','> *本文章摘自我的博客 : ishacker.net*\n\n## 学习笔记 : Java设计模式之Adapter模式\n\n### 概述\n*适配器模式 : 将一个类的接口转换为客户希望的另一个接口. 适配器模式让那些接口不兼容的的类可以在一起工作. Adapter模式也称为Wrapper模式( Adapter Pattern : Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn\'t otherwise because of incompatible interfaces )*\n\n### 示例程序(使用继承的适配器)\n*首先让我们来看一段使用继承的适配器的示例程序,该简单程序的作用是将一段输入的字符串显示为`(hello)`或`*hello*`.*\n\n1. *Banner类 : 充当Adaptee角色*\n```java\npackage pers.huangyuhui.adapter.adapter1;\n\n/**\n * @project: design-patterns\n * @description: 充当Adaptee角色\n * @author: 黄宇辉\n * @date: 9/3/2019-4:12 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Banner {\n    private String string;\n\n    public Banner(String string) {\n        this.string = string;\n    }\n\n    public void showWithParen() {\n        System.out.println(\"(\" + string + \")\");\n    }\n\n    public void showWithAster() {\n        System.out.println(\"*\" + string + \"*\");\n    }\n\n}\n```\n\n2. *Print接口 : 充当Target角色*\n```java\npackage pers.huangyuhui.adapter.adapter1;\n\n/**\n * @project: design-patterns\n * @description: 充当Target角色\n * @author: 黄宇辉\n * @date: 9/3/2019-4:15 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic interface Print {\n    void printWeak();\n\n    void printStrong();\n}\n```\n\n3. *PrintBanner类 : 充当Adapter角色*\n```java\npackage pers.huangyuhui.adapter.adapter1;\n\n/**\n * @project: design-patterns\n * @description: 充当Adapter角色\n * @author: 黄宇辉\n * @date: 9/3/2019-4:16 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class PrintBanner extends Banner implements Print {\n\n    public PrintBanner(String string) {\n        super(string);\n    }\n\n    @Override\n    public void printWeak() {\n        super.showWithParen();\n    }\n\n    @Override\n    public void printStrong() {\n        super.showWithAster();\n    }\n}\n```\n\n4. *Main类 : 充当Client角色*\n```java\npackage pers.huangyuhui.adapter.adapter1;\n\n/**\n * @project: design-patterns\n * @description: 充当Client角色\n * @author: 黄宇辉\n * @date: 9/3/2019-4:17 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Main {\n    public static void main(String[] args) {\n        Print print = new PrintBanner(\"Hello\");\n        print.printWeak();\n        print.printStrong();\n    }\n}\n```\n\n5. *程序运行结果如下所示 :*\n```\n(Hello)\n*Hello*\n```\n\n#### 示例程序的类图\n![ ](Java设计模式之Adapter-Pattern/Adapter1-ClassDiagram.png)\n\n#### Adapter模式中登场的角色\n* `Target( 目标抽象类 )` : 目标抽象类定义客户所需的接口,可以是一个抽象类或接口,也可以是具体类. 在类适配器中,由于Java语言不支持多重继承,所以它只能是接口.\n* `Client( 请求者 ) ` : 该角色负责使用 Target 角色所定义的方法进行具体的处理\n* `Adapter( 适配器类 )` : 它可以调用另一个接口,作为一个转换器,对 Adaptee 和 Target 进行适配. 适配器 Adapter 是适配器模式的核心,`在类适配器中,它通过实现 Target 接口并继承 Adaptee 来使两者产生联系,在对象适配器中,它通过继承Target并关联一个Adaptee对象来使两者产生联系`.\n* `Adaptee( 适配者类 )` : 适配者既被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,其包含着客户希望使用的业务方法\n\n\n\n### 示例程序(使用委托的适配器)\n*在 Java 语言中,委托是指将某个方法中的实际处理交给其它实例的方法*\n\n1. *Banner类 : 充当Adaptee角色(同上个示例程序)*\n```java\npackage pers.huangyuhui.adapter.adapter2;\n\n/**\n * @project: design-patterns\n * @description: 充当Adaptee角色\n * @author: 黄宇辉\n * @date: 9/3/2019-4:23 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Banner {\n    private String string;\n\n    public Banner(String string) {\n        this.string = string;\n    }\n\n    public void showWithParen() {\n        System.out.println(\"(\" + string + \")\");\n    }\n\n    public void showWithAster() {\n        System.out.println(\"*\" + string + \"*\");\n    }\n}\n```\n\n2. *Print类 : 充当Target角色*\n```java\npackage pers.huangyuhui.adapter.adapter2;\n\n/**\n * @project: design-patterns\n * @description: 充当Target角色\n * @author: 黄宇辉\n * @date: 9/3/2019-4:21 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic abstract class Print {\n    public abstract void printWeak();\n\n    public abstract void pintStrong();\n}\n```\n\n3. *PrintBanner类 : 充当Adapter角色*\n```java\npackage pers.huangyuhui.adapter.adapter2;\n\n/**\n * @project: design-patterns\n * @description: 充当Adapter角色\n * @author: 黄宇辉\n * @date: 9/3/2019-4:22 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class PrintBanner extends Print {\n\n    private Banner banner;\n\n    public PrintBanner(String string) {\n        this.banner = new Banner(string);\n    }\n\n    @Override\n    public void printWeak() {\n        banner.showWithParen();\n    }\n\n    @Override\n    public void pintStrong() {\n        banner.showWithAster();\n    }\n}\n```\n\n4. *Main类 : 充当Client角色(同上个示例程序)*\n```java\npackage pers.huangyuhui.adapter.adapter2;\n\n/**\n * @project: design-patterns\n * @description: 充当Client角色\n * @author: 黄宇辉\n * @date: 9/3/2019-4:26 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Main {\n\n    public static void main(String[] args) {\n        Print print = new PrintBanner(\"Adapter Pattern\");\n        print.printWeak();\n        print.pintStrong();\n\n    }\n}\n```\n\n#### 示例程序的类图\n![ ](Java设计模式之Adapter-Pattern/Adapter2-ClassDiagram.png)\n\n\n\n### 扩-缺省适配模式\n*缺省设计模式是适配器模式的一种变体,其应用也比较广泛,其定义为 : `缺省设计模式( Default Adapter Pattern )` : 当不需要实现一个接口提供的所有方法时,可先设计一个抽象类来实现接口,并为接口中的每个方法提供一个默认实现( 空方法 ),那么该抽象类的子类就可以选择性地覆盖父类的某些实现方法来实现需求,它适用于不想使用一个接口的所有方法的情况,又称为单接口适配器模式*\n\n#### 示例程序\n*下面是一个缺省适配模式的示例程序,创建一个 JFrame 窗体,并通过继承 MyWindowAdapter 适配器类,选择性地自定义监听事件.*\n\n1. *MyWindowAdapter接口 : 充当缺省适配器类. WindowListener, MouseListener接口 : 充当适配者接口*\n```java\npackage pers.huangyuhui.adapter.adapter3;\n\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport java.awt.event.WindowEvent;\nimport java.awt.event.WindowListener;\n\n/**\n * @project: design-patterns\n * @description: 充当缺省适配器类\n * @author: 黄宇辉\n * @date: 9/3/2019-4:35 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic abstract class MyWindowAdapter implements WindowListener, MouseListener {\n\n\n    @Override\n    public void mouseClicked(MouseEvent e) {\n\n    }\n\n    @Override\n    public void mousePressed(MouseEvent e) {\n\n    }\n\n    @Override\n    public void mouseReleased(MouseEvent e) {\n\n    }\n\n    @Override\n    public void mouseEntered(MouseEvent e) {\n\n    }\n\n    @Override\n    public void mouseExited(MouseEvent e) {\n\n    }\n\n    @Override\n    public void windowOpened(WindowEvent e) {\n\n    }\n\n    @Override\n    public void windowClosing(WindowEvent e) {\n\n    }\n\n    @Override\n    public void windowClosed(WindowEvent e) {\n\n    }\n\n    @Override\n    public void windowIconified(WindowEvent e) {\n\n    }\n\n    @Override\n    public void windowDeiconified(WindowEvent e) {\n\n    }\n\n    @Override\n    public void windowActivated(WindowEvent e) {\n\n    }\n\n    @Override\n    public void windowDeactivated(WindowEvent e) {\n\n    }\n}\n```\n\n2. *MyEventService类 : 充当具体业务类*\n```java\npackage pers.huangyuhui.adapter.adapter3;\n\nimport java.awt.event.MouseEvent;\nimport java.awt.event.WindowEvent;\n\n/**\n * @project: design-patterns\n * @description: 充当具体业务类\n * @author: 黄宇辉\n * @date: 9/3/2019-4:40 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class MyEventService extends MyWindowAdapter {\n\n    @Override\n    public void windowOpened(WindowEvent e) {\n        System.out.println(\"windowOpened : Hello\");\n    }\n\n    @Override\n    public void windowClosing(WindowEvent e) {\n        System.out.println(\"windowClosing : Bye\");\n    }\n\n    @Override\n    public void mouseClicked(MouseEvent e) {\n        System.out.println(\"mouseClicked : Clicked\");\n    }\n\n}\n```\n\n3. *MyContoller类 : 测试类,创建JFrame窗体并为其绑定监听事件*\n```java\npackage pers.huangyuhui.adapter.adapter3;\n\nimport javax.swing.*;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.WindowAdapter;\nimport java.awt.event.WindowEvent;\n\n/**\n * @project: design-patterns\n * @description: 创建JFrame窗体并为其绑定监听事件\n * @author: 黄宇辉\n * @date: 9/3/2019-4:47 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class MyController {\n    public static void main(String[] args) {\n        MyEventService myEventService = new MyEventService();\n        JFrame j = new JFrame(\"title\");\n        j.setSize(500, 300);\n        j.setVisible(true);\n        j.setLocationRelativeTo(null);\n        j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n\n        //绑定事件\n        j.addWindowListener(new WindowAdapter() {\n            @Override\n            public void windowOpened(WindowEvent e) {\n                myEventService.windowOpened(e);\n            }\n\n            @Override\n            public void windowClosing(WindowEvent e) {\n                myEventService.windowClosing(e);\n            }\n        });\n        j.addMouseListener(new MouseAdapter() {\n            @Override\n            public void mouseClicked(MouseEvent e) {\n                myEventService.mouseClicked(e);\n            }\n        });\n\n    }\n}\n```\n\n#### 示例程序的类图\n![ ](Java设计模式之Adapter-Pattern/Adapter3-ClassDiagram.png)\n\n#### Adapter模式中登场的角色\n* `ServiceInterface( 适配器接口 )` : 该接口中声明了大量的方法.\n* `AbstractServiceClass( 缺省适配器类 )` : 为缺省适配器模式的核心类,通常将其定义为抽象类,使用空方法的形式实现了在 ServiceInterface 接口中声明的方法.\n* `ConcreteServiceClass( 具体业务类 )` : 直接继承 AbstractServiceClass 适配器类,根据需要有选择性地覆盖在适配器中定的方法.\n','2020-06-19 17:27:13',0),(17,1,'Java设计模式之Builder Pattern','建造者模式是一种对象创建型模式，它将客户端与包含多个部件的复杂对象的创建过程分离，客户端无需知道复杂对象的内部组成部分与装配方式，只需要知道所需建造者的类型即可...','> *本文章摘自我的博客 : ishacker.net*\n\n## 学习笔记 : Java设计模式之Builder Pattern\n\n### 概述\n*缔造者设计模式 : 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示( Builder Pattern : Separate the construction of complex object from its representation so that the same construction process can create different representations )*\n\n* 扩 : 建造者模式是一种对象创建型模式,它将客户端与包含多个部件的复杂对象的创建过程分离,客户端无需知道复杂对象的内部组成部分与装配方式,只需要知道所需建造者的类型即可.\n\n\n### 建造者设计模式中的角色\n1. *`Builder( 抽象建造者 )` : 它为创建一个产品的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是 buildPartX(),其用于创建复杂对象的各个部件. 另一类方法是 getResult(),其用于返回复杂对象. Builder 即可是抽象类,也可以是接口.*\n2. *`ConcreteBuilder( 具体建造者 )` : 它实现了 Builder 接口,实现了各个部件的具体构造和装配方法,定义并明确所创建的复杂对象,还可以提供一个用于返回创建好的复杂产品的方法( 该方法可以由抽象构建者实现 ).*\n3. *`Product( 产品 )` : 它是被创建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程.*\n4. *`Director( 指挥者 )` : 指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥者与抽象构建者之间存在关联关系,可以在其 construct() 建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造.*\n\n\n### 示例程序\n*下面是一个使用了建造者设计模式的简单示例程序,其概述为 : 无论是何种游戏角色,都需要逐步创建其组成部分,再将各组成部分配装成一个完整的游戏角色.*\n\n1. *Actor类 : 游戏角色类, 充当复杂产品对象*\n```java\npackage pers.huangyuhui.builder_pattern.builder_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 游戏角色类, 充当复杂产品对象\n * @author: 黄宇辉\n * @date: 9/19/2019-1:30 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Actor {\n    private String type; //角色类型\n    private String sex; //性别\n    private String face; //脸型\n    private String costume; //服装\n\n    public String getType() {\n        return type;\n    }\n\n    public void setType(String type) {\n        this.type = type;\n    }\n\n    public String getSex() {\n        return sex;\n    }\n\n    public void setSex(String sex) {\n        this.sex = sex;\n    }\n\n    public String getFace() {\n        return face;\n    }\n\n    public void setFace(String face) {\n        this.face = face;\n    }\n\n    public String getCostume() {\n        return costume;\n    }\n\n    public void setCostume(String costume) {\n        this.costume = costume;\n    }\n\n    @Override\n    public String toString() {\n        return \"Actor{\" +\n                \"type=\'\" + type + \'\\\'\' +\n                \", sex=\'\" + sex + \'\\\'\' +\n                \", face=\'\" + face + \'\\\'\' +\n                \", costume=\'\" + costume + \'\\\'\' +\n                \'}\';\n    }\n}\n```\n\n2. *ActorBuilder抽象类 : 游戏角色建造者, 充当抽象建造者*\n```java\npackage pers.huangyuhui.builder_pattern.builder_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 游戏角色建造者, 充当抽象建造者\n * @author: 黄宇辉\n * @date: 9/19/2019-1:39 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic abstract class ActorBuilder {\n    protected Actor actor = new Actor();\n\n    public abstract void buildType();\n\n    public abstract void buildSex();\n\n    public abstract void buildFace();\n\n    public abstract void buildCostume();\n\n    //工厂方法,返回一个完整的游戏角色对象\n    public Actor createActor() {\n        return actor;\n    }\n}\n```\n\n3. *HeroBuilder类 : 英雄角色建造者, 充当具体建造者*\n```java\npackage pers.huangyuhui.builder_pattern.builder_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 英雄角色建造者, 充当具体建造者\n * @author: 黄宇辉\n * @date: 9/19/2019-1:42 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class HeroBuilder extends ActorBuilder {\n    @Override\n    public void buildType() {\n        actor.setType(\"英雄\");\n    }\n\n    @Override\n    public void buildSex() {\n        actor.setSex(\"男\");\n    }\n\n    @Override\n    public void buildFace() {\n        actor.setFace(\"英俊\");\n    }\n\n    @Override\n    public void buildCostume() {\n        actor.setCostume(\"盔甲\");\n    }\n}\n```\n\n4. *AngelBuilder类 : 天使角色建造者, 充当具体建造类*\n```java\npackage pers.huangyuhui.builder_pattern.builder_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 天使角色建造者, 充当具体建造类\n * @author: 黄宇辉\n * @date: 9/19/2019-1:44 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class AngelBuilder extends ActorBuilder {\n\n    @Override\n    public void buildType() {\n        actor.setType(\"天使\");\n    }\n\n    @Override\n    public void buildSex() {\n        actor.setSex(\"女\");\n    }\n\n    @Override\n    public void buildFace() {\n        actor.setFace(\"漂亮\");\n    }\n\n    @Override\n    public void buildCostume() {\n        actor.setCostume(\"裙子\");\n    }\n}\n```\n\n5. *ActorController类 : 角色控制器, 充当指挥者*\n```java\npackage pers.huangyuhui.builder_pattern.builder_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 角色控制器, 充当指挥者\n * @author: 黄宇辉\n * @date: 9/19/2019-1:46 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class ActorController {\n\n    //逐步构建复杂产品对象\n    public Actor construct(ActorBuilder actorBuilder) {\n        Actor actor;\n        actorBuilder.buildType();\n        actorBuilder.buildSex();\n        actorBuilder.buildFace();\n        actorBuilder.buildCostume();\n        actor = actorBuilder.createActor();\n        return actor;\n    }\n}\n```\n\n6. *Client类 : 客户端测试类*\n```java\npackage pers.huangyuhui.builder_pattern.builder_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 客户端测试类\n * @author: 黄宇辉\n * @date: 9/19/2019-1:49 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Client {\n\n    public static void main(String[] args) {\n        ActorController actorController = new ActorController();\n\n        ActorBuilder zero = new HeroBuilder();\n        Actor actor_zero = actorController.construct(zero);\n        System.out.println(actor_zero);\n\n        System.out.println(\"------------------------------\");\n\n        ActorBuilder angel = new AngelBuilder();\n        Actor actor_angel = actorController.construct(angel);\n        System.out.println(actor_angel);\n    }\n}\n```\n\n7. *示例程序的运行结果如下所示 :*\n```\nActor{type=\'英雄\', sex=\'男\', face=\'英俊\', costume=\'盔甲\'}\n------------------------------\nActor{type=\'天使\', sex=\'女\', face=\'漂亮\', costume=\'裙子\'}\n```\n\n#### 示例程序的类图\n![](Java设计模式之Builder-Pattern/Builder-Pattern-ClassDiagram1.png)\n\n\n\n### 示例程序-简化版\n*为了简化系统结构,可以将 Director 和抽象建造者 Builder 进行合并,在 Builder 中提供逐步构建复杂产品对象的 construct() 方法. 由于 Builder 类通常是抽象类,因此可以将 construct() 方法定义为静态方法,以便客户端能够直接调用. 除此之外还有一种更简单的处理方法,既将 construct() 方法中的参数去掉,直接在construct()方法中调用 buildPartX() 方法.( 以下示例程序是基于上述示例程序进行简化的 )*\n\n1. *Actor类 : 游戏角色类, 充当复杂产品对象*\n```java\npackage pers.huangyuhui.builder_pattern.builder_pattern_2;\n\n/**\n * @project: design-patterns\n * @description: 游戏角色类, 充当复杂产品对象\n * @author: 黄宇辉\n * @date: 9/19/2019-1:30 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Actor {\n    private String type; //角色类型\n    private String sex; //性别\n    private String face; //脸型\n    private String costume; //服装\n\n    public String getType() {\n        return type;\n    }\n\n    public void setType(String type) {\n        this.type = type;\n    }\n\n    public String getSex() {\n        return sex;\n    }\n\n    public void setSex(String sex) {\n        this.sex = sex;\n    }\n\n    public String getFace() {\n        return face;\n    }\n\n    public void setFace(String face) {\n        this.face = face;\n    }\n\n    public String getCostume() {\n        return costume;\n    }\n\n    public void setCostume(String costume) {\n        this.costume = costume;\n    }\n\n    @Override\n    public String toString() {\n        return \"Actor{\" +\n                \"type=\'\" + type + \'\\\'\' +\n                \", sex=\'\" + sex + \'\\\'\' +\n                \", face=\'\" + face + \'\\\'\' +\n                \", costume=\'\" + costume + \'\\\'\' +\n                \'}\';\n    }\n}\n```\n\n2. *ActorBuilder抽象类 : 游戏角色建造者, 充当抽象建造者(省略Director并简化construct方法)*\n```java\npackage pers.huangyuhui.builder_pattern.builder_pattern_2;\n\n/**\n * @project: design-patterns\n * @description: 游戏角色建造者, 充当抽象建造者(省略Director并简化construct方法)\n * @author: 黄宇辉\n * @date: 9/19/2019-1:39 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic abstract class ActorBuilder {\n    protected Actor actor = new Actor();\n\n    public abstract void buildType();\n\n    public abstract void buildSex();\n\n    public abstract void buildFace();\n\n    public abstract void buildCostume();\n\n    //工厂方法,返回一个完整的游戏角色对象\n    //public Actor createActor() {\n    //    return actor;\n    //}\n\n    //逐步构建复杂产品对象\n    public Actor construct() {\n        this.buildType();\n        this.buildSex();\n        this.buildFace();\n        this.buildCostume();\n        return actor;\n    }\n}\n```\n\n3. *HeroBuilder类 : 英雄角色建造者, 充当具体建造者*\n```java\npackage pers.huangyuhui.builder_pattern.builder_pattern_2;\n\n/**\n * @project: design-patterns\n * @description: 英雄角色建造者, 充当具体建造者\n * @author: 黄宇辉\n * @date: 9/19/2019-1:42 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class HeroBuilder extends ActorBuilder {\n    @Override\n    public void buildType() {\n        actor.setType(\"英雄\");\n    }\n\n    @Override\n    public void buildSex() {\n        actor.setSex(\"男\");\n    }\n\n    @Override\n    public void buildFace() {\n        actor.setFace(\"英俊\");\n    }\n\n    @Override\n    public void buildCostume() {\n        actor.setCostume(\"盔甲\");\n    }\n}\n```\n\n4. *AngelBuilder类 : 天使角色建造者, 充当具体建造类*\n```java\npackage pers.huangyuhui.builder_pattern.builder_pattern_2;\n\n/**\n * @project: design-patterns\n * @description: 天使角色建造者, 充当具体建造类\n * @author: 黄宇辉\n * @date: 9/19/2019-1:44 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class AngelBuilder extends ActorBuilder {\n\n    @Override\n    public void buildType() {\n        actor.setType(\"天使\");\n    }\n\n    @Override\n    public void buildSex() {\n        actor.setSex(\"女\");\n    }\n\n    @Override\n    public void buildFace() {\n        actor.setFace(\"漂亮\");\n    }\n\n    @Override\n    public void buildCostume() {\n        actor.setCostume(\"裙子\");\n    }\n}\n```\n\n5. *Client类 : 客户端测试类*\n```java\npackage pers.huangyuhui.builder_pattern.builder_pattern_2;\n\n/**\n * @project: design-patterns\n * @description: 客户端测试类\n * @author: 黄宇辉\n * @date: 9/19/2019-1:49 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Client {\n\n    public static void main(String[] args) {\n        Actor zero = new HeroBuilder().construct();\n        System.out.println(zero);\n\n        System.out.println(\"------------------------------\");\n\n        Actor angel = new AngelBuilder().construct();\n        System.out.println(angel);\n    }\n}\n```\n\n6. *示例程序的运行结果如下所示 :*\n```\nActor{type=\'英雄\', sex=\'男\', face=\'英俊\', costume=\'盔甲\'}\n------------------------------\nActor{type=\'天使\', sex=\'女\', face=\'漂亮\', costume=\'裙子\'}\n```\n\n#### 示例程序的类图\n![](Java设计模式之Builder-Pattern/Builder-Pattern-ClassDiagram2.png)\n','2020-06-19 17:29:40',0),(18,1,'Java设计模式之Command Pattern','命令模式是一种对象行为型模式，其别名为动作( Action )模式或事物( Transaction )模式。命令模式是常用的行为型模式之一，它将请求发送者与请求接收者解耦，请求发送者通过命令对象来间接引用接受者，使得系统具有更好的灵活性，可以在不修改现有系统源码代码的情况下让相同的发送者对应不同的接受者...','> *本文章摘自我的博客 : ishacker.net*\n\n## 学习笔记 : Java设计模式之Command Pattern\n\n### 定义\n*命令模式 : 将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作. ( Command Pattern : Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and undoable operations )*\n\n* 扩 : 命令模式是一种对象行为型模式,其别名为动作( Action )模式或事物( Transaction )模式. 命令模式是常用的行为型模式之一,它将请求发送者与请求接收者`解耦`,请求发送者通过命令对象来间接引用接受者,使得系统具有更好的灵活性,可以在不修改现有系统源码代码的情况下让相同的发送者对应不同的接受者.\n\n\n\n### 角色分析\n1. *`Command( 抽象命令类 )` : 抽象命令类一般是一个抽象接类或接口,在其中声明了用于执行请求的 execute() 等方法,通过这些方法可以调用`请求接收者`的相关操作.*\n2. *`ConcreteCommand( 具体命令类 )` : 具体命令类是`抽象命令类`的子类,实现了在抽象命令类中声明的方法,它对应具体的`接收者`对象,将接收者对象的动作绑定其中. 具体命令类在实现 execute() 方法时将调用`接收者`对象的相关操作.*\n3. *`Invoker( 调用者 )` : 调用者既请求发送者,它通过命令对象来执行请求. 一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令类之间存在关联关系. 在程序运行时可以将一个具体命令对象注入其中,再调用具体命令对象的 execute() 方法,从而实现间接调用`请求接收者`的相关操作.*\n4. *`Receiver( 接收者 )` : 接收者执行与请求相关的操作,具体实现对请求业务的处理.*\n\n\n\n### 示例程序-1\n*下面是一个使用命令设计模式的简单程序案例,案例说明 : 某系统提供了一系列功能键,用户可以自定义功能键( FunctionButton )的功能,例如登录键( LoginInCommand )用于登录系统,退出键( LoginOutCommand )用于注销系统 · · ·*\n\n1. *FunctionButton类 : 功能键类, 充当请求调用者(请求发送者)*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 功能键类, 充当请求调用者(请求发送者)\n * @author: 黄宇辉\n * @date: 9/20/2019-8:59 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class FunctionButton {\n\n    private Command command;\n\n    //为功能键注入命令\n    public void setCommand(Command command) {\n        this.command = command;\n    }\n\n    //发送请求的方法\n    public void click() {\n        command.execute();\n    }\n\n}\n```\n\n2. *Command抽象类 : 抽象命令类*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 抽象命令类\n * @author: 黄宇辉\n * @date: 9/20/2019-9:01 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic abstract class Command {\n    public abstract void execute();\n}\n```\n\n3. *LoginInCommand类 : 登录命令类, 充当具体命令类*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 登录命令类, 充当具体命令类\n * @author: 黄宇辉\n * @date: 9/20/2019-9:07 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class LoginInCommand extends Command {\n\n    private LoginInSystem enterSystem;\n\n    public LoginInCommand() {\n        this.enterSystem = new LoginInSystem();\n    }\n\n    //命令执行方法,将调用请求接收者的业务方法\n    @Override\n    public void execute() {\n        enterSystem.login();\n    }\n}\n```\n\n4. *LoginOutCommand类 : 退出命令类, 充当具体命令类*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 退出命令类, 充当具体命令类\n * @author: 黄宇辉\n * @date: 9/20/2019-9:05 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class LoginOutCommand extends Command {\n\n    private LoginOutSystem exitSystem;\n\n    public LoginOutCommand() {\n        this.exitSystem = new LoginOutSystem();\n    }\n\n    //命令执行方法,将调用请求接受者的业务方法\n    @Override\n    public void execute() {\n        exitSystem.exit();\n    }\n}\n```\n\n5. *LoginInSystem类 : 登录系统的模拟实现类, 充当请求接收者*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 登录系统的模拟实现类, 充当请求接收者\n * @author: 黄宇辉\n * @date: 9/20/2019-9:10 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class LoginInSystem {\n\n    public void login() {\n        System.out.println(\"login in\");\n    }\n}\n```\n\n6. *LoginOutSystem类 : 退出系统的模拟实现类, 充当请求接收者*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 退出系统的模拟实现类, 充当请求接收者\n * @author: 黄宇辉\n * @date: 9/20/2019-9:08 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class LoginOutSystem {\n\n    public void exit() {\n        System.out.println(\"login out\");\n    }\n}\n```\n\n7. *Client类 : 客户端测试类*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 客户端测试类\n * @author: 黄宇辉\n * @date: 9/20/2019-9:11 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Client {\n\n    public static void main(String[] args) {\n        FunctionButton functionButton = new FunctionButton();\n        Command login_key = new LoginInCommand();\n        functionButton.setCommand(login_key);\n        functionButton.click();\n\n        System.out.println(\"--------------------\");\n\n        Command exit_key = new LoginOutCommand();\n        functionButton.setCommand(exit_key);\n        functionButton.click();\n    }\n}\n```\n\n8. *示例程序运行的结果如下所示 :*\n```\nlogin in\n--------------------\nlogin out\n```\n\n#### 示例程序的类图\n![ ](Java设计模式之Command-Pattern/Command-Pattern-ClassDiagram1.png)\n\n\n\n### 示例程序-2\n*下面是一个使用命令设计模式的简单程序案例,案例说明 : 设计一个画图软件,既用户可以通过拖动鼠标在画板上画画,点击 clear 按钮时会擦除画板上的痕迹.*\n\n1. *Command接口 : 表示\"命令\"的接口,充当(抽象)命令*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_2;\n\n/**\n * @project: design-patterns\n * @description: 表示\"命令\"的接口,充当(抽象)命令\n * @author: 黄宇辉\n * @date: 9/20/2019-9:25 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic interface Command {\n    void execute();\n}\n```\n\n2. *MacroCommand类 : 表示\"由多条命令整合成的命令\"的类,充当具体的命令*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_2;\n\nimport java.util.Stack;\n\n/**\n * @project: design-patterns\n * @description: 表示\"由多条命令整合成的命令\"的类,充当具体的命令\n * @author: 黄宇辉\n * @date: 9/20/2019-9:27 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class MacroCommand implements Command {\n\n    //命令的集合\n    private Stack commands = new Stack();\n\n    //执行命令\n    @Override\n    public void execute() {\n        for (Object command : commands) {\n            ((Command) command).execute();\n        }\n    }\n\n    //添加命令\n    public void append(Command command) {\n        if (command != this) {\n            commands.push(command);\n        }\n    }\n\n    //清除命令\n    public void clear() {\n        commands.clear();\n    }\n\n}\n```\n\n3. *DrawCommand类 : 表示\"绘制一个点的命令( 画笔 )\"的类,充当具体的命令*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_2;\n\nimport java.awt.*;\n\n/**\n * @project: design-patterns\n * @description: 表示\"绘制一个点的命令\"的类,充当具体的命令\n * @author: 黄宇辉\n * @date: 9/20/2019-9:33 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class DrawCommand implements Command {\n\n    //绘制对象\n    protected Drawable drawable;\n\n    //绘制位置\n    private Point position;\n\n    //构造函数\n    public DrawCommand(Drawable drawable, Point position) {\n        this.drawable = drawable;\n        this.position = position;\n    }\n\n    //执行命令\n    @Override\n    public void execute() {\n        drawable.draw(position.x, position.y);\n    }\n\n}\n```\n\n4. *Drawable接口 : 表示\"绘制对象\"的接口*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_2;\n\n/**\n * @project: design-patterns\n * @description: 表示\"绘制对象\"的接口\n * @author: 黄宇辉\n * @date: 9/20/2019-9:37 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic interface Drawable {\n    void draw(int x, int y);\n}\n```\n\n5. *DrawCanvas类 : 实现\"绘制对象\"的类,充当接收者*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_2;\n\nimport java.awt.*;\n\n/**\n * @project: design-patterns\n * @description: 实现\"绘制对象\"的类,充当接收者\n * @author: 黄宇辉\n * @date: 9/20/2019-9:39 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class DrawCanvas extends Canvas implements Drawable {\n\n    //颜色\n    private Color color = Color.green;\n    //要绘制的圆点半径\n    private int redius = 5;\n    //命令的历史记录\n    private MacroCommand history;\n\n    //构造函数\n    public DrawCanvas(int width, int height, MacroCommand history) {\n        this.setSize(width, height);\n        this.setBackground(Color.white);\n        this.history = history;\n    }\n\n    //重新全部绘制\n    public void repaint(Graphics graphics) {\n        history.execute();\n    }\n\n    //绘制\n    @Override\n    public void draw(int x, int y) {\n        Graphics graphics = getGraphics();\n        graphics.setColor(color);\n        graphics.fillOval(x - redius, y - redius, redius * 2, redius * 2);\n    }\n}\n```\n\n6. *Client类 : 客户端测试类*\n```java\npackage pers.huangyuhui.command_pattern.command_pattern_2;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseMotionAdapter;\n\n/**\n * @project: design-patterns\n * @description: 客户端测试类\n * @author: 黄宇辉\n * @date: 9/20/2019-9:48 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Client extends JFrame {\n\n    //绘制的历史记录\n    private MacroCommand history = new MacroCommand();\n    //绘制区域(设置画板大小)\n    private DrawCanvas canvas = new DrawCanvas(600, 400, history);\n    //删除按钮\n    private JButton clearButton = new JButton(\"clear\");\n\n    public Client(String title) {\n        super(title);\n\n        /*\n        鼠标拖动事件\n         */\n        canvas.addMouseMotionListener(new MouseMotionAdapter() {\n            @Override\n            public void mouseDragged(MouseEvent e) {\n                Command command = new DrawCommand(canvas, e.getPoint());\n                history.append(command);\n                command.execute();\n            }\n        });\n\n        /*\n        动作监听事件\n         */\n        clearButton.addActionListener(e -> {\n            if (e.getSource() == clearButton) {\n                history.clear();\n                canvas.repaint();\n            }\n        });\n\n        /*\n        JFrame面板配置\n         */\n        setLayout(new BorderLayout());\n        add(clearButton, BorderLayout.NORTH);\n        add(canvas, BorderLayout.SOUTH);\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        pack();\n        setVisible(true);\n    }\n\n    public static void main(String[] args) {\n        new Client(\"a simple drawing board\");\n    }\n\n}\n```\n\n7. *示例程序的运行结果如下图所示 :*\n![](Java设计模式之Command-Pattern/Command-Pattern-ClassDiagram2-drawing.png)\n\n#### 示例程序的类图\n![ ](Java设计模式之Command-Pattern/Command-Pattern-ClassDiagram2.png)\n','2020-06-19 17:33:22',0),(19,1,'Java设计模式之Composite Pattern','组合模式又称部分-整体( Part-Whole )模式，属于对象结构型模式,它将对象组织到树形结构中，可以用来描述整体与部分的关系...','> *本文章摘自我的博客 : ishacker.net*\n\n## 学习笔记 : Java设计模式之Composite Pattern\n \n### 概述\n*`组合设计模式` : 组合多个对象形成树形结构以表示具有`部分-整体`关系的层次结构. 组合模式让客户端可以统一对待单个对象和组合对象. (Composite Pattern : Compose objects into tree structures to pepresent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uninformly.)*\n\n* 扩 : 组合模式又称`部分-整体( Part-Whole )`模式,属于对象结构型模式,它将对象组织到树形结构中,可以用来描述整体与部分的关系\n\n\n### 组合模式中的角色\n1. *`Component( 抽象构件 )` : 它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现. 在抽象构件中定义了访问及管理它的子构件的方法,如增加,删除,获取子构件等.*\n2. *`Leaf( 叶子构件 )` : 它在组合结构中表示叶子结点对象,叶子节点没有子结点,它实现了在抽象构件中定义的行为. 对于那些访问及管理子构件的方法,可以通过抛出异常,提示错误等方式进行处理.*\n3. *`Composite( 容器构件 )` : 它在组合结构中表示容器节点对象,`容器结点包含子结点,其子结点可以是叶子结点,也可以是容器结点`,它提供了一个集合用于存储子结点,实现了在抽象构件中定义的行为,包括哪些访问及管理子构件的方法,在其业务方法中可以递归调用其自子结点的业务方法.*\n\n* 扩 : 组合模式的关键在于定义了一个抽象构件类,它既可以代表`叶子`,又可以代表`容器`,客户端针对该抽象构件类进行编程,无须知道它到底表示的叶子还是容器,可以对其进行统一处理. 同时容器对象与抽象构件类之间还建立一个`聚合关联关系`,在容器对象中既可以包含叶子,又可以包含容器,以此实现递归组合,形成一个`树形结构`.\n\n\n### 适用环境\n*Java SE中的 AWT 和 Swing 包的设计就基于组合模式,在这些界面包中为用户提供了大量的容器构件,如 Container( 容器构件 ) 和成员构件,如 Checkbox, Button, TextComponent( 一些叶子构件 )等,其都继承自 Componet 抽象类( 抽象构件 )*\n\n\n### 示例程序1\n*下面是一个使用组合设计模式的简单示例程序,这段示例程序的功能为列出文件夹及其中文件的名称及大小~*\n\n1. *Entry抽象类 : 表示目录条目的抽象类, 充当Component角色*\n```java\npackage pers.huangyuhui.composite_pattern.composite_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 表示目录条目的抽象类, 充当Component角色\n * @author: 黄宇辉\n * @date: 9/11/2019-12:16 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic abstract class Entry {\n\n    public abstract String getName();\n\n    public abstract int getSize();\n\n    public Entry add(Entry entry) throws FileTreatMentException {\n        throw new FileTreatMentException();\n    }\n\n    public void printList() {\n        printList(\"\");\n    }\n\n    protected abstract void printList(String prefix);\n\n    public String toString() {\n        return getName() + \" (\" + getSize() + \")\";\n    }\n}\n```\n\n2. *File类 : 表示文件的类, 充当Leaf角色*\n```java\npackage pers.huangyuhui.composite_pattern.composite_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 表示文件的类, 充当Leaf角色\n * @author: 黄宇辉\n * @date: 9/11/2019-12:22 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class File extends Entry {\n\n    private String name;\n    private int size;\n\n    public File(String name, int size) {\n        this.name = name;\n        this.size = size;\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public int getSize() {\n        return size;\n    }\n\n    @Override\n    protected void printList(String prefix) {\n        System.out.println(prefix + \"/\" + this.toString());\n    }\n}\n```\n\n3. *Directory类 : 表示文件夹的类, 充当Composite角色*\n```java\npackage pers.huangyuhui.composite_pattern.composite_pattern_1;\n\nimport java.util.ArrayList;\n\n/**\n * @project: design-patterns\n * @description: 表示文件夹的类, 充当Composite角色\n * @author: 黄宇辉\n * @date: 9/11/2019-12:25 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Directory extends Entry {\n\n    private String name;\n    private ArrayList<Entry> directory = new ArrayList<>();\n\n    public Directory(String name) {\n        this.name = name;\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public int getSize() {\n        var size = 0;\n        for (Entry entry : directory) {\n            size += entry.getSize();\n        }\n        return size;\n    }\n\n    @Override\n    public Entry add(Entry entry) {\n        directory.add(entry);\n        return this;\n    }\n\n    @Override\n    protected void printList(String prefix) {\n        System.out.println(prefix + \"/\" + this.toString());\n        for (Entry entry : directory) {\n            entry.printList(prefix + \"/\" + name);\n        }\n    }\n}\n```\n\n4. *FileTreatMentException类 : 自定义异常类*\n```java\npackage pers.huangyuhui.composite_pattern.composite_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 自定义异常类\n * @author: 黄宇辉\n * @date: 9/11/2019-12:19 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class FileTreatMentException extends RuntimeException {\n\n    public FileTreatMentException() {\n\n    }\n\n    public FileTreatMentException(String msg) {\n        super(msg);\n    }\n}\n```\n\n5. *Client类 : 客户端测试类*\n```java\npackage pers.huangyuhui.composite_pattern.composite_pattern_1;\n\n/**\n * @project: design-patterns\n * @description: 客户端测试类\n * @author: 黄宇辉\n * @date: 9/11/2019-12:36 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Client {\n\n    public static void main(String[] args) {\n        try {\n            System.out.println(\"------ Making Root Entries ------\");\n            Directory rootdir = new Directory(\"root\");\n            Directory bindir = new Directory(\"bin\");\n            Directory temdir = new Directory(\"tmp\");\n            Directory usrdir = new Directory(\"usr\");\n            rootdir.add(bindir);\n            rootdir.add(temdir);\n            rootdir.add(usrdir);\n            bindir.add(new File(\"demo1.class\", 10000));\n            bindir.add(new File(\"demo2.class\", 20000));\n            rootdir.printList();\n\n            System.out.println(\"\\n\" + \"------ Making User Entries ------\");\n            Directory demoDir1 = new Directory(\"demoDir1\");\n            Directory demoDir2 = new Directory(\"demoDir2\");\n            Directory demoDir3 = new Directory(\"demoDir3\");\n            usrdir.add(demoDir1);\n            usrdir.add(demoDir2);\n            usrdir.add(demoDir3);\n            demoDir1.add(new File(\"demo.html\", 100));\n            demoDir1.add(new File(\"demo.java\", 200));\n            demoDir2.add(new File(\"demo.txt\", 300));\n            demoDir3.add(new File(\"demo.doc\", 400));\n            demoDir3.add(new File(\"demo.mail\", 500));\n            rootdir.printList();\n        } catch (FileTreatMentException e) {\n            e.printStackTrace();\n        }\n\n    }\n}\n```\n\n6. *程序运行结果如下所示 :*\n```\n------ Making Root Entries ------\n/root (30000)\n/root/bin (30000)\n/root/bin/demo1.class (10000)\n/root/bin/demo2.class (20000)\n/root/tmp (0)\n/root/usr (0)\n\n------ Making User Entries ------\n/root (31500)\n/root/bin (30000)\n/root/bin/demo1.class (10000)\n/root/bin/demo2.class (20000)\n/root/tmp (0)\n/root/usr (1500)\n/root/usr/demoDir1 (300)\n/root/usr/demoDir1/demo.html (100)\n/root/usr/demoDir1/demo.java (200)\n/root/usr/demoDir2 (300)\n/root/usr/demoDir2/demo.txt (300)\n/root/usr/demoDir3 (900)\n/root/usr/demoDir3/demo.doc (400)\n/root/usr/demoDir3/demo.mail (500)\n```\n\n#### 示例程序的类图\n![](Java设计模式之Composite-Pattern/Composite-Pattern-ClassDiagram1.png)\n\n\n### 示例程序2\n*下面是一个使用组合设计模式的简单示例程序 : 写一个模拟杀毒( Antivirus )程序,该程序既可以对某个文件夹( Folder )杀毒,也可以对某个指定的文件( File )杀毒,而且该杀毒程序还可以根据各类文件的特点为不同类型(文本文件,图像文件,音频文件等)的文件提供不同的杀毒方式.*\n\n1. *AbstractFile抽象类 : 抽象文件类, 充当抽象构件类*\n```java\npackage pers.huangyuhui.composite_pattern.composite_pattern_2;\n\n/**\n * @project: design-patterns\n * @description: 抽象文件类, 充当抽象构件类\n * @author: 黄宇辉\n * @date: 9/11/2019-1:19 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic abstract class AbstractFile {\n\n    public abstract String getName();\n\n    public abstract void killVirus();\n\n    public void add(AbstractFile file) {\n        throw new FileTreatMentException();\n    }\n\n}\n```\n\n2. *TextFile类 : 文本文件类, 充当叶子构件类*\n```java\npackage pers.huangyuhui.composite_pattern.composite_pattern_2;\n\n/**\n * @project: design-patterns\n * @description: 文本文件类, 充当叶子构件类\n * @author: 黄宇辉\n * @date: 9/11/2019-1:31 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class TextFile extends AbstractFile {\n\n    private String name;\n\n    public TextFile(String name) {\n        this.name = name;\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public void killVirus() {\n        System.out.println(\"——————> 对文本文件[ \" + name + \" ]进行杀毒\");\n    }\n}\n```\n\n3. *ImageFile类 : 图像文件类, 充当叶子构件类*\n```java\npackage pers.huangyuhui.composite_pattern.composite_pattern_2;\n\n/**\n * @project: design-patterns\n * @description: 图像文件类, 充当叶子构件类\n * @author: 黄宇辉\n * @date: 9/11/2019-1:27 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class ImageFile extends AbstractFile {\n\n    private String name;\n\n    public ImageFile(String name) {\n        this.name = name;\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public void killVirus() {\n        System.out.println(\"——————> 对图像文件[ \" + name + \" ]进行杀毒\");\n    }\n}\n```\n\n4. *Folder类 : 文件夹类, 充当容器构件类*\n```java\npackage pers.huangyuhui.composite_pattern.composite_pattern_2;\n\nimport java.util.ArrayList;\n\n/**\n * @project: design-patterns\n * @description: 文件夹类, 充当容器构件类\n * @author: 黄宇辉\n * @date: 9/11/2019-1:38 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Folder extends AbstractFile {\n\n    private String name;\n    private ArrayList<AbstractFile> directory = new ArrayList<>();\n\n    public Folder(String name) {\n        this.name = name;\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public void add(AbstractFile file) {\n        directory.add(file);\n    }\n\n    @Override\n    public void killVirus() {\n        System.out.println(\"======> 对文件夹[ \" + name + \" ]进行杀毒\");\n        //递归调用成员构件的killVirus方法\n        for (AbstractFile abstractFile : directory) {\n            abstractFile.killVirus();\n        }\n    }\n}\n```\n\n5. *FileTreatMentException类 : 自定义异常类*\n```java\npackage pers.huangyuhui.composite_pattern.composite_pattern_2;\n\n/**\n * @project: design-patterns\n * @description: 自定义异常类\n * @author: 黄宇辉\n * @date: 9/11/2019-12:19 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class FileTreatMentException extends RuntimeException {\n\n    public FileTreatMentException() {\n\n    }\n\n    public FileTreatMentException(String msg) {\n        super(msg);\n    }\n}\n```\n\n6. *Client类 : 客户端测试类*\n```java\npackage pers.huangyuhui.composite_pattern.composite_pattern_2;\n\n/**\n * @project: design-patterns\n * @description: 客户端测试类\n * @author: 黄宇辉\n * @date: 9/11/2019-1:44 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Client {\n\n    public static void main(String[] args) {\n        AbstractFile folder = new Folder(\"my-folder\");\n        AbstractFile textFolder = new Folder(\"text-folder\");\n        AbstractFile imageFolder = new Folder(\"image-folder\");\n        AbstractFile file = new TextFile(\"demo.text\");\n        AbstractFile image = new ImageFile(\"demo.jpg\");\n        textFolder.add(file);\n        imageFolder.add(image);\n        folder.add(textFolder);\n        folder.add(imageFolder);\n        folder.killVirus();\n    }\n\n}\n```\n\n7. *示例程序的运行结果如下所示 :*\n```\n======> 对文件夹[ my-folder ]进行杀毒\n======> 对文件夹[ text-folder ]进行杀毒\n——————> 对文本文件[ demo.text ]进行杀毒\n======> 对文件夹[ image-folder ]进行杀毒\n——————> 对图像文件[ demo.jpg ]进行杀毒\n```\n\n#### 示例程序的类图\n![](Java设计模式之Composite-Pattern/Composite-Pattern-ClassDiagram2.png)\n','2020-06-19 17:34:58',0),(20,1,'Java设计模式之Decorator Pattern','装饰设计模式( 对象结构型模式 )是一种用于替代继承的技术，它通过一种无须定义子类的方式来给对象动态增加职责，使用对象之间的关联关系取代类之间的继承关系。装饰设计模式的定位为 : 动态地给一个对象增加一些额外的职责，就扩展而言，装饰模式提供了一种比使用子类更加灵活的替代方案...','> *本文章摘自我的博客 : ishacker.net*\n\n## 学习笔记 : Java设计模式之Decorator Pattern\n\n### 概述\n*装饰设计模式( 对象结构型模式 )是一种用于替代继承的技术,它通过一种无须定义子类的方式来给对象动态增加职责,使用对象之间的关联关系取代类之间的继承关系. 装饰设计模式的定位为 : 动态地给一个对象增加一些额外的职责. 就扩展而言,装饰模式提供了一种比使用子类更加灵活的替代方案. ( Decorator Pattern : Attach additonal responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality )*\n\n\n### 装饰设计模式中的角色\n1. *`Component ( 抽象构件 )` : 它是`具体构件`和`抽象装饰类`的共同父类,声明了在具体构件中实现的业务方法,它的引入可以使客户端以一致的方式处理未被装饰的对象及装饰之后的对象,实现客户端的透明操作.*\n2. *`ConcreteComponent ( 具体构件 )` : 它是`抽象构件类`的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰类可以给它增加额外的职责( 方法 )*\n3. *`Decorator ( 抽象装饰类 )` : 它也是`抽象构件类`的子类,用于给`具体构件`增加职责,但是具体职责在其子类中实现. 它维护一个指向抽象构件的引用,通过该引用可以调用装饰之前构件对象的方法,并通过子类扩展该方法,继而达到装饰的目的.*\n4. *`ConcreteDecorator ( 具体装饰类 )` : 它是`抽象装饰类`的子类,负责向构件添加新的职责. 每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用于扩展对象的行为.*\n\n\n### 示例程序-透明装饰模式\n*下面是一个使用了装饰设计模式的简单示例程序,其示例说明为 : 使用面向对象技术开发了一套图形界面构件库,该构件库提供了大量的基本结构,如窗体,文本框,列表框等,由于在使用时用户经常要求定制一些特殊的显示效果,如带滚动条的窗体,或带黑色边框的文本框等. 因此经常需要对该构件库进行扩展以增强其功能,既而可以使用装饰设计模式来设计该界面构件库哟~*\n\n1. *Component接口 : 抽象界面构件类, 充当抽象构件类*\n```java\npackage pers.huangyuhui.decorator_pattern;\n\n/**\n * @project: design-patterns\n * @description: 抽象界面构件类, 充当抽象构件类\n * @author: 黄宇辉\n * @date: 9/9/2019-2:47 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic abstract class Component {\n\n    public abstract void display();\n}\n```\n\n2. *Window类 : 窗体类, 充当具体构件类*\n```java\npackage pers.huangyuhui.decorator_pattern;\n\n/**\n * @project: design-patterns\n * @description: 窗体类, 充当具体构件类\n * @author: 黄宇辉\n * @date: 9/9/2019-2:48 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Window extends Component {\n\n    @Override\n    public void display() {\n        System.out.println(\"显示窗体 !\");\n    }\n}\n```\n\n3. *TextBox类 : 文本框类, 充当具体构件类*\n```java\npackage pers.huangyuhui.decorator_pattern;\n\n/**\n * @project: design-patterns\n * @description: 文本框类, 充当具体构件类\n * @author: 黄宇辉\n * @date: 9/9/2019-2:50 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class TextBox extends Component {\n    @Override\n    public void display() {\n        System.out.println(\"显示文本框 !\");\n    }\n}\n```\n\n4. *ListBox类 : 列表框类, 充当具体构件类*\n```java\npackage pers.huangyuhui.decorator_pattern;\n\n/**\n * @project: design-patterns\n * @description: 列表框类, 充当具体构件类\n * @author: 黄宇辉\n * @date: 9/9/2019-2:51 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class ListBox extends Component {\n\n    @Override\n    public void display() {\n        System.out.println(\"显示列表框 !\");\n    }\n}\n```\n\n5. *ComponentDecorator类 : 构件装饰类, 充当抽象装饰类*\n```java\npackage pers.huangyuhui.decorator_pattern;\n\n/**\n * @project: design-patterns\n * @description: 构件装饰类, 充当抽象装饰类\n * @author: 黄宇辉\n * @date: 9/9/2019-2:52 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class ComponentDecorator extends Component {\n\n    //维持对抽象构件类型对象的引用\n    private Component component;\n\n    //注入抽象构件类型的对象\n    public ComponentDecorator(Component component) {\n        this.component = component;\n    }\n\n    @Override\n    public void display() {\n        component.display();\n    }\n}\n```\n\n6. *ScrollBarDecorator类 : 滚动条装饰类, 充当具体装饰类*\n```java\npackage pers.huangyuhui.decorator_pattern;\n\n/**\n * @project: design-patterns\n * @description: 滚动条装饰类, 充当具体装饰类\n * @author: 黄宇辉\n * @date: 9/9/2019-2:54 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class ScrollBarDecorator extends ComponentDecorator {\n\n    public ScrollBarDecorator(Component component) {\n        super(component);\n    }\n\n    @Override\n    public void display() {\n        this.setScrollBar();\n        super.display();\n    }\n\n    private void setScrollBar() {\n        System.out.println(\"为构件添加滚动条 !\");\n    }\n}\n```\n\n7. *BlackBorderDecorator类 : 黑色边框装饰类, 充当具体装饰类*\n```java\npackage pers.huangyuhui.decorator_pattern;\n\n/**\n * @project: design-patterns\n * @description: 黑色边框装饰类, 充当具体装饰类\n * @author: 黄宇辉\n * @date: 9/9/2019-2:59 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class BlackBorderDecorator extends ComponentDecorator {\n\n    public BlackBorderDecorator(Component component) {\n        super(component);\n    }\n\n    @Override\n    public void display() {\n        this.setBlackBorder();\n        super.display();\n    }\n\n    private void setBlackBorder() {\n        System.out.println(\"为构件添加黑色边框 !\");\n    }\n}\n```\n\n8. *Client类 : 客户端测试类*\n```java\npackage pers.huangyuhui.decorator_pattern;\n\n/**\n * @project: design-patterns\n * @description: 客户端测试类\n * @author: 黄宇辉\n * @date: 9/9/2019-3:03 PM\n * @version: 1.0\n * @website: https://yubuntu0109.github.io/\n */\npublic class Client {\n\n    public static void main(String[] args) {\n        Component component = new Window();\n        component.display();\n\n        System.out.println(\"------------------\");\n\n        Component component2 = new ScrollBarDecorator(component);\n        component2.display();\n    }\n}\n```\n\n#### 示例程序的类图\n![](Java设计模式之Decorator-Pattern/Decorator-Pattern-ClassDiagram.png)\n\n\n\n### 示例程序-半透明装饰模式\n*暂略 · · ·*\n','2020-06-19 17:37:13',0);
/*!40000 ALTER TABLE `m_blog` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `m_user`
--

DROP TABLE IF EXISTS `m_user`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
 SET character_set_client = utf8mb4 ;
CREATE TABLE `m_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(64) DEFAULT NULL,
  `avatar` varchar(255) DEFAULT NULL,
  `email` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL,
  `status` int(5) NOT NULL,
  `created` datetime DEFAULT NULL,
  `last_login` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `UK_USERNAME` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `m_user`
--

LOCK TABLES `m_user` WRITE;
/*!40000 ALTER TABLE `m_user` DISABLE KEYS */;
INSERT INTO `m_user` VALUES (1,'admin','https://vuejs.org/images/logo.png','iblog.run@foxmail.com','eedf8509cd30c0a7f13a3f78d2b11ae4',0,'2020-04-20 10:44:01',NULL);
/*!40000 ALTER TABLE `m_user` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2020-06-19 18:38:30
