diff --git a/README.md b/README.md index 6ef4df8..cea75ef 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ Design patterns from 《大话设计模式》 and some samples implemented by C# 设计模式大体上可分为三类: +> **UML 类图**:本项目包含了所有设计模式的 UML 类图,位于 [uml](./uml) 文件夹中,使用 PlantUML 格式,可在线渲染或本地查看。 + - [创建型模式(Create)](./CreatePattern) 1. [简单工厂(SimpleFactory)](./CreatePattern/SimpleFactoryPattern) 1. [抽象工厂(AbstractFactory)](./CreatePattern/AbstractFactoryPattern) diff --git a/uml/README.md b/uml/README.md new file mode 100644 index 0000000..5bbc10b --- /dev/null +++ b/uml/README.md @@ -0,0 +1,55 @@ +# UML Diagrams for Design Patterns + +This folder contains UML diagrams for all design patterns implemented in this repository. + +## Structure + +- `creational/` - UML diagrams for creational patterns +- `structural/` - UML diagrams for structural patterns +- `behavioral/` - UML diagrams for behavioral patterns + +## Format + +All diagrams are provided in PlantUML format (.puml files) which can be rendered as images using various tools. + +## Usage + +To render these diagrams: +1. **Online**: Use online renderer at http://www.plantuml.com/plantuml/uml/ +2. **Local Installation**: Install PlantUML locally +3. **VS Code**: Install the PlantUML extension for VS Code for inline preview and rendering +4. **IDE Plugins**: Use PlantUML plugins available for IntelliJ IDEA, Eclipse, and other IDEs + +Open the .puml files and render them as PNG/SVG images + +## Patterns Included + +### Creational Patterns (6) +- Simple Factory Pattern +- Abstract Factory Pattern +- Factory Method Pattern +- Builder Pattern +- Prototype Pattern +- Singleton Pattern + +### Structural Patterns (7) +- Adapter Pattern +- Bridge Pattern +- Composite Pattern +- Decorator Pattern +- Facade Pattern +- Flyweight Pattern +- Proxy Pattern + +### Behavioral Patterns (11) +- Observer Pattern +- Template Method Pattern +- Command Pattern +- State Pattern +- Chain of Responsibility Pattern +- Interpreter Pattern +- Mediator Pattern +- Visitor Pattern +- Memento Pattern +- Iterator Pattern +- Strategy Pattern \ No newline at end of file diff --git a/uml/README.zh.md b/uml/README.zh.md new file mode 100644 index 0000000..fc1977f --- /dev/null +++ b/uml/README.zh.md @@ -0,0 +1,55 @@ +# 设计模式 UML 类图 + +本文件夹包含了本仓库中实现的所有设计模式的 UML 类图。 + +## 目录结构 + +- `creational/` - 创建型模式的 UML 类图 +- `structural/` - 结构型模式的 UML 类图 +- `behavioral/` - 行为型模式的 UML 类图 + +## 格式 + +所有类图均采用 PlantUML 格式(.puml 文件),可使用各种工具渲染为图像。 + +## 使用方法 + +渲染这些类图的方法: +1. **在线工具**:使用在线渲染器 http://www.plantuml.com/plantuml/uml/ +2. **本地安装**:本地安装 PlantUML +3. **VS Code**:安装 PlantUML 扩展,支持内联预览和渲染 +4. **IDE 插件**:使用适用于 IntelliJ IDEA、Eclipse 和其他 IDE 的 PlantUML 插件 + +打开 .puml 文件并将其渲染为 PNG/SVG 图像 + +## 包含的模式 + +### 创建型模式 (6种) +- 简单工厂模式 (Simple Factory Pattern) +- 抽象工厂模式 (Abstract Factory Pattern) +- 工厂方法模式 (Factory Method Pattern) +- 建造者模式 (Builder Pattern) +- 原型模式 (Prototype Pattern) +- 单例模式 (Singleton Pattern) + +### 结构型模式 (7种) +- 适配器模式 (Adapter Pattern) +- 桥接模式 (Bridge Pattern) +- 组合模式 (Composite Pattern) +- 装饰器模式 (Decorator Pattern) +- 外观模式 (Facade Pattern) +- 享元模式 (Flyweight Pattern) +- 代理模式 (Proxy Pattern) + +### 行为型模式 (11种) +- 观察者模式 (Observer Pattern) +- 模板方法模式 (Template Method Pattern) +- 命令模式 (Command Pattern) +- 状态模式 (State Pattern) +- 职责链模式 (Chain of Responsibility Pattern) +- 解释器模式 (Interpreter Pattern) +- 中介者模式 (Mediator Pattern) +- 访问者模式 (Visitor Pattern) +- 备忘录模式 (Memento Pattern) +- 迭代器模式 (Iterator Pattern) +- 策略模式 (Strategy Pattern) \ No newline at end of file diff --git a/uml/behavioral/chain-of-responsibility.puml b/uml/behavioral/chain-of-responsibility.puml new file mode 100644 index 0000000..16b55a9 --- /dev/null +++ b/uml/behavioral/chain-of-responsibility.puml @@ -0,0 +1,79 @@ +@startuml Chain of Responsibility Pattern +!theme plain + +title Chain of Responsibility Pattern + +abstract class Manager { + #ManagerName: string + #Superior: Manager + +Manager(managerName: string) + +SetSuperior(superior: Manager): void + +{abstract} RequestApplications(request: Request): void +} + +class CommonManager { + +CommonManager(managerName: string) + +RequestApplications(request: Request): void +} + +class Majordomo { + +Majordomo(managerName: string) + +RequestApplications(request: Request): void +} + +class GeneralManager { + +GeneralManager(managerName: string) + +RequestApplications(request: Request): void +} + +class Request { + +RequestType: string + +RequestContent: string + +RequestNum: int +} + +class Client { + +Main(): void +} + +Manager <|-- CommonManager +Manager <|-- Majordomo +Manager <|-- GeneralManager + +Manager -> Manager : successor +Manager -> Request : handles + +Client -> Manager : uses +Client -> Request : creates + +note right of Manager + Handler defines interface + for handling requests and + implements successor link +end note + +note right of CommonManager + CommonManager handles requests + for leave <= 2 days, otherwise + passes to successor +end note + +note right of Majordomo + Majordomo handles requests + for leave <= 5 days, otherwise + passes to successor +end note + +note right of GeneralManager + GeneralManager handles all + leave requests and salary + increase <= 500 +end note + +note top of Manager + Chain of Responsibility passes + request along chain of handlers + until one handles it +end note + +@enduml \ No newline at end of file diff --git a/uml/behavioral/command.puml b/uml/behavioral/command.puml new file mode 100644 index 0000000..10fd4ab --- /dev/null +++ b/uml/behavioral/command.puml @@ -0,0 +1,95 @@ +@startuml Command Pattern +!theme plain + +title Command Pattern + +abstract class Command { + #Receiver: Receiver + +Command(receiver: Receiver) + +{abstract} Execute(): void +} + +class ConcreteCommand { + +ConcreteCommand(receiver: Receiver) + +Execute(): void +} + +class Receiver { + +Action(): void +} + +class Invoker { + -command: Command + +SetCommand(command: Command): void + +ExecuteCommand(): void +} + +abstract class OrderCommand { + #Receiver: Barbecuer + +OrderCommand(receiver: Barbecuer) + +{abstract} ExecuteCommand(): void +} + +class BakeMuttonCommand { + +BakeMuttonCommand(receiver: Barbecuer) + +ExecuteCommand(): void + +ToString(): string +} + +class BakeChickenWingCommand { + +BakeChickenWingCommand(receiver: Barbecuer) + +ExecuteCommand(): void + +ToString(): string +} + +class Barbecuer { + +BakeMutton(): void + +BakeChickenWing(): void +} + +class Waiter { + -orders: ICollection + +SetOrder(order: OrderCommand): void + +CancelOrder(order: OrderCommand): void + +Notify(): void +} + +class Client { + +Main(): void +} + +Command <|-- ConcreteCommand +Command -> Receiver +Invoker -> Command + +OrderCommand <|-- BakeMuttonCommand +OrderCommand <|-- BakeChickenWingCommand +OrderCommand -> Barbecuer +Waiter *-- OrderCommand + +Client -> Invoker : uses +Client -> Waiter : uses + +note right of Command + Command declares interface + for executing an operation +end note + +note right of ConcreteCommand + ConcreteCommand defines binding + between Receiver object and action. + Implements Execute by invoking + corresponding operations on Receiver +end note + +note right of Invoker + Invoker asks command to + carry out the request +end note + +note right of Waiter + Waiter manages multiple orders + and can execute them in batch +end note + +@enduml \ No newline at end of file diff --git a/uml/behavioral/interpreter.puml b/uml/behavioral/interpreter.puml new file mode 100644 index 0000000..7f84e79 --- /dev/null +++ b/uml/behavioral/interpreter.puml @@ -0,0 +1,88 @@ +@startuml Interpreter Pattern +!theme plain + +title Interpreter Pattern + +class Context { + +Input: string + +Output: string +} + +abstract class AbstractExpression { + +{abstract} Interpret(context: Context): void +} + +class TerminalExpression { + +Interpret(context: Context): void +} + +class NoneTerminalExpression { + +Interpret(context: Context): void +} + +class PlayContext { + +PlayText: string +} + +abstract class MusicalExpression { + +Interpret(context: PlayContext): void + +{abstract} Execute(key: string, value: double): void +} + +class MusicalNote { + +Execute(key: string, value: double): void +} + +class MusicalScale { + +Execute(key: string, value: double): void +} + +class MusicalSpeed { + +Execute(key: string, value: double): void +} + +class Client { + +Main(): void +} + +AbstractExpression <|-- TerminalExpression +AbstractExpression <|-- NoneTerminalExpression +AbstractExpression -> Context : interprets + +MusicalExpression <|-- MusicalNote +MusicalExpression <|-- MusicalScale +MusicalExpression <|-- MusicalSpeed +MusicalExpression -> PlayContext : interprets + +Client -> AbstractExpression : uses +Client -> MusicalExpression : uses +Client -> Context : uses +Client -> PlayContext : uses + +note right of AbstractExpression + AbstractExpression declares + abstract Interpret operation + that is common to all nodes + in abstract syntax tree +end note + +note right of TerminalExpression + TerminalExpression implements + Interpret operation for + terminal symbols in grammar +end note + +note right of MusicalExpression + Concrete example: interprets + musical notation including + notes, scales, and speeds +end note + +note top of AbstractExpression + Interpreter pattern defines + representation for grammar + and interpreter to interpret + sentences in the language +end note + +@enduml \ No newline at end of file diff --git a/uml/behavioral/iterator.puml b/uml/behavioral/iterator.puml new file mode 100644 index 0000000..e284f9d --- /dev/null +++ b/uml/behavioral/iterator.puml @@ -0,0 +1,83 @@ +@startuml Iterator Pattern +!theme plain + +title Iterator Pattern + +abstract class Iterator { + +{abstract} First(): object + +{abstract} Next(): object + +{abstract} IsDone(): bool + +{abstract} CurrentItem(): object +} + +class ConcreteIterator { + -aggregate: ConcreteAggregate + -current: int + +ConcreteIterator(aggregate: ConcreteAggregate) + +First(): object + +Next(): object + +IsDone(): bool + +CurrentItem(): object +} + +class ConcreteIteratorDesc { + -aggregate: ConcreteAggregate + -current: int + +ConcreteIteratorDesc(aggregate: ConcreteAggregate) + +First(): object + +Next(): object + +IsDone(): bool + +CurrentItem(): object +} + +abstract class Aggregate { + +{abstract} CreateIterator(): Iterator +} + +class ConcreteAggregate { + -items: IList + +CreateIterator(): Iterator + +TotalCount: int + +this[index: int]: object +} + +class Client { + +Main(): void +} + +Iterator <|-- ConcreteIterator +Iterator <|-- ConcreteIteratorDesc +Aggregate <|-- ConcreteAggregate + +ConcreteIterator -> ConcreteAggregate : traverses +ConcreteIteratorDesc -> ConcreteAggregate : traverses +ConcreteAggregate ..> ConcreteIterator : creates + +Client -> Aggregate : uses +Client -> Iterator : uses + +note right of Iterator + Iterator defines interface + for accessing and traversing + elements +end note + +note right of ConcreteIterator + ConcreteIterator implements + Iterator interface and keeps + track of current position +end note + +note right of Aggregate + Aggregate defines interface + for creating Iterator object +end note + +note right of ConcreteAggregate + ConcreteAggregate implements + Iterator creation interface + and returns appropriate + ConcreteIterator instance +end note + +@enduml \ No newline at end of file diff --git a/uml/behavioral/mediator.puml b/uml/behavioral/mediator.puml new file mode 100644 index 0000000..9de8f2b --- /dev/null +++ b/uml/behavioral/mediator.puml @@ -0,0 +1,74 @@ +@startuml Mediator Pattern +!theme plain + +title Mediator Pattern + +abstract class Mediator { + +{abstract} Send(message: string, colleague: Colleague): void +} + +class ConcreteMediator { + +Colleague1: Colleague + +Colleague2: Colleague + +Send(message: string, colleague: Colleague): void +} + +abstract class Colleague { + #Mediator: Mediator + +Colleague(mediator: Mediator) + +{abstract} Notify(message: string): void +} + +class ConcreteColleague1 { + +ConcreteColleague1(mediator: Mediator) + +Send(message: string): void + +Notify(message: string): void +} + +class ConcreteColleague2 { + +ConcreteColleague2(mediator: Mediator) + +Send(message: string): void + +Notify(message: string): void +} + +class Client { + +Main(): void +} + +Mediator <|-- ConcreteMediator +Colleague <|-- ConcreteColleague1 +Colleague <|-- ConcreteColleague2 + +ConcreteMediator -> Colleague : manages +Colleague -> Mediator : communicates through + +Client -> Mediator : uses +Client -> Colleague : uses + +note right of Mediator + Mediator defines interface + for communication between + Colleague components +end note + +note right of ConcreteMediator + ConcreteMediator implements + cooperative behavior by + coordinating Colleague objects +end note + +note right of Colleague + Colleague classes communicate + with each other through + Mediator instead of directly +end note + +note top of ConcreteMediator + Mediator pattern defines how + set of objects interact. + Promotes loose coupling by keeping + objects from referring to + each other explicitly +end note + +@enduml \ No newline at end of file diff --git a/uml/behavioral/memento.puml b/uml/behavioral/memento.puml new file mode 100644 index 0000000..ccf3c1c --- /dev/null +++ b/uml/behavioral/memento.puml @@ -0,0 +1,67 @@ +@startuml Memento Pattern +!theme plain + +title Memento Pattern + +class GameRole { + +Vitality: int + +Attack: int + +Defense: int + +GameRole() + +StateDisplay(): void + +FightWithBoss(): void + +SaveState(): RoleStateMemento + +RecoveryState(memento: RoleStateMemento): void +} + +class RoleStateMemento { + +Vitality: int + +Attack: int + +Defense: int + +RoleStateMemento(vitality: int, attack: int, defense: int) +} + +class RoleStateCaretaker { + +Memento: RoleStateMemento +} + +class Client { + +Main(): void +} + +GameRole ..> RoleStateMemento : creates +GameRole -> RoleStateMemento : uses +RoleStateCaretaker -> RoleStateMemento : stores + +Client -> GameRole : uses +Client -> RoleStateCaretaker : uses + +note right of GameRole + Originator creates memento + containing snapshot of its + current internal state and + uses memento to restore state +end note + +note right of RoleStateMemento + Memento stores internal state + of Originator object. Protects + against access by objects + other than the originator +end note + +note right of RoleStateCaretaker + Caretaker is responsible for + memento's safekeeping but + never operates on or examins + contents of memento +end note + +note top of GameRole + Memento pattern captures and + externalizes object's internal + state so it can be restored later + without violating encapsulation +end note + +@enduml \ No newline at end of file diff --git a/uml/behavioral/observer.puml b/uml/behavioral/observer.puml new file mode 100644 index 0000000..f220954 --- /dev/null +++ b/uml/behavioral/observer.puml @@ -0,0 +1,89 @@ +@startuml Observer Pattern +!theme plain + +title Observer Pattern + +interface ISubject { + +Notify(): void + +SubjectState: string +} + +class Boss { + -observers: IList + +Attach(observer: Observer): void + +Detach(observer: Observer): void + +Notify(): void + +SubjectState: string +} + +class NewBoss { + +Update: event Action + +Notify(): void + +SubjectState: string +} + +abstract class Observer { + #Name: string + #Subject: ISubject + +Observer(name: string, subject: ISubject) + +{abstract} Update(): void +} + +class StockObserver { + +StockObserver(name: string, subject: ISubject) + +Update(): void +} + +class NBAObserver { + +NBAObserver(name: string, subject: ISubject) + +Update(): void +} + +class GamePlayerObserver { + -name: string + -subject: ISubject + +GamePlayerObserver(name: string, subject: ISubject) + +CloseGame(): void +} + +class Client { + +Main(): void +} + +ISubject <|-- Boss +ISubject <|-- NewBoss + +Observer <|-- StockObserver +Observer <|-- NBAObserver + +Observer -> ISubject : observes +Boss *-- Observer +NewBoss -> GamePlayerObserver : notifies + +Client -> ISubject : uses +Client -> Observer : uses + +note right of ISubject + Subject interface defines + methods for attaching/detaching + observers and notifying them +end note + +note right of Observer + Observer interface defines + update method to be called + when subject changes +end note + +note right of Boss + Concrete subject maintains + list of observers and + notifies them of changes +end note + +note right of NewBoss + Uses C# events for + observer notification +end note + +@enduml \ No newline at end of file diff --git a/uml/behavioral/state.puml b/uml/behavioral/state.puml new file mode 100644 index 0000000..bc201c9 --- /dev/null +++ b/uml/behavioral/state.puml @@ -0,0 +1,82 @@ +@startuml State Pattern +!theme plain + +title State Pattern + +class Work { + -currentState: WorkState + +Hour: int + +TaskFinished: bool + +Work() + +SetState(workState: WorkState): void + +WriteProgram(): void +} + +abstract class WorkState { + +{abstract} WriteProgram(work: Work): void +} + +class ForenoonState { + +WriteProgram(work: Work): void +} + +class NoonState { + +WriteProgram(work: Work): void +} + +class AfternoonState { + +WriteProgram(work: Work): void +} + +class EveningState { + +WriteProgram(work: Work): void +} + +class RestState { + +WriteProgram(work: Work): void +} + +class SleepingState { + +WriteProgram(work: Work): void +} + +class Client { + +Main(): void +} + +Work -> WorkState : current state +WorkState <|-- ForenoonState +WorkState <|-- NoonState +WorkState <|-- AfternoonState +WorkState <|-- EveningState +WorkState <|-- RestState +WorkState <|-- SleepingState + +ForenoonState ..> NoonState : transitions to +NoonState ..> AfternoonState : transitions to +AfternoonState ..> EveningState : transitions to +EveningState ..> RestState : transitions to +EveningState ..> SleepingState : transitions to + +Client -> Work : uses + +note right of Work + Context maintains reference + to current state and delegates + state-specific behavior to it +end note + +note right of WorkState + State defines interface for + encapsulating behavior associated + with particular state of Context +end note + +note bottom of ForenoonState + Concrete states implement + behavior associated with + state of Context and handle + state transitions +end note + +@enduml \ No newline at end of file diff --git a/uml/behavioral/strategy.puml b/uml/behavioral/strategy.puml new file mode 100644 index 0000000..2d80c3b --- /dev/null +++ b/uml/behavioral/strategy.puml @@ -0,0 +1,91 @@ +@startuml Strategy Pattern +!theme plain + +title Strategy Pattern + +class Context { + -strategy: Strategy + +Context(strategy: Strategy) + +Implement(): void +} + +abstract class Strategy { + +{abstract} AlgorithmImplement(): void +} + +class ConcreteStrategyA { + +AlgorithmImplement(): void +} + +class ConcreteStrategyB { + +AlgorithmImplement(): void +} + +class ConcreteStrategyC { + +AlgorithmImplement(): void +} + +abstract class AbstractCash { + +{abstract} AcceptCash(money: double): double +} + +class CashNormal { + +AcceptCash(money: double): double +} + +class CashRebate { + -rebate: double + +CashRebate(rebate: double) + +AcceptCash(money: double): double +} + +class CashReturn { + -condition: double + -return: double + +CashReturn(condition: double, mReturn: double) + +AcceptCash(money: double): double +} + +class CashContext { + -cash: AbstractCash + +StrategyType: string + +CashContext(type: string) + +GetResult(money: double): double +} + +class Client { + +Main(): void +} + +Strategy <|-- ConcreteStrategyA +Strategy <|-- ConcreteStrategyB +Strategy <|-- ConcreteStrategyC +Context -> Strategy + +AbstractCash <|-- CashNormal +AbstractCash <|-- CashRebate +AbstractCash <|-- CashReturn +CashContext -> AbstractCash + +Client -> Context : uses +Client -> CashContext : uses + +note right of Strategy + Strategy defines interface + common to all concrete + strategy algorithms +end note + +note right of Context + Context maintains reference + to Strategy object and + delegates algorithm to it +end note + +note right of CashContext + Context combines strategy + selection with factory pattern + for cash calculation strategies +end note + +@enduml \ No newline at end of file diff --git a/uml/behavioral/template-method.puml b/uml/behavioral/template-method.puml new file mode 100644 index 0000000..c311b67 --- /dev/null +++ b/uml/behavioral/template-method.puml @@ -0,0 +1,67 @@ +@startuml Template Method Pattern +!theme plain + +title Template Method Pattern + +class TestPaper { + #StudentName: string + +TestResult(): void + -TestQuestion1(): void + -TestQuestion2(): void + -TestQuestion3(): void + #Answer1(): string + #Answer2(): string + #Answer3(): string +} + +class TestPaperA { + +TestPaperA() + #Answer1(): string + #Answer2(): string + #Answer3(): string +} + +class TestPaperB { + +TestPaperB() + #Answer1(): string + #Answer2(): string + #Answer3(): string +} + +class Client { + +Main(): void +} + +TestPaper <|-- TestPaperA +TestPaper <|-- TestPaperB + +Client -> TestPaper : uses + +note right of TestPaper + Template method TestResult() + defines skeleton of algorithm. + Subclasses override specific + steps (Answer methods) +end note + +note bottom of TestPaperA + Concrete class provides + specific implementation + for student "路人甲" +end note + +note bottom of TestPaperB + Concrete class provides + specific implementation + for student "吃泡面乙" +end note + +note top of TestPaper + Template Method pattern defines + skeleton of an algorithm in base + class, letting subclasses override + specific steps without changing + the algorithm's structure +end note + +@enduml \ No newline at end of file diff --git a/uml/behavioral/visitor.puml b/uml/behavioral/visitor.puml new file mode 100644 index 0000000..12e36da --- /dev/null +++ b/uml/behavioral/visitor.puml @@ -0,0 +1,89 @@ +@startuml Visitor Pattern +!theme plain + +title Visitor Pattern + +abstract class AbstractAction { + +{abstract} GetManConclusion(man: Man): void + +{abstract} GetWomanConclusion(woman: Woman): void +} + +class Success { + +GetManConclusion(man: Man): void + +GetWomanConclusion(woman: Woman): void +} + +class Fail { + +GetManConclusion(man: Man): void + +GetWomanConclusion(woman: Woman): void +} + +class Marriage { + +GetManConclusion(man: Man): void + +GetWomanConclusion(woman: Woman): void +} + +abstract class Person { + +{abstract} Accept(visitor: AbstractAction): void +} + +class Man { + +Accept(visitor: AbstractAction): void +} + +class Woman { + +Accept(visitor: AbstractAction): void +} + +class PersonStructure { + -persons: IList + +Attach(person: Person): void + +Detach(person: Person): void + +Display(visitor: AbstractAction): void +} + +class Client { + +Main(): void +} + +AbstractAction <|-- Success +AbstractAction <|-- Fail +AbstractAction <|-- Marriage + +Person <|-- Man +Person <|-- Woman + +PersonStructure *-- Person +PersonStructure -> AbstractAction : uses +Person -> AbstractAction : accepts + +Client -> PersonStructure : uses +Client -> AbstractAction : uses + +note right of AbstractAction + Visitor declares visit operation + for each type of ConcreteElement + in object structure +end note + +note right of Person + Element defines Accept operation + that takes visitor as argument +end note + +note right of PersonStructure + ObjectStructure can enumerate + its elements and provide high-level + interface to allow visitor to + visit its elements +end note + +note top of AbstractAction + Visitor pattern represents operation + to be performed on elements of + object structure. Lets you define + new operation without changing + classes of elements on which it operates +end note + +@enduml \ No newline at end of file diff --git a/uml/creational/abstract-factory.puml b/uml/creational/abstract-factory.puml new file mode 100644 index 0000000..4d2de6d --- /dev/null +++ b/uml/creational/abstract-factory.puml @@ -0,0 +1,94 @@ +@startuml Abstract Factory Pattern +!theme plain + +title Abstract Factory Pattern + +interface IDbFactory { + +CreateUserRepo(): IUserRepo + +CreateDepartmentRepo(): IDepartmentRepo +} + +class SqlServerFactory { + +CreateUserRepo(): IUserRepo + +CreateDepartmentRepo(): IDepartmentRepo +} + +class AccessFactory { + +CreateUserRepo(): IUserRepo + +CreateDepartmentRepo(): IDepartmentRepo +} + +interface IUserRepo { + +Insert(user: User): void + +GetUser(userId: int): User +} + +interface IDepartmentRepo { + +CreateDepartment(department: Department): void +} + +class SqlServerUserRepo { + +Insert(user: User): void + +GetUser(userId: int): User +} + +class AccessUserRepo { + +Insert(user: User): void + +GetUser(userId: int): User +} + +class SqlServerDepartmentRepo { + +CreateDepartment(department: Department): void +} + +class AccessDepartmentRepo { + +CreateDepartment(department: Department): void +} + +class User { + +Id: int + +Name: string +} + +class Department { + +Id: int + +Name: string +} + +class Client { + +Main(): void +} + +IDbFactory <|-- SqlServerFactory +IDbFactory <|-- AccessFactory + +IUserRepo <|-- SqlServerUserRepo +IUserRepo <|-- AccessUserRepo + +IDepartmentRepo <|-- SqlServerDepartmentRepo +IDepartmentRepo <|-- AccessDepartmentRepo + +SqlServerFactory ..> SqlServerUserRepo : creates +SqlServerFactory ..> SqlServerDepartmentRepo : creates +AccessFactory ..> AccessUserRepo : creates +AccessFactory ..> AccessDepartmentRepo : creates + +Client -> IDbFactory : uses + +note right of IDbFactory + Abstract factory creates + families of related objects + (SqlServer or Access) +end note + +note right of SqlServerFactory + Concrete factory for + SqlServer database objects +end note + +note right of AccessFactory + Concrete factory for + Access database objects +end note + +@enduml \ No newline at end of file diff --git a/uml/creational/builder.puml b/uml/creational/builder.puml new file mode 100644 index 0000000..d5b4b31 --- /dev/null +++ b/uml/creational/builder.puml @@ -0,0 +1,68 @@ +@startuml Builder Pattern +!theme plain + +title Builder Pattern + +class Director { + +Construct(builder: Builder): void +} + +abstract class Builder { + +{abstract} BuildPartA(): void + +{abstract} BuildPartB(): void + +{abstract} GetResult(): Product +} + +class ConcreteBuilder1 { + -product: Product + +BuildPartA(): void + +BuildPartB(): void + +GetResult(): Product +} + +class ConcreteBuilder2 { + -product: Product + +BuildPartA(): void + +BuildPartB(): void + +GetResult(): Product +} + +class Product { + -parts: ICollection + +Add(part: string): void + +Show(): void +} + +class Client { + +Main(): void +} + +Builder <|-- ConcreteBuilder1 +Builder <|-- ConcreteBuilder2 + +ConcreteBuilder1 ..> Product : creates +ConcreteBuilder2 ..> Product : creates + +Director -> Builder : uses +Client -> Director : uses + +note right of Director + Director constructs a product + using the Builder interface +end note + +note right of Builder + Abstract builder defines + interface for creating + parts of Product object +end note + +note bottom of ConcreteBuilder1 + ConcreteBuilder1 creates PartA, PartB +end note + +note bottom of ConcreteBuilder2 + ConcreteBuilder2 creates PartX, PartY +end note + +@enduml \ No newline at end of file diff --git a/uml/creational/factory-method.puml b/uml/creational/factory-method.puml new file mode 100644 index 0000000..f5d7f02 --- /dev/null +++ b/uml/creational/factory-method.puml @@ -0,0 +1,58 @@ +@startuml Factory Method Pattern +!theme plain + +title Factory Method Pattern + +interface ILeifengFactory { + +CreateLeifeng(): Leifeng +} + +class UndergraduteFactory { + +CreateLeifeng(): Leifeng +} + +class VolunteerFactory { + +CreateLeifeng(): Leifeng +} + +class Leifeng { + +Sweep(): void + +Wash(): void + +BuyRice(): void +} + +class Undergradute { +} + +class Volunteer { +} + +class Client { + +Main(): void +} + +ILeifengFactory <|-- UndergraduteFactory +ILeifengFactory <|-- VolunteerFactory + +Leifeng <|-- Undergradute +Leifeng <|-- Volunteer + +UndergraduteFactory ..> Undergradute : creates +VolunteerFactory ..> Volunteer : creates + +Client -> ILeifengFactory : uses + +note right of ILeifengFactory + Factory method defines + interface for creating objects + but lets subclasses decide + which class to instantiate +end note + +note right of Leifeng + Product base class + defines interface for + objects factory creates +end note + +@enduml \ No newline at end of file diff --git a/uml/creational/prototype.puml b/uml/creational/prototype.puml new file mode 100644 index 0000000..aaaa5ed --- /dev/null +++ b/uml/creational/prototype.puml @@ -0,0 +1,80 @@ +@startuml Prototype Pattern +!theme plain + +title Prototype Pattern + +abstract class Prototype { + +Id: string + +Prototype(id: string) + +{abstract} Clone(): Prototype +} + +class ConcretePrototype1 { + +ConcretePrototype1(id: string) + +Clone(): Prototype +} + +interface ICloneable { + +Clone(): object +} + +class SimpleResume { + -name: string + -email: string + -timePeriod: string + -company: string + +SetPersonalInfo(name: string, email: string): void + +SetWorkExperience(company: string, timePeriod: string): void + +Display(): void + +Clone(): object +} + +class ComplexResume { + -workExperience: WorkExperience + -name: string + -email: string + +ComplexResume() + +SetPersonalInfo(name: string, email: string): void + +SetWorkExperience(company: string, timePeriod: string): void + +Show(): void + +Clone(): object +} + +class WorkExperience { + +TimePeriod: string + +Company: string + +Clone(): object +} + +class Client { + +Main(): void +} + +Prototype <|-- ConcretePrototype1 + +ICloneable <|-- SimpleResume +ICloneable <|-- ComplexResume +ICloneable <|-- WorkExperience + +ComplexResume *-- WorkExperience + +Client -> Prototype : uses +Client -> SimpleResume : uses +Client -> ComplexResume : uses + +note right of Prototype + Abstract prototype declares + clone interface +end note + +note right of SimpleResume + Shallow copy implementation + using MemberwiseClone() +end note + +note right of ComplexResume + Deep copy implementation + creates copies of referenced objects +end note + +@enduml \ No newline at end of file diff --git a/uml/creational/simple-factory.puml b/uml/creational/simple-factory.puml new file mode 100644 index 0000000..5e335ac --- /dev/null +++ b/uml/creational/simple-factory.puml @@ -0,0 +1,55 @@ +@startuml Simple Factory Pattern +!theme plain + +title Simple Factory Pattern + +class OperationFactory { + +{static} CreateOperation(operate: string): Operation +} + +abstract class Operation { + +NumberA: double + +NumberB: double + +{abstract} GetResult(): double +} + +class OperationAdd { + +GetResult(): double +} + +class OpertaionSub { + +GetResult(): double +} + +class OperationMul { + +GetResult(): double +} + +class OperationDiv { + +GetResult(): double +} + +class Client { + +Main(): void +} + +Operation <|-- OperationAdd +Operation <|-- OpertaionSub +Operation <|-- OperationMul +Operation <|-- OperationDiv + +OperationFactory ..> Operation : creates +Client -> OperationFactory : uses + +note right of OperationFactory + Factory creates concrete + Operation objects based + on input parameter +end note + +note right of Operation + Base class for all + mathematical operations +end note + +@enduml \ No newline at end of file diff --git a/uml/creational/singleton.puml b/uml/creational/singleton.puml new file mode 100644 index 0000000..442ffbb --- /dev/null +++ b/uml/creational/singleton.puml @@ -0,0 +1,55 @@ +@startuml Singleton Pattern +!theme plain + +title Singleton Pattern + +class Singleton { + -{static} instance: Singleton + -{static} syncLock: object + -Singleton() + +{static} GetInstance(): Singleton +} + +class Singleton1 { + -{static} readonly Instance: Singleton1 + -Singleton1() + +{static} GetInstance(): Singleton1 +} + +class Singleton2 { + -{static} readonly Instances: ConcurrentDictionary + -Singleton2() + +{static} GetInstance(): Singleton2 +} + +class Client { + +Main(): void +} + +Client -> Singleton : GetInstance() +Client -> Singleton1 : GetInstance() +Client -> Singleton2 : GetInstance() + +note right of Singleton + Lazy initialization with + double-checked locking + (懒汉式) +end note + +note right of Singleton1 + Eager initialization + initialized at class loading + (饿汉式) +end note + +note right of Singleton2 + Using ConcurrentDictionary + for thread-safe lazy initialization +end note + +note top of Singleton + Ensures class has only one instance + and provides global point of access +end note + +@enduml \ No newline at end of file diff --git a/uml/structural/adapter.puml b/uml/structural/adapter.puml new file mode 100644 index 0000000..67f3c15 --- /dev/null +++ b/uml/structural/adapter.puml @@ -0,0 +1,85 @@ +@startuml Adapter Pattern +!theme plain + +title Adapter Pattern + +class Target { + +Request(): void +} + +class Adaptee { + +SpecialRequest(): void +} + +class TargetAdapter { + -adaptee: Adaptee + +Request(): void +} + +abstract class Player { + +{abstract} Attact(): void + +{abstract} Defend(): void +} + +class Forwards { + -name: string + +Forwards(name: string) + +Attact(): void + +Defend(): void +} + +class Guards { + -name: string + +Guards(name: string) + +Attact(): void + +Defend(): void +} + +class ForeignGuards { + -name: string + +ForeignGuards(name: string) + +进攻(): void + +防守(): void +} + +class Translator { + -foreignGuards: ForeignGuards + +Translator(name: string) + +Attact(): void + +Defend(): void +} + +class Client { + +Main(): void +} + +Target <|-- TargetAdapter +TargetAdapter *-- Adaptee + +Player <|-- Forwards +Player <|-- Guards +Player <|-- Translator +Translator *-- ForeignGuards + +Client -> Target : uses +Client -> Player : uses + +note right of TargetAdapter + Adapter converts interface + of Adaptee to Target interface + that clients expect +end note + +note right of Translator + Adapter translates Chinese + method names to English + interface for ForeignGuards +end note + +note right of Adaptee + Existing class with + incompatible interface + that needs adapting +end note + +@enduml \ No newline at end of file diff --git a/uml/structural/bridge.puml b/uml/structural/bridge.puml new file mode 100644 index 0000000..4562129 --- /dev/null +++ b/uml/structural/bridge.puml @@ -0,0 +1,94 @@ +@startuml Bridge Pattern +!theme plain + +title Bridge Pattern + +abstract class Abstraction { + #Implementor: Implementor + +SetImplementor(implementor: Implementor): void + +{abstract} Operation(): void +} + +class RefinedAbstraction { + +Operation(): void +} + +abstract class Implementor { + +{abstract} Operation(): void +} + +class ConcreteImplementorA { + +Operation(): void +} + +class ConcreteImplementorB { + +Operation(): void +} + +abstract class HandsetBrand { + #Soft: HandsetSoft + +SetHandsetSoft(soft: HandsetSoft): void + +{abstract} Run(): void +} + +class HandsetBrandM { + +Run(): void +} + +class HandsetBrandN { + +Run(): void +} + +abstract class HandsetSoft { + +{abstract} Run(): void +} + +class HandsetGame { + +Run(): void +} + +class HandsetMp3 { + +Run(): void +} + +class HandsetAddressList { + +Run(): void +} + +class Client { + +Main(): void +} + +Abstraction <|-- RefinedAbstraction +Implementor <|-- ConcreteImplementorA +Implementor <|-- ConcreteImplementorB +Abstraction -> Implementor : bridge + +HandsetBrand <|-- HandsetBrandM +HandsetBrand <|-- HandsetBrandN +HandsetSoft <|-- HandsetGame +HandsetSoft <|-- HandsetMp3 +HandsetSoft <|-- HandsetAddressList +HandsetBrand -> HandsetSoft : bridge + +Client -> Abstraction : uses +Client -> HandsetBrand : uses + +note right of Abstraction + Abstraction defines interface + for the control part of the + two class hierarchies +end note + +note right of Implementor + Implementor defines interface + for implementation classes +end note + +note right of HandsetBrand + Handset brands separated from + software functionality using + bridge pattern +end note + +@enduml \ No newline at end of file diff --git a/uml/structural/composite.puml b/uml/structural/composite.puml new file mode 100644 index 0000000..9af1f09 --- /dev/null +++ b/uml/structural/composite.puml @@ -0,0 +1,95 @@ +@startuml Composite Pattern +!theme plain + +title Composite Pattern + +abstract class Component { + #Name: string + +Component(name: string) + +{abstract} Add(c: Component): void + +{abstract} Remove(c: Component): void + +{abstract} Display(depth: int): void +} + +class Composite { + -children: List + +Composite(name: string) + +Add(c: Component): void + +Remove(c: Component): void + +Display(depth: int): void +} + +class Leaf { + +Leaf(name: string) + +Add(c: Component): void + +Remove(c: Component): void + +Display(depth: int): void +} + +abstract class Company { + #Name: string + +Company(name: string) + +{abstract} Add(company: Company): void + +{abstract} Remove(company: Company): void + +Display(depth: int): void + +{abstract} LineOfDuty(): void +} + +class ConcreteCompany { + -children: List + +ConcreteCompany(name: string) + +Add(company: Company): void + +Remove(company: Company): void + +Display(depth: int): void + +LineOfDuty(): void +} + +class HrDepartment { + +HrDepartment(name: string) + +Add(company: Company): void + +Remove(company: Company): void + +LineOfDuty(): void +} + +class FinanceDepartment { + +FinanceDepartment(name: string) + +Add(company: Company): void + +Remove(company: Company): void + +LineOfDuty(): void +} + +class Client { + +Main(): void +} + +Component <|-- Composite +Component <|-- Leaf +Composite *-- Component + +Company <|-- ConcreteCompany +Company <|-- HrDepartment +Company <|-- FinanceDepartment +ConcreteCompany *-- Company + +Client -> Component : uses +Client -> Company : uses + +note right of Component + Base component declares + interface for objects + in composition +end note + +note right of Composite + Defines behavior for components + having children, stores child + components and implements + child-related operations +end note + +note right of Leaf + Represents leaf objects in + composition. Has no children. +end note + +@enduml \ No newline at end of file diff --git a/uml/structural/decorator.puml b/uml/structural/decorator.puml new file mode 100644 index 0000000..a08b187 --- /dev/null +++ b/uml/structural/decorator.puml @@ -0,0 +1,93 @@ +@startuml Decorator Pattern +!theme plain + +title Decorator Pattern + +abstract class Component { + +{abstract} Operation(): void +} + +class ConcreteComponent { + +Operation(): void +} + +abstract class Decorator { + #Component: Component + +SetComponent(component: Component): void + +Operation(): void +} + +class DecoratorA { + -state: string + +Operation(): void +} + +class DecoratorB { + +Operation(): void + -AddBehavior(): void +} + +class Person { + #Name: string + +Person() + +Person(name: string) + +Show(): void +} + +class Finery { + #Person: Person + +Decorate(person: Person): void + +Show(): void +} + +class Tshirts { + +Show(): void +} + +class Pants { + +Show(): void +} + +class Client { + +Main(): void +} + +Component <|-- ConcreteComponent +Component <|-- Decorator +Decorator <|-- DecoratorA +Decorator <|-- DecoratorB +Decorator -> Component : wraps + +Person <|-- Finery +Finery <|-- Tshirts +Finery <|-- Pants +Finery -> Person : decorates + +Client -> Component : uses +Client -> Person : uses + +note right of Component + Base interface for objects + that can have responsibilities + added to them dynamically +end note + +note right of Decorator + Maintains reference to + Component object and defines + interface that conforms to + Component's interface +end note + +note right of DecoratorA + Adds additional state + and behavior +end note + +note right of Person + Concrete component that + can be decorated with + various clothing items +end note + +@enduml \ No newline at end of file diff --git a/uml/structural/facade.puml b/uml/structural/facade.puml new file mode 100644 index 0000000..83f1883 --- /dev/null +++ b/uml/structural/facade.puml @@ -0,0 +1,61 @@ +@startuml Facade Pattern +!theme plain + +title Facade Pattern + +class SubSystem1 { + +MethodA(): void + +MethodB(): void +} + +class SubSystem2 { + +MethodA(): void + +MethodB(): void +} + +class SubSystem3 { + +MethodA(): void + +MethodB(): void +} + +class Facade { + -subSystem1: SubSystem1 + -subSystem2: SubSystem2 + -subSystem3: SubSystem3 + +MethodA(): void + +MethodB(): void +} + +class Client { + +Main(): void +} + +Facade *-- SubSystem1 +Facade *-- SubSystem2 +Facade *-- SubSystem3 + +Client -> Facade : uses +Client -.-> SubSystem1 : doesn't access directly +Client -.-> SubSystem2 : doesn't access directly +Client -.-> SubSystem3 : doesn't access directly + +note right of Facade + Facade provides unified + interface to set of + interfaces in subsystem +end note + +note left of SubSystem1 + Subsystem classes implement + subsystem functionality + but have no knowledge + of facade +end note + +note bottom of Client + Client communicates with + subsystem only through + facade interface +end note + +@enduml \ No newline at end of file diff --git a/uml/structural/flyweight.puml b/uml/structural/flyweight.puml new file mode 100644 index 0000000..154628c --- /dev/null +++ b/uml/structural/flyweight.puml @@ -0,0 +1,59 @@ +@startuml Flyweight Pattern +!theme plain + +title Flyweight Pattern + +abstract class Flyweight { + +{abstract} Operation(extrinsicstate: int): void +} + +class ConcreteFlyweight { + +Operation(extrinsicstate: int): void +} + +class UnsharedFlyweight { + +Operation(extrinsicstate: int): void +} + +class FlyWeightFactory { + -flyweights: ConcurrentDictionary + +GetFlyweight(name: string): Flyweight +} + +class Client { + +Main(): void +} + +Flyweight <|-- ConcreteFlyweight +Flyweight <|-- UnsharedFlyweight +FlyWeightFactory -> Flyweight : creates and manages +FlyWeightFactory *-- Flyweight + +Client -> FlyWeightFactory : uses +Client -> Flyweight : uses + +note right of Flyweight + Flyweight declares interface + through which flyweights can + receive and act on extrinsic state +end note + +note right of ConcreteFlyweight + Implements Flyweight interface + and stores intrinsic state. + Must be shareable. +end note + +note right of FlyWeightFactory + Creates and manages flyweight + objects. Ensures flyweights + are shared properly. +end note + +note right of UnsharedFlyweight + Not all flyweight subclasses + need to be shared. Some may + store all their state +end note + +@enduml \ No newline at end of file diff --git a/uml/structural/proxy.puml b/uml/structural/proxy.puml new file mode 100644 index 0000000..6269e32 --- /dev/null +++ b/uml/structural/proxy.puml @@ -0,0 +1,62 @@ +@startuml Proxy Pattern +!theme plain + +title Proxy Pattern + +abstract class Subject { + +{abstract} Request(): void +} + +class RealSubject { + +Request(): void +} + +class Proxy0 { + -subject: Subject + +Request(): void +} + +class Proxy { + -subject: Subject + +Proxy(subject: Subject) + +Request(): void +} + +class Client { + +Main(): void +} + +Subject <|-- RealSubject +Subject <|-- Proxy0 +Subject <|-- Proxy + +Proxy0 -> RealSubject : creates +Proxy -> Subject : delegates to + +Client -> Subject : uses + +note right of Subject + Subject defines common + interface for RealSubject + and Proxy so Proxy can be + used anywhere RealSubject is +end note + +note right of RealSubject + RealSubject defines the + real object that the + proxy represents +end note + +note right of Proxy0 + Lazy loading proxy - creates + RealSubject only when needed +end note + +note right of Proxy + Proxy maintains reference + to subject and controls + access to it +end note + +@enduml \ No newline at end of file