# JavaStudy **Repository Path**: steve-one/java-test ## Basic Information - **Project Name**: JavaStudy - **Description**: Stev5的JavaStudy - **Primary Language**: Unknown - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-20 - **Last Updated**: 2025-12-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # JavaSE 与设计模式学习项目 这是一个用于学习和实践 JavaSE 核心知识与设计模式的Java项目。 ## 📚 学习计划与进度 ### JavaSE 学习进度 | 日期 | 学习主题 | 示例代码 | 学习要点 | 状态 | |------------|-----------------|-----------------------------------------------------------------------|-------------------------------------|-------| | 2025-10-27 | 类型定义结构 | [javase](src/main/java/com/steve/javase) | 类、接口、枚举、记录类等类型定义 | ✅ 已完成 | | 2025-10-27 | JavaSE 基础语法 | [javase](src/main/java/com/steve/javase) | 数据类型、断言、Scanner输入 | ✅ 已完成 | | 2025-10-29 | 对象克隆 | [clone](src/main/java/com/steve/javase/clone) | 深拷贝与浅拷贝、Cloneable接口 | ✅ 已完成 | | 2025-10-29 | 泛型基础 | [fanxing](src/main/java/com/steve/javase/fanxing) | 泛型集合、类型擦除、堆污染 | ✅ 已完成 | | 2025-10-29 | hashCode与equals | [hashCodeAndEquals](src/main/java/com/steve/javase/hashcodeandequals) | 重写规则、HashSet应用 | ✅ 已完成 | | 2025-10-29 | String类与可变字符串 | [string](src/main/java/com/steve/javase/stringtest) | String、StringBuffer、StringBuilder | ✅ 已完成 | | 2025-10-29 | 数组 | [array](src/main/java/com/steve/javase/array) | 数组定义、遍历、可变参数 | ✅ 已完成 | | 2025-11-02 | 数据结构类型定义复习 | [shujujiegou](src/main/java/com/steve/javase/shujujiegou) | 类、接口、记录类的综合应用,数组工具类 | ✅ 已完成 | | 2025-12-10 | 异常处理 | [exceptiontest](src/main/java/com/steve/javase/exceptiontest) | 自定义异常、异常处理机制 | ✅ 已完成 | | 2025-12-10 | IO流 | [inputandoutput](src/main/java/com/steve/javase/inputandoutput) | 字节流、字符流、对象序列化 | ✅ 已完成 | | 2025-12-10 | 关键字学习 | [keywordlearning](src/main/java/com/steve/javase/keywordlearning) | volatile、synchronized、AtomicInteger | ✅ 已完成 | | 2025-12-10 | Object类方法 | [objecttest](src/main/java/com/steve/javase/objecttest) | hashCode、equals重写规则 | ✅ 已完成 | | 2025-12-10 | Stream流操作 | [streamtest](src/main/java/com/steve/javase/streamtest) | 文件流操作、字节流与字符流转换 | ✅ 已完成 | ### 设计模式学习进度 | 日期 | 设计模式 | 类型 | 示例代码 | 学习总结 | |------------|----------------------------------|-----|----------------------------------------------------------------------------------------|-------------------| | 2025-10-21 | 策略模式(Strategy Pattern) | 行为型 | [strategy](src/main/java/com/steve/designpattern/strategy) | [总结](#策略模式总结) | | 2025-10-27 | 观察者模式(Observer Pattern) | 行为型 | [observer](src/main/java/com/steve/designpattern/observer) | [总结](#观察者模式总结) | | 2025-11-26 | 装饰器模式(Decorator Pattern) | 结构型 | [decorator](src/main/java/com/steve/designpattern/decorator) | [总结](#装饰器模式总结) | | 2025-12-10 | 工厂方法模式(Factory Pattern) | 创建型 | [factory](src/main/java/com/steve/designpattern/factory) | [总结](#工厂方法模式总结) | | 2025-12-10 | 单例模式(Singleton Pattern) | 创建型 | [singleton](src/main/java/com/steve/designpattern/singleton) | [总结](#单例模式总结) | | 2025-12-10 | 抽象工厂模式(Abstract Factory) | 创建型 | [abstactfactory](src/main/java/com/steve/designpattern/abstactfactory) | [总结](#抽象工厂模式总结) | | 2025-12-12 | 命令模式(Command Pattern) | 行为型 | [command](src/main/java/com/steve/designpattern/command) | [总结](#命令模式总结) | | 2025-12-12 | 适配器模式(Adapter Pattern) | 结构型 | [adapter](src/main/java/com/steve/designpattern/adapter) | [总结](#适配器模式总结) | | 2025-12-12 | 外观模式(Facade Pattern) | 结构型 | [facade](src/main/java/com/steve/designpattern/facade) | [总结](#外观模式总结) | | 2025-12-12 | 模板方法模式(Template Method Pattern) | 行为型 | [templatemethod](src/main/java/com/steve/designpattern/templatemethod) | [总结](#模板方法模式总结) | | 2025-12-12 | 模板方法钩子模式(Template Method + Hook) | 行为型 | [templatemethodwithhook](src/main/java/com/steve/designpattern/templatemethodwithhook) | [总结](#模板方法钩子模式总结) | | 2025-12-12 | 迭代器模式(Iterator Pattern) | 行为型 | [iterator](src/main/java/com/steve/designpattern/iterator) | [总结](#迭代器模式总结) | | 2025-12-12 | 组合模式(Composite Pattern) | 结构型 | [composite](src/main/java/com/steve/designpattern/composite) | [总结](#组合模式总结) | | 2025-12-12 | 状态模式(State Pattern) | 行为型 | [state](src/main/java/com/steve/designpattern/state) | [总结](#状态模式总结) | | 2025-12-12 | 代理模式(Proxy Pattern) | 结构型 | [proxy](src/main/java/com/steve/designpattern/proxy) | [总结](#代理模式总结) | | 2025-12-15 | 桥接模式(Bridge Pattern) | 结构型 | [bridge](src/main/java/com/steve/designpattern/bridge) | [总结](#桥接模式总结) | | 2025-12-15 | 建造者模式(Builder Pattern) | 创建型 | [builder](src/main/java/com/steve/designpattern/builder) | [总结](#建造者模式总结) | | 2025-12-15 | 责任链模式(Chain of Responsibility) | 行为型 | [chainofresponsibility](src/main/java/com/steve/designpattern/chainofresponsibility) | [总结](#责任链模式总结) | | 2025-12-15 | 享元模式(Flyweight Pattern) | 结构型 | [flyweight](src/main/java/com/steve/designpattern/flyweight) | [总结](#享元模式总结) | | 2025-12-15 | 解释器模式(Interpreter Pattern) | 行为型 | [interpreter](src/main/java/com/steve/designpattern/interpreter) | [总结](#解释器模式总结) | | 2025-12-15 | 中介者模式(Mediator Pattern) | 行为型 | [mediator](src/main/java/com/steve/designpattern/mediator) | [总结](#中介者模式总结) | ## 设计模式详解 ### 策略模式(Strategy Pattern) #### 模式定义 策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。 #### 项目实现 当前项目使用经典的鸭子模拟器示例来演示策略模式: - [Duck](src/main/java/com/steve/designpattern/strategy/Duck.java) 是一个抽象类,代表各种鸭子的基类 - [FlyBehavior](src/main/java/com/steve/designpattern/strategy/FlyBehavior.java) 和 [QuackBehavior](src/main/java/com/steve/designpattern/strategy/QuackBehavior.java) 是两个接口,定义了飞行和叫声的行为 - 具体的实现类提供了不同的行为方式 #### 类图结构 ```mermaid classDiagram class Duck { <> +performQuack() +performFly() +display() +swim() } class FlyBehavior { <> +fly() } class QuackBehavior { <> +quack() } class MallardDuck Duck <|-- MallardDuck Duck --> FlyBehavior Duck --> QuackBehavior FlyBehavior <|.. FlyWithWings FlyBehavior <|.. FlyNoWay QuackBehavior <|.. Quack QuackBehavior <|.. MuteQuack QuackBehavior <|.. Squeak class FlyWithWings class FlyNoWay class Quack class MuteQuack class Squeak ``` #### 策略模式总结 策略模式通过将变化的部分(飞行行为和叫声行为)封装成接口并独立实现,使系统更加灵活和可扩展,解决了继承带来的代码复用性差、维护困难等问题。 通过Setter方法可以在运行时动态改变鸭子的行为,例如可以让不会飞的鸭子学会飞行,或者让会叫的鸭子变得安静。 --- ### 观察者模式(Observer Pattern) #### 模式定义 观察者模式定义了对象之间的一对多依赖关系,当一个对象状态改变时,它的所有依赖者都会收到通知并自动更新。 #### 项目实现 本项目使用天气数据监控系统来演示观察者模式,实现了两种方式: **Push 方式(推送模式)** - [Subject](src/main/java/com/steve/designpattern/observer/push/Subject.java) - 主题接口,定义了注册、移除和通知观察者的方法 - [Observer](src/main/java/com/steve/designpattern/observer/push/Observer.java) - 观察者接口,定义了更新方法 - [WeatherData](src/main/java/com/steve/designpattern/observer/push/WeatherData.java) - 具体主题,维护天气数据 - [CurrentConditionsDisplay](src/main/java/com/steve/designpattern/observer/push/CurrentConditionsDisplay.java) - 具体观察者,显示当前天气 **Pull 方式(拉取模式)** - [WeatherData](src/main/java/com/steve/designpattern/observer/pull/WeatherData.java) - 使用 Java 内置的 Observable 类 - [CurrentConditionDisplay](src/main/java/com/steve/designpattern/observer/pull/CurrentConditionDisplay.java) - 使用 Java 内置的 Observer 接口 #### 类图结构 ```mermaid classDiagram class Subject { <> +registerObserver(Observer) +removeObserver(Observer) +notifyObservers() } class Observer { <> +update(temp, humidity, pressure) } class WeatherData { -observers: List~Observer~ -temperature: float -humidity: float -pressure: float +measurementsChanged() } class CurrentConditionsDisplay { -temperature: float -humidity: float +display() } Subject <|.. WeatherData Observer <|.. CurrentConditionsDisplay WeatherData --> Observer ``` #### 观察者模式总结 观察者模式实现了对象间的松耦合设计,主题只知道观察者实现了某个接口,不需要知道观察者的具体类是谁、做了什么。 **Push vs Pull 两种实现方式:** - **Push(推送)**:主题主动将数据推送给观察者,观察者被动接收 - **Pull(拉取)**:主题只通知观察者数据变化,观察者主动从主题拉取需要的数据 **优点:** - 主题与观察者之间是松耦合的 - 可以动态地添加或删除观察者 - 符合开闭原则,增加新的观察者无需修改主题代码 **应用场景:** - 事件处理系统 - 消息订阅系统 - MVC 架构中的模型-视图关系 --- ### 装饰器模式(Decorator Pattern) #### 模式定义 装饰器模式动态地将责任附加到对象上。若要扩展功能,装饰器提供了比继承更有弹性的替代方案。 #### 项目实现 本项目使用咖啡店订单系统来演示装饰器模式,可以为各种咖啡动态添加调料: - [Beverage](src/main/java/com/steve/designpattern/decorator/Beverage.java) - 抽象组件类,表示饮料 - [CondimentDecorator](src/main/java/com/steve/designpattern/decorator/CondimentDecorator.java) - 抽象装饰器类,表示调料 - [Espresso](src/main/java/com/steve/designpattern/decorator/Espresso.java) - 具体组件:浓缩咖啡 - [HouseBlend](src/main/java/com/steve/designpattern/decorator/HouseBlend.java) - 具体组件:自家混合咖啡 - [Mocha](src/main/java/com/steve/designpattern/decorator/Mocha.java) - 具体装饰器:摩卡调料 - [Milk](src/main/java/com/steve/designpattern/decorator/Milk.java) - 具体装饰器:牛奶调料 #### 类图结构 ```mermaid classDiagram class Beverage { <> #description: String +getDescription() String +cost() Double* } class CondimentDecorator { <> #beverage: Beverage +CondimentDecorator(Beverage) +getDescription() String } class Espresso { +cost() Double } class HouseBlend { +cost() Double } class Mocha { +Mocha(Beverage) +cost() Double } class Milk { +Milk(Beverage) +cost() Double } Beverage <|-- CondimentDecorator Beverage <|-- Espresso Beverage <|-- HouseBlend CondimentDecorator <|-- Mocha CondimentDecorator <|-- Milk CondimentDecorator o-- Beverage ``` #### 装饰器模式总结 装饰器模式通过组合而非继承的方式实现功能的动态扩展,装饰器和被装饰对象有相同的超类型,可以用一个或多个装饰器包装一个对象。 **核心思想:** - 装饰器和被装饰对象有相同的接口(或超类) - 装饰器内部持有一个被装饰对象的引用 - 装饰器可以在委托给被装饰对象之前或之后,加上自己的行为 **优点:** - 比继承更灵活,可以在运行时动态组合功能 - 符合开闭原则,无需修改现有代码即可扩展功能 - 可以用多个装饰器装饰同一个对象,实现功能的自由组合 - 每个装饰器类只关注一个功能,符合单一职责原则 **缺点:** - 会产生很多小对象,增加系统复杂度 - 装饰器嵌套过多时,调试可能比较困难 **应用场景:** - Java I/O 流(InputStream、OutputStream等) - GUI 组件的边框、滚动条等装饰 - 需要动态地给对象添加功能,且这些功能可以动态撤销 - 当继承会导致子类数量爆炸时 **示例运行结果:** ``` Espresso $1.99 House Blend Coffee $0.89 Espresso+Mocha $2.19 House Blend Coffee+Mocha $1.09 House Blend Coffee+Mocha+Milk $1.19 ``` --- ### 工厂方法模式(Factory Pattern) #### 模式定义 工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。 #### 项目实现 本项目使用披萨店订单系统来演示工厂方法模式: - [PizzaFactory](src/main/java/com/steve/designpattern/factory/PizzaFactory.java) - 抽象工厂类,定义了订购披萨的流程 - [Pizza](src/main/java/com/steve/designpattern/factory/Pizza.java) - 抽象产品类,表示披萨 - [ChicagoStylePizzaFactory](src/main/java/com/steve/designpattern/factory/ChicagoStylePizzaFactory.java) - 具体工厂:芝加哥风格披萨工厂 - [ChicagoStyleCheesePizza](src/main/java/com/steve/designpattern/factory/ChicagoStyleCheesePizza.java) - 具体产品:芝加哥风格奶酪披萨 - [ChicagoStyleVeggiePizza](src/main/java/com/steve/designpattern/factory/ChicagoStyleVeggiePizza.java) - 具体产品:芝加哥风格蔬菜披萨 #### 类图结构 ```mermaid classDiagram class PizzaFactory { <> +orderPizza(Class) Pizza #createPizza(Class)* Pizza } class Pizza { <> #name: String +prepare() +bake() +cut() +box() +getName() String } class ChicagoStylePizzaFactory { #createPizza(Class) Pizza } class ChicagoStyleCheesePizza class ChicagoStyleVeggiePizza PizzaFactory <|-- ChicagoStylePizzaFactory Pizza <|-- ChicagoStyleCheesePizza Pizza <|-- ChicagoStyleVeggiePizza PizzaFactory ..> Pizza ``` #### 工厂方法模式总结 工厂方法模式通过让子类决定要实例化哪个具体类,将对象创建的责任委托给子类,实现了创建者和产品的解耦。 **核心思想:** - 定义一个创建对象的接口,让子类决定实例化哪一个类 - 工厂方法让类的实例化推迟到子类 - 使用泛型和反射机制灵活创建对象 **优点:** - 遵循开闭原则,增加新产品时只需增加新的具体工厂类 - 将对象的创建和使用分离,降低系统耦合度 - 使用泛型提高了代码的灵活性和类型安全性 - 客户端只需知道工厂类,无需关心产品的具体实现 **缺点:** - 每增加一个产品就需要增加一个具体产品类和工厂类,增加系统复杂度 - 增加了系统的抽象性和理解难度 **应用场景:** - 创建对象需要大量重复代码时 - 客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可 - 工厂类负责创建的对象比较少 --- ### 单例模式(Singleton Pattern) #### 模式定义 单例模式确保一个类只有一个实例,并提供一个全局访问点。 #### 项目实现 本项目实现了单例模式的多种实现方式: - [EagerSingleton](src/main/java/com/steve/designpattern/singleton/EagerSingleton.java) - 饿汉式单例(类加载时创建) - [LazySingleton](src/main/java/com/steve/designpattern/singleton/LazySingleton.java) - 懒汉式单例(非线程安全) - [ThreadSafeSingleton](src/main/java/com/steve/designpattern/singleton/ThreadSafeSingleton.java) - 线程安全的单例 - [DoubleCheckSingleton](src/main/java/com/steve/designpattern/singleton/DoubleCheckSingleton.java) - 双重检查锁定单例 - [StaticInnerClassSingleton](src/main/java/com/steve/designpattern/singleton/StaticInnerClassSingleton.java) - 静态内部类单例 - [EnumSingleton](src/main/java/com/steve/designpattern/singleton/EnumSingleton.java) - 枚举单例 - [DatabaseConnection](src/main/java/com/steve/designpattern/singleton/DatabaseConnection.java) - 数据库连接单例示例 #### 类图结构 ```mermaid classDiagram class Singleton { -instance: Singleton -Singleton() +getInstance() Singleton } ``` #### 单例模式总结 单例模式通过将构造函数私有化,并提供一个静态方法来获取唯一实例,确保一个类只有一个实例存在。 **各种实现方式比较:** 1. **饿汉式**:线程安全,但可能造成资源浪费(类加载时就创建实例) 2. **懒汉式**:延迟加载,但在多线程环境下不安全 3. **线程安全的懒汉式**:方法加锁,线程安全但性能较低 4. **双重检查锁定**:既保证线程安全又提高性能,需要使用 volatile 关键字 5. **静态内部类**:利用类加载机制保证线程安全,推荐使用 6. **枚举**:最简单且天然线程安全,防止反序列化创建新对象 **优点:** - 在内存中只有一个实例,减少内存开销 - 避免对资源的多重占用(如文件操作) - 提供全局访问点 **缺点:** - 没有接口,不能继承 - 与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么实例化 **应用场景:** - 数据库连接池 - 配置文件读取 - 日志对象 - 应用程序中需要唯一实例的场景 --- ### 抽象工厂模式(Abstract Factory Pattern) #### 模式定义 抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。 #### 项目实现 本项目使用披萨原料工厂来演示抽象工厂模式: - [PizzaIngredientFactory](src/main/java/com/steve/designpattern/abstactfactory/PizzaIngredientFactory.java) - 抽象工厂接口 - [NYPizzaIngredientFactory](src/main/java/com/steve/designpattern/abstactfactory/NYPizzaIngredientFactory.java) - 纽约风格原料工厂 - [Pizza](src/main/java/com/steve/designpattern/abstactfactory/Pizza.java) - 抽象产品:披萨 - [CheesePizza](src/main/java/com/steve/designpattern/abstactfactory/CheesePizza.java) - 具体产品:奶酪披萨 - [Dough](src/main/java/com/steve/designpattern/abstactfactory/Dough.java) - 抽象产品:面团 - [Sauce](src/main/java/com/steve/designpattern/abstactfactory/Sauce.java) - 抽象产品:酱料 - [Cheese](src/main/java/com/steve/designpattern/abstactfactory/Cheese.java) - 抽象产品:奶酪 - [ThinCrustDough](src/main/java/com/steve/designpattern/abstactfactory/ThinCrustDough.java) - 具体产品:薄饼面团 - [MarinaraSauce](src/main/java/com/steve/designpattern/abstactfactory/MarinaraSauce.java) - 具体产品:番茄酱 - [ReggianoCheese](src/main/java/com/steve/designpattern/abstactfactory/ReggianoCheese.java) - 具体产品:雷吉亚诺奶酪 #### 类图结构 ```mermaid classDiagram class PizzaIngredientFactory { <> +createDough() Dough +createSauce() Sauce +createCheese() Cheese } class NYPizzaIngredientFactory { +createDough() Dough +createSauce() Sauce +createCheese() Cheese } class Pizza { <> #name: String #dough: Dough #sauce: Sauce +prepare()* +bake() +cut() +box() } class CheesePizza { -ingredientFactory: PizzaIngredientFactory +prepare() } class Dough { <> } class Sauce { <> } class Cheese { <> } PizzaIngredientFactory <|.. NYPizzaIngredientFactory Pizza <|-- CheesePizza CheesePizza --> PizzaIngredientFactory PizzaIngredientFactory ..> Dough PizzaIngredientFactory ..> Sauce PizzaIngredientFactory ..> Cheese Dough <|.. ThinCrustDough Sauce <|.. MarinaraSauce Cheese <|.. ReggianoCheese ``` #### 抽象工厂模式总结 抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。它将产品家族的创建封装在工厂中。 **核心思想:** - 提供一个接口,用于创建相关或依赖对象的家族 - 客户端通过抽象接口操纵实例,产品的具体类名被具体工厂的实现分离 - 将一组相关的产品对象创建在一起 **优点:** - 分离了具体类的实现,客户端只需通过抽象接口操作实例 - 使产品族的切换变得容易(只需更换工厂实例) - 确保客户端使用的产品对象来自同一产品族 - 符合开闭原则,新增产品族时只需增加新的工厂类 **缺点:** - 难以支持新种类的产品,需要修改抽象工厂接口及所有实现类 - 增加了系统的抽象性和理解难度 **应用场景:** - 系统中有多个产品族,而系统只消费其中某一族的产品 - 需要提供一个产品类库,而只想显示它们的接口而不是实现 - 强调一系列相关产品对象的设计以便进行联合使用 **与工厂方法模式的区别:** - **工厂方法模式**:针对一个产品等级结构,创建一种产品 - **抽象工厂模式**:针对多个产品等级结构,创建一系列相关产品 --- ### 命令模式(Command Pattern) #### 模式定义 命令模式将"请求"封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。 #### 项目实现 本项目使用智能家居遥控器来演示命令模式: - [Command](src/main/java/com/steve/designpattern/command/Command.java) - 命令接口 - [Light](src/main/java/com/steve/designpattern/command/Light.java) - 接收者:电灯 - [LightOnCommand](src/main/java/com/steve/designpattern/command/LightOnCommand.java) - 具体命令:打开电灯 - [LightOffCommand](src/main/java/com/steve/designpattern/command/LightOffCommand.java) - 具体命令:关闭电灯 - [NoCommand](src/main/java/com/steve/designpattern/command/NoCommand.java) - 空命令对象 - [SimpleRemoteControl](src/main/java/com/steve/designpattern/command/SimpleRemoteControl.java) - 调用者:简单遥控器 #### 类图结构 ```mermaid classDiagram class Command { <> +execute() } class LightOnCommand { -light: Light +execute() } class LightOffCommand { -light: Light +execute() } class NoCommand { +execute() } class Light { -location: String +on() +off() } class SimpleRemoteControl { -command: Command +setCommand(Command) +pressButton() } Command <|.. LightOnCommand Command <|.. LightOffCommand Command <|.. NoCommand LightOnCommand --> Light LightOffCommand --> Light SimpleRemoteControl --> Command ``` #### 命令模式总结 命令模式将发出请求的对象和执行请求的对象解耦,通过将请求封装成命令对象,可以将请求参数化、队列化、日志化,并支持可撤销操作。 **核心思想:** - 将请求封装成对象,从而使你可以用不同的请求对客户进行参数化 - 命令对象将动作和接收者包进对象中,只暴露一个execute()方法 - 调用者通过调用命令对象的execute()方法来提交请求 **优点:** - 降低系统的耦合度,调用者无需知道接收者的接口 - 新的命令可以很容易地加入到系统中 - 可以比较容易地设计一个命令队列和宏命令 - 可以方便地实现对请求的Undo和Redo **缺点:** - 使用命令模式可能会导致系统有过多的具体命令类 **应用场景:** - GUI按钮和菜单项 - 线程池任务调度 - 事务操作(支持回滚) - 日志和审计系统 --- ### 适配器模式(Adapter Pattern) #### 模式定义 适配器模式将一个类的接口转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。 #### 项目实现 本项目使用鸭子和火鸡的例子来演示适配器模式: - [Duck](src/main/java/com/steve/designpattern/adapter/Duck.java) - 目标接口:鸭子 - [Turkey](src/main/java/com/steve/designpattern/adapter/Turkey.java) - 被适配者接口:火鸡 - [MallardDuck](src/main/java/com/steve/designpattern/adapter/MallardDuck.java) - 具体鸭子 - [WildTurkey](src/main/java/com/steve/designpattern/adapter/WildTurkey.java) - 具体火鸡 - [TurkeyAdapter](src/main/java/com/steve/designpattern/adapter/TurkeyAdapter.java) - 适配器:将火鸡适配成鸭子 #### 类图结构 ```mermaid classDiagram class Duck { <> +quack() +fly() } class Turkey { <> +gobble() +flyShortDistance() } class MallardDuck { +quack() +fly() } class WildTurkey { +gobble() +flyShortDistance() } class TurkeyAdapter { -turkey: Turkey +TurkeyAdapter(Turkey) +quack() +fly() } Duck <|.. MallardDuck Turkey <|.. WildTurkey Duck <|.. TurkeyAdapter TurkeyAdapter --> Turkey ``` #### 适配器模式总结 适配器模式通过创建适配器类来包装一个对象,将一个接口转换成另一个接口,使得原本不兼容的类可以一起工作。 **核心思想:** - 适配器实现目标接口,并持有被适配者的引用 - 通过组合的方式将请求委托给被适配者 - 可以在适配过程中进行接口转换 **优点:** - 可以让任何两个没有关联的类一起运行 - 提高了类的复用性 - 增加了类的透明度 - 灵活性好,符合开闭原则 **缺点:** - 过多使用适配器会让系统非常零乱,不易整体把握 **应用场景:** - 使用第三方库或遗留代码时需要接口转换 - 系统需要使用现有的类,但其接口不符合系统的需要 - Java I/O流中的InputStreamReader(将字节流适配成字符流) **示例运行结果:** ``` The Duck says... Quack I'm flying The TurkeyAdapter says... Gobble gobble I'm flying a short distance (x5) ``` --- ### 外观模式(Facade Pattern) #### 模式定义 外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。 #### 项目实现 本项目使用家庭影院系统来演示外观模式: - [HomeTheaterFacade](src/main/java/com/steve/designpattern/facade/HomeTheaterFacade.java) - 外观类 - [Amplifier](src/main/java/com/steve/designpattern/facade/Amplifier.java) - 子系统:功放 - [DvdPlayer](src/main/java/com/steve/designpattern/facade/DvdPlayer.java) - 子系统:DVD播放器 - [Projector](src/main/java/com/steve/designpattern/facade/Projector.java) - 子系统:投影仪 - [Screen](src/main/java/com/steve/designpattern/facade/Screen.java) - 子系统:屏幕 #### 类图结构 ```mermaid classDiagram class HomeTheaterFacade { -amplifier: Amplifier -dvdPlayer: DvdPlayer -projector: Projector -screen: Screen +watchMovie(String) +endMovie() } class Amplifier { +on() +off() +setVolume(int) +setDvd(DvdPlayer) } class DvdPlayer { +on() +off() +play(String) +stop() +eject() } class Projector { +on() +off() +setInput(String) +wideScreenMode() } class Screen { +down() +up() } HomeTheaterFacade --> Amplifier HomeTheaterFacade --> DvdPlayer HomeTheaterFacade --> Projector HomeTheaterFacade --> Screen ``` #### 外观模式总结 外观模式通过提供一个简化的接口来访问复杂的子系统,隐藏了系统的复杂性,使得子系统更容易使用。 **核心思想:** - 为复杂的子系统提供一个简单的接口 - 外观类将客户的请求委派给适当的子系统对象 - 客户与子系统之间通过外观进行通信 **优点:** - 简化了客户端的使用,对客户屏蔽了子系统组件 - 实现了子系统与客户之间的松耦合关系 - 降低了大型软件系统中的编译依赖性 - 更好地划分访问层次,符合迪米特法则 **缺点:** - 不能很好地限制客户使用子系统类 - 增加新的子系统可能需要修改外观类 **应用场景:** - 为复杂的模块或子系统提供简单接口 - 客户程序与多个子系统之间存在很大的依赖性 - 在层次化结构中,定义系统中每一层的入口 **示例运行结果:** ``` Get ready to watch a movie... Screen is going down Projector is on Projector input set to DVD Projector in widescreen mode Amplifier is on Amplifier setting DVD player Amplifier volume set to 5 DVD Player is on Playing movie: Inception Shutting movie theater down... Screen is going up Projector is off Amplifier is off DVD Player stopped DVD ejected DVD Player is off ``` --- ### 模板方法模式(Template Method Pattern) #### 模式定义 模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。 #### 项目实现 本项目使用饮料制作流程来演示模板方法模式: - [Beverage](src/main/java/com/steve/designpattern/templatemethod/Beverage.java) - 抽象类,定义模板方法 - [TeaBeverage](src/main/java/com/steve/designpattern/templatemethod/TeaBeverage.java) - 具体类:茶 - [CoffeeBeverage](src/main/java/com/steve/designpattern/templatemethod/CoffeeBeverage.java) - 具体类:咖啡 #### 类图结构 ```mermaid classDiagram class Beverage { <> +prepareRecipe() final #boilWater() #brew()* #pourInCup()* #addCondiments() #wantCondiments() boolean } class TeaBeverage { #brew() #pourInCup() #addCondiments() } class CoffeeBeverage { -wantCondiments: boolean #brew() #pourInCup() #addCondiments() #wantCondiments() boolean } Beverage <|-- TeaBeverage Beverage <|-- CoffeeBeverage ``` #### 模板方法模式总结 模板方法模式定义了算法的骨架,将一些步骤的实现延迟到子类。通过模板方法,子类可以重定义算法的某些步骤,而不改变算法的整体结构。 **核心思想:** - 在抽象类中定义算法的骨架(模板方法) - 模板方法调用基本方法来完成算法步骤 - 基本方法可以是抽象的,由子类实现 - 钩子方法(Hook)提供默认实现,子类可以选择覆盖 **优点:** - 封装不变部分,扩展可变部分 - 提取公共代码,便于维护 - 行为由父类控制,子类实现 - 符合开闭原则 **缺点:** - 每个不同的实现都需要一个子类,导致类的数量增加 - 抽象类定义了部分抽象方法,由子类实现,子类执行的结果影响父类 **应用场景:** - 一次性实现算法的不变部分,将可变部分留给子类实现 - 各子类中公共的行为应被提取出来并集中到一个公共父类中 - 控制子类的扩展 --- ### 模板方法钩子模式(Template Method + Hook) #### 模式定义 模板方法钩子模式是模板方法模式的扩展,通过钩子方法(Hook Method)让子类能够影响模板方法的流程,提供更大的灵活性。 #### 项目实现 本项目使用游戏流程来演示带钩子的模板方法模式: - [Game](src/main/java/com/steve/designpattern/templatemethodwithhook/Game.java) - 抽象类,定义游戏流程模板和钩子方法 - [Football](src/main/java/com/steve/designpattern/templatemethodwithhook/Football.java) - 具体类:足球游戏 - [Basketball](src/main/java/com/steve/designpattern/templatemethodwithhook/Basketball.java) - 具体类:篮球游戏 - [Chess](src/main/java/com/steve/designpattern/templatemethodwithhook/Chess.java) - 具体类:国际象棋游戏 #### 类图结构 ```mermaid classDiagram class Game { <> +play() final #initialize()* #startPlay()* #endPlay()* #needsSaveScore() boolean #saveScore() } class Football { -isOfficialMatch: boolean #initialize() #startPlay() #endPlay() #needsSaveScore() boolean } class Basketball { #initialize() #startPlay() #endPlay() } class Chess { -isFriendlyMatch: boolean #initialize() #startPlay() #endPlay() #needsSaveScore() boolean #saveScore() } Game <|-- Football Game <|-- Basketball Game <|-- Chess ``` #### 模板方法钩子模式总结 钩子方法为子类提供了干预模板方法执行流程的能力,使得算法更加灵活,子类可以通过钩子方法来控制算法的某些可选步骤。 **钩子方法的特点:** 1. 提供默认实现(可以是空实现或有具体逻辑) 2. 子类可以选择性覆盖 3. 用于在算法的特定点给子类提供干预的机会 4. 可以控制算法流程的某些可选步骤 **核心思想:** - 钩子方法在抽象类中提供默认实现 - 子类可以覆盖钩子方法来影响算法流程 - 通过钩子方法实现"不要调用我们,我们会调用你"的好莱坞原则 **优点:** - 提供了更大的灵活性 - 子类可以选择性地实现钩子方法 - 可以控制算法的某些可选步骤是否执行 **应用场景:** - 需要在算法的特定点让子类进行扩展 - 需要控制算法的某些可选步骤 - 需要在不改变算法结构的前提下让子类影响算法行为 --- ### 迭代器模式(Iterator Pattern) #### 模式定义 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。 #### 项目实现 本项目使用餐厅菜单系统来演示迭代器模式: - [Iterator](src/main/java/com/steve/designpattern/iterator/Iterator.java) - 迭代器接口 - [Menu](src/main/java/com/steve/designpattern/iterator/Menu.java) - 菜单接口 - [MenuItem](src/main/java/com/steve/designpattern/iterator/MenuItem.java) - 菜单项 - [PancakeHouseMenu](src/main/java/com/steve/designpattern/iterator/PancakeHouseMenu.java) - 煎饼屋菜单(使用ArrayList) - [DinerMenu](src/main/java/com/steve/designpattern/iterator/DinerMenu.java) - 餐厅菜单(使用数组) - [PancakeHouseMenuIterator](src/main/java/com/steve/designpattern/iterator/PancakeHouseMenuIterator.java) - 煎饼屋菜单迭代器 - [DinerMenuIterator](src/main/java/com/steve/designpattern/iterator/DinerMenuIterator.java) - 餐厅菜单迭代器 - [Waitress](src/main/java/com/steve/designpattern/iterator/Waitress.java) - 女招待(客户端) #### 类图结构 ```mermaid classDiagram class Iterator { <> +hasNext() boolean +next() MenuItem } class Menu { <> +createIterator() Iterator } class MenuItem { -name: String -description: String -vegetarian: boolean -price: double } class PancakeHouseMenu { -menuItems: ArrayList +createIterator() Iterator } class DinerMenu { -menuItems: MenuItem[] +createIterator() Iterator } class PancakeHouseMenuIterator { -items: ArrayList -position: int +hasNext() boolean +next() MenuItem } class DinerMenuIterator { -items: MenuItem[] -position: int +hasNext() boolean +next() MenuItem } class Waitress { -menus: ArrayList~Menu~ +printMenu() +printVegetarianMenu() } Iterator <|.. PancakeHouseMenuIterator Iterator <|.. DinerMenuIterator Menu <|.. PancakeHouseMenu Menu <|.. DinerMenu PancakeHouseMenu ..> PancakeHouseMenuIterator DinerMenu ..> DinerMenuIterator Waitress --> Menu Waitress --> Iterator ``` #### 迭代器模式总结 迭代器模式将遍历聚合对象的任务封装到迭代器对象中,客户端通过迭代器来访问聚合对象的元素,而不需要了解聚合对象的内部结构。 **核心思想:** - 将遍历的任务放在迭代器上,而不是聚合对象上 - 简化了聚合对象的接口和实现 - 让聚合对象专注于管理对象集合 **优点:** - 支持以不同的方式遍历一个聚合对象 - 简化了聚合类 - 在同一个聚合上可以有多个遍历 - 增加新的聚合类和迭代器类都很方便,符合开闭原则 **缺点:** - 由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要增加新的迭代器类,类的个数成对增加 **应用场景:** - 访问一个聚合对象的内容而无需暴露其内部表示 - 需要为聚合对象提供多种遍历方式 - 为遍历不同的聚合结构提供统一的接口 **Java中的应用:** - Java集合框架中的Iterator接口 - for-each循环的底层实现 --- ### 组合模式(Composite Pattern) #### 模式定义 组合模式允许你将对象组合成树形结构来表现"整体/部分"层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。 #### 项目实现 本项目使用餐厅菜单树形结构来演示组合模式: - [MenuComponent](src/main/java/com/steve/designpattern/composite/MenuComponent.java) - 抽象组件类 - [Menu](src/main/java/com/steve/designpattern/composite/Menu.java) - 组合类:菜单(可以包含子菜单和菜单项) - [MenuItem](src/main/java/com/steve/designpattern/composite/MenuItem.java) - 叶子类:菜单项 - [Waitress](src/main/java/com/steve/designpattern/composite/Waitress.java) - 客户端 #### 类图结构 ```mermaid classDiagram class MenuComponent { <> +add(MenuComponent) +remove(MenuComponent) +getChild(int) MenuComponent +getName() String +getDescription() String +getPrice() double +isVegetarian() boolean +print()* } class Menu { -name: String -description: String -menuComponents: ArrayList +add(MenuComponent) +remove(MenuComponent) +getChild(int) MenuComponent +print() } class MenuItem { -name: String -description: String -vegetarian: boolean -price: double +print() } class Waitress { -allMenus: MenuComponent +printMenu() } MenuComponent <|-- Menu MenuComponent <|-- MenuItem Menu o-- MenuComponent Waitress --> MenuComponent ``` #### 组合模式总结 组合模式通过将对象组织成树形结构,使得客户端可以统一地对待单个对象和组合对象,简化了客户端代码。 **核心思想:** - 定义包含基本对象和组合对象的类层次结构 - 基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合 - 客户端统一地使用组合结构中的所有对象 **优点:** - 定义了包含基本对象和组合对象的类层次结构 - 简化了客户端代码,客户端可以一致地使用组合结构和单个对象 - 更容易增加新类型的组件 - 符合开闭原则 **缺点:** - 设计较为抽象,不容易理解 - 使设计变得更加一般化,容易增加新组件,但也使得控制组合中的组件变得困难 **应用场景:** - 想表示对象的部分-整体层次结构 - 希望用户忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象 - 文件系统(文件夹和文件) - 组织机构树 - GUI组件树 --- ### 状态模式(State Pattern) #### 模式定义 状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。 #### 项目实现 本项目使用糖果机来演示状态模式: - [State](src/main/java/com/steve/designpattern/state/State.java) - 状态接口 - [GumballMachine](src/main/java/com/steve/designpattern/state/GumballMachine.java) - 上下文类:糖果机 - [NoQuarterState](src/main/java/com/steve/designpattern/state/NoQuarterState.java) - 具体状态:没有硬币状态 - [HasQuarterState](src/main/java/com/steve/designpattern/state/HasQuarterState.java) - 具体状态:有硬币状态 - [SoldState](src/main/java/com/steve/designpattern/state/SoldState.java) - 具体状态:售出状态 - [SoldOutState](src/main/java/com/steve/designpattern/state/SoldOutState.java) - 具体状态:售罄状态 #### 类图结构 ```mermaid classDiagram class State { <> +insertQuarter(GumballMachine) +ejectQuarter(GumballMachine) +turnCrank(GumballMachine) +dispense(GumballMachine) } class GumballMachine { -state: State -count: int -noQuarterState: State -hasQuarterState: State -soldState: State -soldOutState: State +insertQuarter() +ejectQuarter() +turnCrank() +setState(State) +releaseBall() } class NoQuarterState { +insertQuarter(GumballMachine) +ejectQuarter(GumballMachine) +turnCrank(GumballMachine) +dispense(GumballMachine) } class HasQuarterState { +insertQuarter(GumballMachine) +ejectQuarter(GumballMachine) +turnCrank(GumballMachine) +dispense(GumballMachine) } class SoldState { +insertQuarter(GumballMachine) +ejectQuarter(GumballMachine) +turnCrank(GumballMachine) +dispense(GumballMachine) } class SoldOutState { +insertQuarter(GumballMachine) +ejectQuarter(GumballMachine) +turnCrank(GumballMachine) +dispense(GumballMachine) } State <|.. NoQuarterState State <|.. HasQuarterState State <|.. SoldState State <|.. SoldOutState GumballMachine --> State ``` #### 状态模式总结 状态模式将与特定状态相关的行为封装到独立的状态类中,使得状态转换更加明确,并且易于扩展新的状态。 **核心思想:** - 将每一个状态的行为封装到对应的状态类中 - 上下文将行为委托给当前状态对象 - 通过改变上下文中的状态对象来改变上下文的行为 **优点:** - 封装了状态转换规则 - 将所有与某个状态有关的行为放到一个类中 - 可以让多个环境对象共享一个状态对象 - 符合开闭原则,增加新状态无需修改已有代码 **缺点:** - 状态模式的使用会增加系统类和对象的个数 - 状态模式的结构与实现都较为复杂 **应用场景:** - 对象的行为取决于它的状态,并且必须在运行时根据状态改变行为 - 代码中包含大量与对象状态有关的条件语句 - 工作流引擎 - 游戏状态管理 **与策略模式的区别:** - **状态模式**:状态之间的切换是自动的,客户端通常不需要关心状态的切换 - **策略模式**:策略的选择通常由客户端决定,策略之间不会自动切换 --- ### 代理模式(Proxy Pattern) #### 模式定义 代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问。 #### 项目实现 本项目实现了两种代理模式: **远程代理示例:** - [GumballMachine](src/main/java/com/steve/designpattern/proxy/GumballMachine.java) - 糖果机接口 - [GumballMachineImpl](src/main/java/com/steve/designpattern/proxy/GumballMachineImpl.java) - 真实糖果机 - [GumballMachineProxy](src/main/java/com/steve/designpattern/proxy/GumballMachineProxy.java) - 糖果机代理 - [GumballMonitor](src/main/java/com/steve/designpattern/proxy/GumballMonitor.java) - 监视器 **虚拟代理示例:** - [Image](src/main/java/com/steve/designpattern/proxy/Image.java) - 图片接口 - [RealImage](src/main/java/com/steve/designpattern/proxy/RealImage.java) - 真实图片(加载耗时) - [ImageProxy](src/main/java/com/steve/designpattern/proxy/ImageProxy.java) - 图片代理(延迟加载) #### 类图结构 ```mermaid classDiagram class Image { <> +display() } class RealImage { -filename: String +RealImage(String) -loadFromDisk() +display() } class ImageProxy { -filename: String -realImage: RealImage +ImageProxy(String) +display() } class GumballMachine { <> +insertQuarter() +ejectQuarter() +turnCrank() +getLocation() String +getCount() int } class GumballMachineImpl { -location: String -count: int +insertQuarter() +ejectQuarter() +turnCrank() } class GumballMachineProxy { -gumballMachine: GumballMachine +insertQuarter() +ejectQuarter() +turnCrank() +getLocation() String +getCount() int } Image <|.. RealImage Image <|.. ImageProxy ImageProxy --> RealImage GumballMachine <|.. GumballMachineImpl GumballMachine <|.. GumballMachineProxy GumballMachineProxy --> GumballMachine ``` #### 代理模式总结 代理模式通过创建代理对象来控制对真实对象的访问,可以在访问对象时添加额外的功能,如延迟加载、访问控制、日志记录等。 **代理模式的类型:** 1. **远程代理(Remote Proxy)**:为远程对象提供本地代表 2. **虚拟代理(Virtual Proxy)**:延迟创建开销很大的对象 3. **保护代理(Protection Proxy)**:控制对原始对象的访问权限 4. **智能引用代理(Smart Reference)**:在访问对象时执行额外操作 **核心思想:** - 代理对象持有真实对象的引用 - 代理对象与真实对象实现相同的接口 - 客户端通过代理对象来访问真实对象 - 代理可以在调用真实对象前后添加额外的操作 **优点:** - 代理模式能够协调调用者和被调用者,降低了系统的耦合度 - 可以灵活地控制对真实对象的访问 - 可以在不修改真实对象的情况下增加新功能 **缺点:** - 由于在客户端和真实对象之间增加了代理对象,可能会降低请求的处理速度 - 实现代理模式需要额外的工作,有些代理模式的实现比较复杂 **应用场景:** - 延迟加载(虚拟代理):只有在真正需要时才创建对象 - 访问控制(保护代理):控制对敏感对象的访问权限 - 远程代理:访问远程对象(如RMI、Web Service) - 智能引用:访问对象时执行额外操作(如引用计数、日志记录) - 缓存代理:为开销大的操作结果提供缓存 **示例运行结果:** ``` === 初始状态 === Gumball Machine: Beijing Current inventory: 5 gumballs Current state: NoQuarterState === 投入硬币并转动曲柄 === You inserted a quarter You turned the crank A gumball comes rolling out the slot === 虚拟代理示例 === 第一次显示图片1(需要加载): [Virtual Proxy] Creating real image object... Loading image from disk: photo1.jpg Displaying image: photo1.jpg 第二次显示图片1(使用缓存): [Virtual Proxy] Using cached image Displaying image: photo1.jpg ``` ### 桥接模式(Bridge Pattern) #### 模式定义 桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。通过组合关系代替继承关系,将两个独立变化的维度分离开来。 #### 项目实现 本项目使用遥控器控制电视的示例来演示桥接模式: - [TV](src/main/java/com/steve/designpattern/bridge/TV.java) - 电视接口(实现部分) - [SonyTV](src/main/java/com/steve/designpattern/bridge/SonyTV.java) 和 [SamsungTV](src/main/java/com/steve/designpattern/bridge/SamsungTV.java) - 具体电视实现 - [RemoteControl](src/main/java/com/steve/designpattern/bridge/RemoteControl.java) - 遥控器抽象类(抽象部分) - [ConcreteRemote](src/main/java/com/steve/designpattern/bridge/ConcreteRemote.java) 和 [AdvancedRemote](src/main/java/com/steve/designpattern/bridge/AdvancedRemote.java) - 具体遥控器实现 #### 类图结构 ```mermaid classDiagram class RemoteControl { <> #TV tv +on() +off() +setChannel(int) +setVolume(int) } class ConcreteRemote { +on() +off() +setChannel(int) +setVolume(int) } class AdvancedRemote { +on() +off() +setChannel(int) +setVolume(int) +mute() } class TV { <> +on() +off() +setChannel(int) +setVolume(int) } class SonyTV class SamsungTV RemoteControl <|-- ConcreteRemote RemoteControl <|-- AdvancedRemote RemoteControl --> TV TV <|.. SonyTV TV <|.. SamsungTV ``` #### 桥接模式总结 桥接模式通过将抽象与实现分离,使两者可以独立变化。在本例中,遥控器(抽象)和电视(实现)可以独立扩展。 **核心思想:** - 抽象与实现分离:将类的抽象部分和实现部分分离开 - 组合优于继承:使用组合关系代替继承关系 - 两个独立维度:抽象和实现可以独立变化 **优点:** 1. 分离抽象和实现:两者可以独立扩展 2. 提高可扩展性:新增抽象或实现都很方便 3. 实现细节对客户透明:客户只需关心抽象接口 **缺点:** 1. 增加系统的理解和设计难度 2. 需要正确识别出系统中两个独立变化的维度 **应用场景:** - 系统需要在抽象化和具体化之间增加更多的灵活性 - 一个类存在两个或多个独立变化的维度 - 不希望使用继承导致系统类的个数急剧增加 ### 建造者模式(Builder Pattern) #### 模式定义 建造者模式是一种创建型设计模式,它将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 #### 项目实现 本项目使用房屋建造的示例来演示建造者模式: - [House](src/main/java/com/steve/designpattern/builder/House.java) - 复杂产品类 - [HouseBuilder](src/main/java/com/steve/designpattern/builder/HouseBuilder.java) - 建造者接口 - [WoodenHouseBuilder](src/main/java/com/steve/designpattern/builder/WoodenHouseBuilder.java) 和 [StoneHouseBuilder](src/main/java/com/steve/designpattern/builder/StoneHouseBuilder.java) - 具体建造者 - [ConstructionEngineer](src/main/java/com/steve/designpattern/builder/ConstructionEngineer.java) - 指挥者类 #### 类图结构 ```mermaid classDiagram class House { -String foundation -String walls -String roof -String interior +setFoundation(String) +setWalls(String) +setRoof(String) +setInterior(String) } class HouseBuilder { <> +buildFoundation() +buildWalls() +buildRoof() +buildInterior() +getResult() House } class WoodenHouseBuilder { -House house +buildFoundation() +buildWalls() +buildRoof() +buildInterior() +getResult() House } class StoneHouseBuilder { -House house +buildFoundation() +buildWalls() +buildRoof() +buildInterior() +getResult() House } class ConstructionEngineer { -HouseBuilder builder +construct() House } HouseBuilder <|.. WoodenHouseBuilder HouseBuilder <|.. StoneHouseBuilder WoodenHouseBuilder --> House StoneHouseBuilder --> House ConstructionEngineer --> HouseBuilder ``` #### 建造者模式总结 建造者模式将复杂对象的构建过程封装起来,通过指挥者控制构建顺序,使得相同的构建过程可以创建不同的产品表示。 **核心思想:** - 分步骤构建复杂对象 - 将构建过程和表示分离 - 同样的构建过程可以创建不同的表示 **优点:** 1. 封装性好:客户端不需要知道产品内部组成细节 2. 建造者独立,易扩展:可以方便地增加新的具体建造者 3. 便于控制细节风险:可以对建造过程逐步细化 **缺点:** 1. 产品必须有共同点,范围有限制 2. 如果产品内部变化复杂,会有很多建造类 **应用场景:** - 需要生成的对象具有复杂的内部结构 - 需要生成的对象内部属性相互依赖 - 对象的创建过程独立于创建该对象的类 ### 责任链模式(Chain of Responsibility Pattern) #### 模式定义 责任链模式为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。 #### 项目实现 本项目使用请假审批流程的示例来演示责任链模式: - [Approver](src/main/java/com/steve/designpattern/chainofresponsibility/Approver.java) - 抽象审批者 - [TeamLeaderApprover](src/main/java/com/steve/designpattern/chainofresponsibility/TeamLeaderApprover.java) - 组长审批者(处理<=1天) - [ManagerApprover](src/main/java/com/steve/designpattern/chainofresponsibility/ManagerApprover.java) - 经理审批者(处理< =3天) - [DirectorApprover](src/main/java/com/steve/designpattern/chainofresponsibility/DirectorApprover.java) - 总监审批者(处理>3天) - [LeaveRequest](src/main/java/com/steve/designpattern/chainofresponsibility/LeaveRequest.java) - 请假请求 #### 类图结构 ```mermaid classDiagram class Approver { <> #Approver next +setNext(Approver) Approver +approve(LeaveRequest) #canHandle(LeaveRequest) boolean #doApprove(LeaveRequest) #onUnhandled(LeaveRequest) } class TeamLeaderApprover { +canHandle(LeaveRequest) boolean +doApprove(LeaveRequest) } class ManagerApprover { +canHandle(LeaveRequest) boolean +doApprove(LeaveRequest) } class DirectorApprover { +canHandle(LeaveRequest) boolean +doApprove(LeaveRequest) } class LeaveRequest { -String name -int days -String reason } Approver <|-- TeamLeaderApprover Approver <|-- ManagerApprover Approver <|-- DirectorApprover Approver --> Approver : next Approver ..> LeaveRequest ``` #### 责任链模式总结 责任链模式通过建立一条链来组织请求的处理者,请求沿着链进行传递,直到有对象处理它为止。 **核心思想:** - 解耦请求发送者和接收者 - 多个对象都有机会处理请求 - 请求沿着链传递,直到被处理 **优点:** 1. 降低耦合度:请求发送者不需要知道链的结构 2. 简化对象:对象不需要知道链的结构 3. 增强灵活性:可以动态地增加或删除处理者 4. 增强职责分配的灵活性:可以动态改变链内的成员或调动次序 **缺点:** 1. 请求可能不被处理:如果链配置不当 2. 性能问题:可能需要遍历整条链 3. 调试困难:观察运行时的特征比较困难 **应用场景:** - 有多个对象可以处理同一个请求 - 处理者不明确时,可以动态指定 - 需要在不明确指定接收者的情况下向多个对象中的一个提交请求 - 审批流程、日志处理、异常处理等场景 ### 享元模式(Flyweight Pattern) #### 模式定义 享元模式是一种结构型设计模式,它通过共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。 #### 项目实现 本项目使用游戏森林渲染的示例来演示享元模式: - [TreeType](src/main/java/com/steve/designpattern/flyweight/TreeType.java) - 享元类(内在状态:树的类型、颜色、纹理) - [TreeFactory](src/main/java/com/steve/designpattern/flyweight/TreeFactory.java) - 享元工厂 - [Tree](src/main/java/com/steve/designpattern/flyweight/Tree.java) - 树类(外在状态:坐标位置) - [Forest](src/main/java/com/steve/designpattern/flyweight/Forest.java) - 森林类(管理所有树) #### 类图结构 ```mermaid classDiagram class TreeType { -String name -String color -String texture +draw(int x, int y) } class TreeFactory { -Map~String, TreeType~ treeTypes +getTreeType(String, String, String) TreeType +getTreeTypeCount() int } class Tree { -int x -int y -TreeType type +draw() } class Forest { -List~Tree~ trees +plantTree(int, int, String, String, String) +draw() +getTreeCount() int } TreeFactory --> TreeType : creates Tree --> TreeType : uses Forest --> Tree : manages Forest --> TreeFactory : uses ``` #### 享元模式总结 享元模式通过共享技术实现相同或相似对象的重用,将对象的状态分为内在状态和外在状态,内在状态可以共享,外在状态由外部设置。 **核心思想:** - 共享对象,减少内存使用 - 内在状态(Intrinsic State):可以共享的状态,存储在享元对象内部 - 外在状态(Extrinsic State):不可共享的状态,由外部传入 **优点:** 1. 大幅减少对象创建,降低内存占用 2. 提高程序性能 3. 外部状态独立,不影响内部状态 **缺点:** 1. 增加系统复杂度 2. 需要分离内部状态和外部状态 3. 读取外部状态会使运行时间变长 **应用场景:** - 系统中存在大量相似对象 - 需要缓冲池的场景 - 对象的大部分状态可以外部化 - 字符串常量池、数据库连接池、线程池等 **示例输出:** ``` === Planting Oak Trees === Creating new TreeType: Oak_Green_Rough === Planting Pine Trees === Creating new TreeType: Pine_Dark Green_Smooth Reusing existing TreeType: Pine_Dark Green_Smooth Reusing existing TreeType: Pine_Dark Green_Smooth === Summary === We planted 10 trees But only created 3 tree type objects Memory saved: avoided creating 7 duplicate tree type objects ``` ### 解释器模式(Interpreter Pattern) #### 模式定义 解释器模式是一种行为型设计模式,它给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 #### 项目实现 本项目使用布尔表达式解释器的示例来演示解释器模式: - [Expression](src/main/java/com/steve/designpattern/interpreter/Expression.java) - 抽象表达式接口 - [TerminalExpression](src/main/java/com/steve/designpattern/interpreter/TerminalExpression.java) - 终结符表达式 - [AndExpression](src/main/java/com/steve/designpattern/interpreter/AndExpression.java) - 与表达式 - [OrExpression](src/main/java/com/steve/designpattern/interpreter/OrExpression.java) - 或表达式 - [NotExpression](src/main/java/com/steve/designpattern/interpreter/NotExpression.java) - 非表达式 #### 类图结构 ```mermaid classDiagram class Expression { <> +interpret(String context) boolean } class TerminalExpression { -String data +interpret(String context) boolean } class AndExpression { -Expression expr1 -Expression expr2 +interpret(String context) boolean } class OrExpression { -Expression expr1 -Expression expr2 +interpret(String context) boolean } class NotExpression { -Expression expr +interpret(String context) boolean } Expression <|.. TerminalExpression Expression <|.. AndExpression Expression <|.. OrExpression Expression <|.. NotExpression AndExpression --> Expression OrExpression --> Expression NotExpression --> Expression ``` #### 解释器模式总结 解释器模式为简单语言定义文法表示,并提供解释器来处理该语言中的句子。 **核心思想:** - 为语言定义文法规则 - 使用类来表示文法规则 - 通过解释器解释语言中的句子 **优点:** 1. 易于改变和扩展文法 2. 易于实现文法 3. 增加新的解释表达式较为方便 **缺点:** 1. 对于复杂文法难以维护 2. 执行效率较低 3. 会引起类膨胀 **应用场景:** - 有一个简单的语法规则 - 一些重复出现的问题可以用简单的语言来表达 - SQL解析、符号处理引擎、正则表达式等 **示例输出:** ``` ===== 解释器模式示例 ===== === 测试男性规则 === John 是男性? true Robert 是男性? true Julie 是男性? false === 测试已婚女性规则 === Julie Married 满足条件? true Julie 满足条件? false Married 满足条件? false === 复杂规则测试 === Tom 不是 Tom? false Jerry 不是 Tom? true === 组合规则: (Robert 或 John) 且不是 Tom === Robert 满足条件? true John 满足条件? true Tom 满足条件? false ``` ### 中介者模式(Mediator Pattern) #### 模式定义 中介者模式是一种行为型设计模式,它用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 #### 项目实现 本项目使用聊天室的示例来演示中介者模式: - [Mediator](src/main/java/com/steve/designpattern/mediator/Mediator.java) - 中介者接口 - [ChatRoom](src/main/java/com/steve/designpattern/mediator/ChatRoom.java) - 具体中介者(聊天室) - [Colleague](src/main/java/com/steve/designpattern/mediator/Colleague.java) - 抽象同事类 - [User](src/main/java/com/steve/designpattern/mediator/User.java) - 具体同事类(用户) #### 类图结构 ```mermaid classDiagram class Mediator { <> +addColleague(Colleague) +sendMessage(String, Colleague) } class ChatRoom { -List~Colleague~ colleagues +addColleague(Colleague) +sendMessage(String, Colleague) } class Colleague { <> #Mediator mediator #String name +send(String) +receive(String) } class User { +send(String) +receive(String) } Mediator <|.. ChatRoom Colleague <|-- User Colleague --> Mediator ChatRoom --> Colleague : manages ``` #### 中介者模式总结 中介者模式通过引入中介者对象,将多对多的网状关系转变为一对多的星型关系,降低了系统的耦合度。 **核心思想:** - 用中介对象封装对象间的交互 - 各对象不需要显式地相互引用 - 将多对多关系转化为一对多关系 **优点:** 1. 降低类的复杂度:将一对多转化为一对一 2. 解耦各同事类:同事类之间不需要相互引用 3. 符合迪米特法则:减少类间依赖 4. 便于维护:集中控制交互逻辑 **缺点:** 1. 中介者会变得复杂:承担了过多的责任 2. 中介者可能成为性能瓶颈 **应用场景:** - 系统中对象之间存在复杂的引用关系 - 一组对象需要通信,但交互方式复杂难以理解 - 想通过一个中间类来封装多个类的行为 - 聊天室、航空管制系统、MVC框架中的Controller等 **示例输出:** ``` ===== Chat Room Demo ===== [Alice] sends: Hello everyone! [Bob] receives: Hello everyone! [Charlie] receives: Hello everyone! [David] receives: Hello everyone! [Bob] sends: Hi Alice! [Alice] receives: Hi Alice! [Charlie] receives: Hi Alice! [David] receives: Hi Alice! ``` ## 项目信息 ### 运行环境 - Java 21 - Maven ### 如何运行 1. 克隆项目到本地 2. 使用IDE导入Maven项目 3. 运行各个模式中的 Main 类来查看效果 **设计模式示例:** - [Strategy Main](src/main/java/com/steve/designpattern/strategy/Main.java) - 策略模式演示 - [Observer Push Main](src/main/java/com/steve/designpattern/observer/push/Main.java) - 观察者模式(推送) - [Observer Pull Main](src/main/java/com/steve/designpattern/observer/pull/Main.java) - 观察者模式(拉取) - [Decorator Main](src/main/java/com/steve/designpattern/decorator/Main.java) - 装饰器模式演示 - [Factory Main](src/main/java/com/steve/designpattern/factory/Main.java) - 工厂方法模式演示 - [Singleton Main](src/main/java/com/steve/designpattern/singleton/Main.java) - 单例模式演示 - [Abstract Factory Main](src/main/java/com/steve/designpattern/abstactfactory/Main.java) - 抽象工厂模式演示 - [Command Main](src/main/java/com/steve/designpattern/command/Main.java) - 命令模式演示(智能家居遥控器) - [Adapter Main](src/main/java/com/steve/designpattern/adapter/Main.java) - 适配器模式演示(鸭子和火鸡) - [Facade Main](src/main/java/com/steve/designpattern/facade/Main.java) - 外观模式演示(家庭影院系统) - [Template Method Main](src/main/java/com/steve/designpattern/templatemethod/Main.java) - 模板方法模式演示(饮料制作) - [Template Method with Hook Main](src/main/java/com/steve/designpattern/templatemethodwithhook/Main.java) - 模板方法钩子模式演示(游戏流程) - [Iterator Main](src/main/java/com/steve/designpattern/iterator/Main.java) - 迭代器模式演示(餐厅菜单遍历) - [Composite Main](src/main/java/com/steve/designpattern/composite/Main.java) - 组合模式演示(菜单树形结构) - [State Main](src/main/java/com/steve/designpattern/state/Main.java) - 状态模式演示(糖果机状态管理) - [Proxy Main](src/main/java/com/steve/designpattern/proxy/Main.java) - 代理模式演示(远程代理和虚拟代理) - [Bridge Main](src/main/java/com/steve/designpattern/bridge/Main.java) - 桥接模式演示(遥控器控制电视) - [Builder Main](src/main/java/com/steve/designpattern/builder/Main.java) - 建造者模式演示(房屋建造) - [Chain of Responsibility Main](src/main/java/com/steve/designpattern/chainofresponsibility/Main.java) - 责任链模式演示(请假审批) - [Flyweight Main](src/main/java/com/steve/designpattern/flyweight/Main.java) - 享元模式演示(森林树木渲染) - [Interpreter Main](src/main/java/com/steve/designpattern/interpreter/Main.java) - 解释器模式演示(布尔表达式解释器) - [Mediator Main](src/main/java/com/steve/designpattern/mediator/Main.java) - 中介者模式演示(聊天室) **JavaSE 示例:** - [DataType](src/main/java/com/steve/javase/base/DataType.java) - 数据类型与枚举方法演示 - [AssertTest](src/main/java/com/steve/javase/base/AssertTest.java) - 断言使用(需要VM参数 `-ea`) - [TestScanner](src/main/java/com/steve/javase/scanner/TestScanner.java) - Scanner控制台输入 - [Main](src/main/java/com/steve/javase/base/Main.java) - 运算符与instanceof演示 - [Person](src/main/java/com/steve/javase/shujujiegou/Person.java) - 类的定义示例(字段、构造器、方法) - [Flyable](src/main/java/com/steve/javase/shujujiegou/Flyable.java) - 接口定义示例(抽象方法、默认方法、静态方法) - [Point](src/main/java/com/steve/javase/shujujiegou/Point.java) - 记录类示例(不可变数据类、紧凑构造器) - [Animal & Cat](src/main/java/com/steve/javase/clone/) - 对象克隆(深拷贝与浅拷贝) - [ReflectionHeapPollution](src/main/java/com/steve/javase/fanxing/ReflectionHeapPollution.java) - 泛型堆污染演示 - [hashCodeAndEquals/Test](src/main/java/com/steve/javase/hashcodeandequals/Test.java) - hashCode与equals重写演示 - [BufferAndBuilderTest](src/main/java/com/steve/javase/stringtest/BufferAndBuilderTest.java) - String、StringBuffer、StringBuilder对比 - [ArrayTest](src/main/java/com/steve/javase/array/ArrayTest.java) - 数组与可变参数 - [ArraysTest](src/main/java/com/steve/javase/array/ArraysTest.java) - Arrays工具类使用(排序、复制、转换) - [TestException](src/main/java/com/steve/javase/exceptiontest/TestException.java) - 自定义异常示例 - [StreamTest](src/main/java/com/steve/javase/inputandoutput/StreamTest.java) - 对象序列化操作 - [Stream Main](src/main/java/com/steve/javase/streamtest/Main.java) - 字节流与字符流操作(文件复制、字符编码) - [CounterDemo](src/main/java/com/steve/javase/keywordlearning/CounterDemo.java) - volatile、synchronized、AtomicInteger对比 - [MyClass](src/main/java/com/steve/javase/objecttest/MyClass.java) - hashCode与equals重写、对象克隆 ### 后续学习计划 **设计模式:** - [x] 策略模式 ✅ - [x] 观察者模式 ✅ - [x] 装饰器模式 ✅ - [x] 工厂方法模式 ✅ - [x] 单例模式 ✅ - [x] 抽象工厂模式 ✅ - [x] 命令模式 ✅ - [x] 适配器模式 ✅ - [x] 外观模式 ✅ - [x] 模板方法模式 ✅ - [x] 迭代器模式 ✅ - [x] 组合模式 ✅ - [x] 状态模式 ✅ - [x] 代理模式 ✅ - [x] 桥接模式 ✅ - [x] 建造者模式 ✅ - [x] 责任链模式 ✅ - [x] 享元模式 ✅ - [x] 解释器模式 ✅ - [x] 中介者模式 ✅ **JavaSE 学习计划:** - [x] 类型定义结构(类、接口、枚举、记录类)✅ - [x] 基础语法(数据类型、运算符、断言)✅ - [x] 控制台输入(Scanner)✅ - [x] 对象克隆(深拷贝与浅拷贝)✅ - [x] 泛型(类型擦除、堆污染)✅ - [x] hashCode 与 equals 重写规则 ✅ - [x] String、StringBuffer 与 StringBuilder ✅ - [x] 数组与可变参数 ✅ - [x] 异常处理(自定义异常)✅ - [x] IO 流(字节流、字符流)✅ - [x] 关键字学习(volatile、synchronized、AtomicInteger)✅ - [ ] 集合框架(List, Set, Map) - [ ] 多线程与并发 - [ ] Lambda 表达式与 Stream API - [ ] 反射机制 - [ ] 注解 ## 学习资源 - 《Head First 设计模式》 - 《大话设计模式》