pdd-skills 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1478 -0
- package/bin/pdd.js +354 -0
- package/config/bpmn-rules.yaml +166 -0
- package/config/checkstyle.xml +105 -0
- package/config/eslint.config.js +48 -0
- package/config/pmd.xml +91 -0
- package/config/prd-rules.yaml +113 -0
- package/config/ruff.toml +45 -0
- package/config/sqlfluff.cfg +82 -0
- package/hooks/hook-executor.js +332 -0
- package/index.js +43 -0
- package/lib/api-routes.js +750 -0
- package/lib/api-server.js +408 -0
- package/lib/cache/cache-config.js +209 -0
- package/lib/cache/system-cache.js +852 -0
- package/lib/config-manager.js +373 -0
- package/lib/generate.js +528 -0
- package/lib/grpc/grpc-routes.js +1134 -0
- package/lib/grpc/grpc-server.js +912 -0
- package/lib/grpc/proto-definitions.js +1033 -0
- package/lib/init.js +172 -0
- package/lib/iteration/auto-fixer.js +1025 -0
- package/lib/iteration/auto-reviewer.js +923 -0
- package/lib/iteration/controller.js +577 -0
- package/lib/list.js +130 -0
- package/lib/mcp-server.js +548 -0
- package/lib/openclaw/api-integration.js +535 -0
- package/lib/openclaw/cli-integration.js +567 -0
- package/lib/openclaw/data-sync.js +845 -0
- package/lib/openclaw/openclaw-adapter.js +783 -0
- package/lib/plugin/example-plugins/code-stats/index.js +332 -0
- package/lib/plugin/example-plugins/code-stats/plugin.json +1 -0
- package/lib/plugin/example-plugins/custom-linter/index.js +472 -0
- package/lib/plugin/example-plugins/custom-linter/plugin.json +1 -0
- package/lib/plugin/example-plugins/hello-world/index.js +86 -0
- package/lib/plugin/example-plugins/hello-world/plugin.json +1 -0
- package/lib/plugin/plugin-manager.js +655 -0
- package/lib/plugin/plugin-sdk.js +565 -0
- package/lib/plugin/sandbox.js +627 -0
- package/lib/quality/rules/maintainability.js +418 -0
- package/lib/quality/rules/performance.js +498 -0
- package/lib/quality/rules/readability.js +441 -0
- package/lib/quality/rules/robustness.js +504 -0
- package/lib/quality/rules/security.js +444 -0
- package/lib/quality/scorer.js +576 -0
- package/lib/report.js +669 -0
- package/lib/sdk-base.js +301 -0
- package/lib/sdk-js.js +446 -0
- package/lib/sdk-python/README.md +546 -0
- package/lib/sdk-python/examples/basic_usage.py +450 -0
- package/lib/sdk-python/pdd_sdk/__init__.py +180 -0
- package/lib/sdk-python/pdd_sdk/client.py +1170 -0
- package/lib/sdk-python/pdd_sdk/events.py +423 -0
- package/lib/sdk-python/pdd_sdk/exceptions.py +158 -0
- package/lib/sdk-python/pdd_sdk/models.py +518 -0
- package/lib/sdk-python/pdd_sdk/utils.py +759 -0
- package/lib/token/budget-alert.js +367 -0
- package/lib/token/budget-manager.js +485 -0
- package/lib/update.js +54 -0
- package/lib/utils/logger.js +88 -0
- package/lib/verify.js +741 -0
- package/lib/version.js +52 -0
- package/lib/vm/README.md +102 -0
- package/lib/vm/dashboard/api-routes.js +669 -0
- package/lib/vm/dashboard/server.js +391 -0
- package/lib/vm/dashboard/sse.js +358 -0
- package/lib/vm/dashboard/static/css/dashboard.css +1378 -0
- package/lib/vm/dashboard/static/index.html +118 -0
- package/lib/vm/dashboard/static/js/app.js +949 -0
- package/lib/vm/dashboard/static/js/charts.js +913 -0
- package/lib/vm/dashboard/static/js/kanban-view.js +1053 -0
- package/lib/vm/dashboard/static/js/pipeline-view.js +463 -0
- package/lib/vm/dashboard/static/js/quality-view.js +598 -0
- package/lib/vm/dashboard/static/js/system-view.js +1021 -0
- package/lib/vm/data-provider.js +1191 -0
- package/lib/vm/event-bus.js +402 -0
- package/lib/vm/hooks/extract-hook.js +307 -0
- package/lib/vm/hooks/generate-hook.js +374 -0
- package/lib/vm/hooks/hook-interface.js +458 -0
- package/lib/vm/hooks/report-hook.js +331 -0
- package/lib/vm/hooks/verify-hook.js +454 -0
- package/lib/vm/models.js +1003 -0
- package/lib/vm/reconciler.js +855 -0
- package/lib/vm/scanner.js +988 -0
- package/lib/vm/state-schema.js +955 -0
- package/lib/vm/state-store.js +733 -0
- package/lib/vm/tui/components/card.js +339 -0
- package/lib/vm/tui/components/progress-bar.js +368 -0
- package/lib/vm/tui/components/sparkline.js +327 -0
- package/lib/vm/tui/components/status-light.js +294 -0
- package/lib/vm/tui/components/table.js +370 -0
- package/lib/vm/tui/input.js +335 -0
- package/lib/vm/tui/renderer.js +548 -0
- package/lib/vm/tui/screens/kanban-screen.js +397 -0
- package/lib/vm/tui/screens/overview-screen.js +357 -0
- package/lib/vm/tui/screens/quality-screen.js +336 -0
- package/lib/vm/tui/screens/system-screen.js +379 -0
- package/lib/vm/tui/tui.js +805 -0
- package/package.json +1 -0
- package/scripts/cso-analyzer.js +198 -0
- package/scripts/eval-runner.js +359 -0
- package/scripts/i18n-checker.js +109 -0
- package/scripts/linter/activiti-linter.js +272 -0
- package/scripts/linter/prd-linter.js +162 -0
- package/scripts/linter/report-generator.js +207 -0
- package/scripts/linter/run-linters.js +285 -0
- package/scripts/linter/sql-linter.js +166 -0
- package/scripts/token-analyzer.js +162 -0
- package/scripts/vm-test.js +180 -0
- package/skills/core/official-doc-writer/LICENSE +21 -0
- package/skills/core/official-doc-writer/README.md +232 -0
- package/skills/core/official-doc-writer/SKILL.md +475 -0
- package/skills/core/official-doc-writer/_meta.json +1 -0
- package/skills/core/official-doc-writer/document_generator.py +580 -0
- package/skills/core/official-doc-writer/evals/default-evals.json +1 -0
- package/skills/core/official-doc-writer/examples.md +150 -0
- package/skills/core/official-doc-writer/fonts/FONTS_LIST.md +45 -0
- package/skills/core/official-doc-writer/fonts/README.md +141 -0
- package/skills/core/official-doc-writer/fonts/SIMFANG.TTF +0 -0
- package/skills/core/official-doc-writer/fonts/SIMHEI.TTF +0 -0
- package/skills/core/official-doc-writer/fonts/SIMKAI.TTF +0 -0
- package/skills/core/official-doc-writer/fonts/SIMSUN.TTC +0 -0
- package/skills/core/official-doc-writer/fonts//346/226/271/346/255/243/345/260/217/346/240/207/345/256/213GBK.TTF +0 -0
- package/skills/core/official-doc-writer/references/GBT_9704-2012_/345/205/232/346/224/277/346/234/272/345/205/263/345/205/254/346/226/207/346/240/274/345/274/217.md +422 -0
- package/skills/core/official-doc-writer/scripts/__pycache__/generate_official_doc.cpython-313.pyc +0 -0
- package/skills/core/official-doc-writer/scripts/dialog_manager.py +564 -0
- package/skills/core/official-doc-writer/scripts/generate_official_doc.py +252 -0
- package/skills/core/official-doc-writer/scripts/install_fonts.py +390 -0
- package/skills/core/official-doc-writer/scripts/smart_prompts.py +363 -0
- package/skills/core/pdd-ba/SKILL.md +305 -0
- package/skills/core/pdd-ba/_meta.json +1 -0
- package/skills/core/pdd-ba/evals/default-evals.json +1 -0
- package/skills/core/pdd-code-reviewer/SKILL.md +378 -0
- package/skills/core/pdd-code-reviewer/_meta.json +1 -0
- package/skills/core/pdd-code-reviewer/evals/default-evals.json +1 -0
- package/skills/core/pdd-doc-change/SKILL.md +350 -0
- package/skills/core/pdd-doc-change/_meta.json +1 -0
- package/skills/core/pdd-doc-change/evals/default-evals.json +1 -0
- package/skills/core/pdd-doc-gardener/SKILL.md +248 -0
- package/skills/core/pdd-doc-gardener/_meta.json +1 -0
- package/skills/core/pdd-doc-gardener/evals/default-evals.json +1 -0
- package/skills/core/pdd-entropy-reduction/SKILL.md +360 -0
- package/skills/core/pdd-entropy-reduction/_meta.json +1 -0
- package/skills/core/pdd-entropy-reduction/evals/default-evals.json +1 -0
- package/skills/core/pdd-entropy-reduction/references/entropy-report-template.md +287 -0
- package/skills/core/pdd-entropy-reduction/references/golden-principles.md +573 -0
- package/skills/core/pdd-entropy-reduction/scripts/entropy_scan.py +712 -0
- package/skills/core/pdd-extract-features/SKILL.md +320 -0
- package/skills/core/pdd-extract-features/_meta.json +1 -0
- package/skills/core/pdd-extract-features/evals/default-evals.json +1 -0
- package/skills/core/pdd-generate-spec/SKILL.md +418 -0
- package/skills/core/pdd-generate-spec/_meta.json +1 -0
- package/skills/core/pdd-generate-spec/evals/default-evals.json +1 -0
- package/skills/core/pdd-implement-feature/SKILL.md +332 -0
- package/skills/core/pdd-implement-feature/_meta.json +1 -0
- package/skills/core/pdd-implement-feature/evals/default-evals.json +1 -0
- package/skills/core/pdd-main/SKILL.md +540 -0
- package/skills/core/pdd-main/_meta.json +1 -0
- package/skills/core/pdd-main/evals/default-evals.json +1 -0
- package/skills/core/pdd-main/evals/evals.json +215 -0
- package/skills/core/pdd-verify-feature/SKILL.md +474 -0
- package/skills/core/pdd-verify-feature/_meta.json +1 -0
- package/skills/core/pdd-verify-feature/evals/default-evals.json +1 -0
- package/skills/core/pdd-vm/evals/default-evals.json +1 -0
- package/skills/core/traffic-accident-assessor/LICENSE +29 -0
- package/skills/core/traffic-accident-assessor/SKILL.md +439 -0
- package/skills/core/traffic-accident-assessor/evals/evals.json +1 -0
- package/skills/core/traffic-accident-assessor/references/accident-types.md +369 -0
- package/skills/core/traffic-accident-assessor/references/liability-rules.md +287 -0
- package/skills/core/traffic-accident-assessor/references/traffic-laws.md +226 -0
- package/skills/core/traffic-accident-assessor/references//351/253/230/345/260/224/345/244/253/350/257/264/346/230/216/344/271/246.pdf +32576 -106
- package/skills/core/traffic-accident-assessor/scripts/generate_official_statement.py +588 -0
- package/skills/core/traffic-accident-assessor/scripts/generate_report.py +495 -0
- package/skills/core/traffic-accident-assessor/scripts/generate_statement.py +528 -0
- package/skills/core/traffic-accident-assessor.zip +0 -0
- package/skills/entropy/expert-arch-enforcer/SKILL.md +292 -0
- package/skills/entropy/expert-arch-enforcer/_meta.json +1 -0
- package/skills/entropy/expert-arch-enforcer/evals/default-evals.json +1 -0
- package/skills/entropy/expert-auto-refactor/SKILL.md +327 -0
- package/skills/entropy/expert-auto-refactor/_meta.json +1 -0
- package/skills/entropy/expert-auto-refactor/evals/default-evals.json +1 -0
- package/skills/entropy/expert-code-quality/SKILL.md +468 -0
- package/skills/entropy/expert-code-quality/_meta.json +1 -0
- package/skills/entropy/expert-code-quality/evals/default-evals.json +1 -0
- package/skills/entropy/expert-code-quality/evals/evals.json +109 -0
- package/skills/entropy/expert-code-quality/references/code-smells.md +605 -0
- package/skills/entropy/expert-code-quality/references/design-patterns.md +1111 -0
- package/skills/entropy/expert-code-quality/references/refactoring-catalog.md +1281 -0
- package/skills/entropy/expert-code-quality/references/solid-principles.md +524 -0
- package/skills/entropy/expert-entropy-auditor/SKILL.md +276 -0
- package/skills/entropy/expert-entropy-auditor/_meta.json +1 -0
- package/skills/entropy/expert-entropy-auditor/evals/default-evals.json +1 -0
- package/skills/expert/expert-activiti/SKILL.md +497 -0
- package/skills/expert/expert-activiti/_meta.json +1 -0
- package/skills/expert/expert-mysql/SKILL.md +832 -0
- package/skills/expert/expert-mysql/_meta.json +1 -0
- package/skills/expert/expert-performance/SKILL.md +379 -0
- package/skills/expert/expert-performance/_meta.json +1 -0
- package/skills/expert/expert-performance/evals/default-evals.json +1 -0
- package/skills/expert/expert-ruoyi/SKILL.md +472 -0
- package/skills/expert/expert-ruoyi/_meta.json +1 -0
- package/skills/expert/expert-security/SKILL.md +1341 -0
- package/skills/expert/expert-security/_meta.json +1 -0
- package/skills/expert/expert-security/evals/default-evals.json +1 -0
- package/skills/expert/software-architect/SKILL.md +350 -0
- package/skills/expert/software-architect/_meta.json +1 -0
- package/skills/expert/software-engineer/SKILL.md +437 -0
- package/skills/expert/software-engineer/_meta.json +1 -0
- package/skills/expert/software-engineer/architecture.md +130 -0
- package/skills/expert/software-engineer/patterns.md +151 -0
- package/skills/expert/software-engineer/testing.md +135 -0
- package/skills/expert/system-architect/SKILL.md +628 -0
- package/skills/expert/system-architect/_meta.json +1 -0
- package/skills/expert/system-architect/assets/templates/ARCHITECTURE.md +25 -0
- package/skills/expert/system-architect/assets/templates/README.md +44 -0
- package/skills/expert/system-architect/references/js-ts-standards.md +18 -0
- package/skills/expert/system-architect/references/python-standards.md +19 -0
- package/skills/expert/system-architect/references/scaffolding.md +61 -0
- package/skills/expert/system-architect/references/security-checklist.md +21 -0
- package/skills/openspec/openspec-apply-change/SKILL.md +156 -0
- package/skills/openspec/openspec-apply-change/_meta.json +1 -0
- package/skills/openspec/openspec-archive-change/SKILL.md +114 -0
- package/skills/openspec/openspec-archive-change/_meta.json +1 -0
- package/skills/openspec/openspec-bulk-archive-change/SKILL.md +246 -0
- package/skills/openspec/openspec-bulk-archive-change/_meta.json +1 -0
- package/skills/openspec/openspec-continue-change/SKILL.md +118 -0
- package/skills/openspec/openspec-continue-change/_meta.json +1 -0
- package/skills/openspec/openspec-explore/SKILL.md +288 -0
- package/skills/openspec/openspec-explore/_meta.json +1 -0
- package/skills/openspec/openspec-ff-change/SKILL.md +101 -0
- package/skills/openspec/openspec-ff-change/_meta.json +1 -0
- package/skills/openspec/openspec-new-change/SKILL.md +74 -0
- package/skills/openspec/openspec-new-change/_meta.json +1 -0
- package/skills/openspec/openspec-onboard/SKILL.md +554 -0
- package/skills/openspec/openspec-onboard/_meta.json +1 -0
- package/skills/openspec/openspec-sync-specs/SKILL.md +138 -0
- package/skills/openspec/openspec-sync-specs/_meta.json +1 -0
- package/skills/openspec/openspec-verify-change/SKILL.md +168 -0
- package/skills/openspec/openspec-verify-change/_meta.json +1 -0
- package/skills/pr/pdd-multi-review/SKILL.md +534 -0
- package/skills/pr/pdd-multi-review/_meta.json +1 -0
- package/skills/pr/pdd-pr-batch/SKILL.md +303 -0
- package/skills/pr/pdd-pr-batch/_meta.json +1 -0
- package/skills/pr/pdd-pr-create/SKILL.md +344 -0
- package/skills/pr/pdd-pr-create/_meta.json +1 -0
- package/skills/pr/pdd-pr-merge/SKILL.md +286 -0
- package/skills/pr/pdd-pr-merge/_meta.json +1 -0
- package/skills/pr/pdd-pr-review/SKILL.md +217 -0
- package/skills/pr/pdd-pr-review/_meta.json +1 -0
- package/skills/pr/pdd-task-manager/SKILL.md +636 -0
- package/skills/pr/pdd-task-manager/_meta.json +1 -0
- package/skills/pr/pdd-template-engine/SKILL.md +306 -0
- package/skills/pr/pdd-template-engine/_meta.json +1 -0
- package/templates/behavior-shaping/iron-law-template.md +87 -0
- package/templates/behavior-shaping/rationalization-template.md +62 -0
- package/templates/behavior-shaping/red-flags-template.md +70 -0
- package/templates/bilingual-template.md +139 -0
- package/templates/config/default.yaml +47 -0
- package/templates/project/default/README.md +31 -0
- package/templates/project/frontend/README.md +46 -0
- package/templates/project/java/README.md +48 -0
|
@@ -0,0 +1,1111 @@
|
|
|
1
|
+
# Design Patterns Reference
|
|
2
|
+
|
|
3
|
+
A comprehensive reference of the 23 GoF design patterns, organized by category.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Creational Patterns](#1-creational-patterns)
|
|
8
|
+
2. [Structural Patterns](#2-structural-patterns)
|
|
9
|
+
3. [Behavioral Patterns](#3-behavioral-patterns)
|
|
10
|
+
4. [Pattern Selection Guide](#4-pattern-selection-guide)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 1. Creational Patterns
|
|
15
|
+
|
|
16
|
+
### Singleton
|
|
17
|
+
|
|
18
|
+
**Intent**: Ensure a class only has one instance, and provide a global point of access to it.
|
|
19
|
+
|
|
20
|
+
**When to Use**:
|
|
21
|
+
- Need exactly one instance of a class
|
|
22
|
+
- Need a global access point
|
|
23
|
+
- Control access to shared resources
|
|
24
|
+
|
|
25
|
+
**Structure**:
|
|
26
|
+
```
|
|
27
|
+
┌─────────────────┐
|
|
28
|
+
│ Singleton │
|
|
29
|
+
├─────────────────┤
|
|
30
|
+
│ - instance │
|
|
31
|
+
├─────────────────┤
|
|
32
|
+
│ + getInstance() │
|
|
33
|
+
│ - Singleton() │
|
|
34
|
+
└─────────────────┘
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Implementation**:
|
|
38
|
+
```java
|
|
39
|
+
public class Singleton {
|
|
40
|
+
private static volatile Singleton instance;
|
|
41
|
+
|
|
42
|
+
private Singleton() {}
|
|
43
|
+
|
|
44
|
+
public static Singleton getInstance() {
|
|
45
|
+
if (instance == null) {
|
|
46
|
+
synchronized (Singleton.class) {
|
|
47
|
+
if (instance == null) {
|
|
48
|
+
instance = new Singleton();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return instance;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Recommended: Enum implementation
|
|
57
|
+
public enum Singleton {
|
|
58
|
+
INSTANCE;
|
|
59
|
+
|
|
60
|
+
public void doSomething() { }
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Pros**: Controlled access, reduced namespace, extensible
|
|
65
|
+
**Cons**: Can hide dependencies, difficult to test, may violate SRP
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
### Factory Method
|
|
70
|
+
|
|
71
|
+
**Intent**: Define an interface for creating an object, but let subclasses decide which class to instantiate.
|
|
72
|
+
|
|
73
|
+
**When to Use**:
|
|
74
|
+
- A class can't anticipate the class of objects it must create
|
|
75
|
+
- A class wants its subclasses to specify the objects it creates
|
|
76
|
+
|
|
77
|
+
**Structure**:
|
|
78
|
+
```
|
|
79
|
+
┌──────────────┐ ┌──────────────┐
|
|
80
|
+
│ Creator │ │ Product │
|
|
81
|
+
├──────────────┤ ├──────────────┤
|
|
82
|
+
│+factoryMethod│ │+operation() │
|
|
83
|
+
└──────┬───────┘ └──────────────┘
|
|
84
|
+
│ △
|
|
85
|
+
│ │
|
|
86
|
+
┌──────┴───────┐ ┌──────┴───────┐
|
|
87
|
+
│ConcreteCreator│ │ConcreteProduct│
|
|
88
|
+
├──────────────┤ ├──────────────┤
|
|
89
|
+
│+factoryMethod│ │+operation() │
|
|
90
|
+
└──────────────┘ └──────────────┘
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Implementation**:
|
|
94
|
+
```java
|
|
95
|
+
// Product interface
|
|
96
|
+
public interface Product {
|
|
97
|
+
void use();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Concrete products
|
|
101
|
+
public class ConcreteProductA implements Product {
|
|
102
|
+
public void use() { System.out.println("Using Product A"); }
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Creator
|
|
106
|
+
public abstract class Creator {
|
|
107
|
+
public abstract Product factoryMethod();
|
|
108
|
+
|
|
109
|
+
public void doSomething() {
|
|
110
|
+
Product product = factoryMethod();
|
|
111
|
+
product.use();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Concrete creator
|
|
116
|
+
public class ConcreteCreatorA extends Creator {
|
|
117
|
+
public Product factoryMethod() {
|
|
118
|
+
return new ConcreteProductA();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Pros**: Decouples client from product creation, supports Open/Closed Principle
|
|
124
|
+
**Cons**: May require creating a creator subclass just to instantiate a product
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
### Abstract Factory
|
|
129
|
+
|
|
130
|
+
**Intent**: Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
|
|
131
|
+
|
|
132
|
+
**When to Use**:
|
|
133
|
+
- A system should be independent of how its products are created
|
|
134
|
+
- A family of related product objects is designed to be used together
|
|
135
|
+
|
|
136
|
+
**Structure**:
|
|
137
|
+
```
|
|
138
|
+
┌──────────────────┐
|
|
139
|
+
│ AbstractFactory │
|
|
140
|
+
├──────────────────┤
|
|
141
|
+
│+createProductA() │
|
|
142
|
+
│+createProductB() │
|
|
143
|
+
└────────┬─────────┘
|
|
144
|
+
│
|
|
145
|
+
┌────┴────┐
|
|
146
|
+
│ │
|
|
147
|
+
┌───┴───┐ ┌───┴───┐
|
|
148
|
+
│Factory│ │Factory│
|
|
149
|
+
│ A │ │ B │
|
|
150
|
+
└───────┘ └───────┘
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Implementation**:
|
|
154
|
+
```java
|
|
155
|
+
// Abstract factory
|
|
156
|
+
public interface GUIFactory {
|
|
157
|
+
Button createButton();
|
|
158
|
+
TextField createTextField();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Concrete factories
|
|
162
|
+
public class WindowsFactory implements GUIFactory {
|
|
163
|
+
public Button createButton() { return new WindowsButton(); }
|
|
164
|
+
public TextField createTextField() { return new WindowsTextField(); }
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
public class MacFactory implements GUIFactory {
|
|
168
|
+
public Button createButton() { return new MacButton(); }
|
|
169
|
+
public TextField createTextField() { return new MacTextField(); }
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Pros**: Isolates concrete classes, exchanges product families easily
|
|
174
|
+
**Cons**: Difficult to support new kinds of products
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
### Builder
|
|
179
|
+
|
|
180
|
+
**Intent**: Separate the construction of a complex object from its representation so that the same construction process can create different representations.
|
|
181
|
+
|
|
182
|
+
**When to Use**:
|
|
183
|
+
- The algorithm for creating a complex object should be independent of the parts
|
|
184
|
+
- The construction process must allow different representations
|
|
185
|
+
|
|
186
|
+
**Structure**:
|
|
187
|
+
```
|
|
188
|
+
Director → Builder ← ConcreteBuilder → Product
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Implementation**:
|
|
192
|
+
```java
|
|
193
|
+
public class Computer {
|
|
194
|
+
private String cpu;
|
|
195
|
+
private String ram;
|
|
196
|
+
private String storage;
|
|
197
|
+
|
|
198
|
+
private Computer(Builder builder) {
|
|
199
|
+
this.cpu = builder.cpu;
|
|
200
|
+
this.ram = builder.ram;
|
|
201
|
+
this.storage = builder.storage;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public static class Builder {
|
|
205
|
+
private String cpu;
|
|
206
|
+
private String ram;
|
|
207
|
+
private String storage;
|
|
208
|
+
|
|
209
|
+
public Builder cpu(String cpu) { this.cpu = cpu; return this; }
|
|
210
|
+
public Builder ram(String ram) { this.ram = ram; return this; }
|
|
211
|
+
public Builder storage(String storage) { this.storage = storage; return this; }
|
|
212
|
+
|
|
213
|
+
public Computer build() {
|
|
214
|
+
return new Computer(this);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Usage
|
|
220
|
+
Computer computer = new Computer.Builder()
|
|
221
|
+
.cpu("Intel i7")
|
|
222
|
+
.ram("16GB")
|
|
223
|
+
.storage("512GB SSD")
|
|
224
|
+
.build();
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Pros**: Fine control over construction process, immutable objects
|
|
228
|
+
**Cons**: Requires creating a separate Builder class
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
### Prototype
|
|
233
|
+
|
|
234
|
+
**Intent**: Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
|
|
235
|
+
|
|
236
|
+
**When to Use**:
|
|
237
|
+
- Classes to instantiate are specified at run-time
|
|
238
|
+
- Avoiding a proliferation of factory classes
|
|
239
|
+
- Instances of a class have few combinations of state
|
|
240
|
+
|
|
241
|
+
**Implementation**:
|
|
242
|
+
```java
|
|
243
|
+
public class Prototype implements Cloneable {
|
|
244
|
+
private String name;
|
|
245
|
+
private List<String> items;
|
|
246
|
+
|
|
247
|
+
public Prototype clone() {
|
|
248
|
+
try {
|
|
249
|
+
Prototype cloned = (Prototype) super.clone();
|
|
250
|
+
cloned.items = new ArrayList<>(this.items); // Deep copy
|
|
251
|
+
return cloned;
|
|
252
|
+
} catch (CloneNotSupportedException e) {
|
|
253
|
+
throw new RuntimeException(e);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Pros**: Reduces subclassing, dynamic addition/removal of products
|
|
260
|
+
**Cons**: Implementing Clone can be difficult for complex objects
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## 2. Structural Patterns
|
|
265
|
+
|
|
266
|
+
### Adapter
|
|
267
|
+
|
|
268
|
+
**Intent**: Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
|
|
269
|
+
|
|
270
|
+
**When to Use**:
|
|
271
|
+
- You want to use an existing class, and its interface does not match
|
|
272
|
+
- You want to create a reusable class that cooperates with unrelated classes
|
|
273
|
+
|
|
274
|
+
**Structure**:
|
|
275
|
+
```
|
|
276
|
+
Target ← Adapter → Adaptee
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**Implementation**:
|
|
280
|
+
```java
|
|
281
|
+
// Target interface
|
|
282
|
+
public interface Target {
|
|
283
|
+
void request();
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Adaptee
|
|
287
|
+
public class Adaptee {
|
|
288
|
+
public void specificRequest() { }
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Object Adapter
|
|
292
|
+
public class Adapter implements Target {
|
|
293
|
+
private Adaptee adaptee;
|
|
294
|
+
|
|
295
|
+
public Adapter(Adaptee adaptee) {
|
|
296
|
+
this.adaptee = adaptee;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
public void request() {
|
|
300
|
+
adaptee.specificRequest();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**Pros**: Single responsibility principle, Open/Closed Principle
|
|
306
|
+
**Cons**: Complexity increases
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
### Decorator
|
|
311
|
+
|
|
312
|
+
**Intent**: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
|
|
313
|
+
|
|
314
|
+
**When to Use**:
|
|
315
|
+
- To add responsibilities to individual objects dynamically
|
|
316
|
+
- When extension by subclassing is impractical
|
|
317
|
+
|
|
318
|
+
**Structure**:
|
|
319
|
+
```
|
|
320
|
+
Component ← Decorator
|
|
321
|
+
↑ ↑
|
|
322
|
+
ConcreteComponent ConcreteDecorator
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Implementation**:
|
|
326
|
+
```java
|
|
327
|
+
public interface Component {
|
|
328
|
+
void operation();
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
public class ConcreteComponent implements Component {
|
|
332
|
+
public void operation() {
|
|
333
|
+
System.out.println("Base operation");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
public abstract class Decorator implements Component {
|
|
338
|
+
protected Component component;
|
|
339
|
+
|
|
340
|
+
public Decorator(Component component) {
|
|
341
|
+
this.component = component;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
public void operation() {
|
|
345
|
+
component.operation();
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
public class ConcreteDecorator extends Decorator {
|
|
350
|
+
public ConcreteDecorator(Component component) {
|
|
351
|
+
super(component);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
public void operation() {
|
|
355
|
+
super.operation();
|
|
356
|
+
addedBehavior();
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
private void addedBehavior() { }
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**Pros**: More flexibility than static inheritance, avoids feature-laden classes
|
|
364
|
+
**Cons**: Many small objects, decorator can complicate code
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
### Proxy
|
|
369
|
+
|
|
370
|
+
**Intent**: Provide a surrogate or placeholder for another object to control access to it.
|
|
371
|
+
|
|
372
|
+
**When to Use**:
|
|
373
|
+
- Remote proxy: local representative for an object in a different address space
|
|
374
|
+
- Virtual proxy: creates expensive objects on demand
|
|
375
|
+
- Protection proxy: controls access to the original object
|
|
376
|
+
|
|
377
|
+
**Structure**:
|
|
378
|
+
```
|
|
379
|
+
Subject ← Proxy → RealSubject
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
**Implementation**:
|
|
383
|
+
```java
|
|
384
|
+
public interface Subject {
|
|
385
|
+
void request();
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
public class RealSubject implements Subject {
|
|
389
|
+
public void request() {
|
|
390
|
+
System.out.println("Real request");
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
public class Proxy implements Subject {
|
|
395
|
+
private RealSubject realSubject;
|
|
396
|
+
|
|
397
|
+
public void request() {
|
|
398
|
+
if (realSubject == null) {
|
|
399
|
+
realSubject = new RealSubject();
|
|
400
|
+
}
|
|
401
|
+
preRequest();
|
|
402
|
+
realSubject.request();
|
|
403
|
+
postRequest();
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
private void preRequest() { }
|
|
407
|
+
private void postRequest() { }
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
**Pros**: Controls access, adds functionality transparently
|
|
412
|
+
**Cons**: May add overhead
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
### Facade
|
|
417
|
+
|
|
418
|
+
**Intent**: Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
|
|
419
|
+
|
|
420
|
+
**When to Use**:
|
|
421
|
+
- You want to provide a simple interface to a complex subsystem
|
|
422
|
+
- There are many dependencies between clients and implementation classes
|
|
423
|
+
|
|
424
|
+
**Structure**:
|
|
425
|
+
```
|
|
426
|
+
Client → Facade → Subsystem classes
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
**Implementation**:
|
|
430
|
+
```java
|
|
431
|
+
public class ComputerFacade {
|
|
432
|
+
private CPU cpu;
|
|
433
|
+
private Memory memory;
|
|
434
|
+
private HardDrive hardDrive;
|
|
435
|
+
|
|
436
|
+
public ComputerFacade() {
|
|
437
|
+
cpu = new CPU();
|
|
438
|
+
memory = new Memory();
|
|
439
|
+
hardDrive = new HardDrive();
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
public void start() {
|
|
443
|
+
cpu.start();
|
|
444
|
+
memory.start();
|
|
445
|
+
hardDrive.start();
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
public void shutdown() {
|
|
449
|
+
hardDrive.shutdown();
|
|
450
|
+
memory.shutdown();
|
|
451
|
+
cpu.shutdown();
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
**Pros**: Shields clients from subsystem components, promotes weak coupling
|
|
457
|
+
**Cons**: Can become a "god object"
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
### Composite
|
|
462
|
+
|
|
463
|
+
**Intent**: Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
|
|
464
|
+
|
|
465
|
+
**When to Use**:
|
|
466
|
+
- You want to represent part-whole hierarchies of objects
|
|
467
|
+
- You want clients to be able to ignore the difference between compositions and individual objects
|
|
468
|
+
|
|
469
|
+
**Structure**:
|
|
470
|
+
```
|
|
471
|
+
Component
|
|
472
|
+
↑
|
|
473
|
+
┌───┴───┐
|
|
474
|
+
Leaf Composite → Component
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
**Implementation**:
|
|
478
|
+
```java
|
|
479
|
+
public interface Component {
|
|
480
|
+
void operation();
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
public class Leaf implements Component {
|
|
484
|
+
public void operation() { }
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
public class Composite implements Component {
|
|
488
|
+
private List<Component> children = new ArrayList<>();
|
|
489
|
+
|
|
490
|
+
public void add(Component component) { children.add(component); }
|
|
491
|
+
public void remove(Component component) { children.remove(component); }
|
|
492
|
+
|
|
493
|
+
public void operation() {
|
|
494
|
+
for (Component child : children) {
|
|
495
|
+
child.operation();
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
**Pros**: Defines class hierarchies consisting of primitive and complex objects, makes client simpler
|
|
502
|
+
**Cons**: Can make design overly general
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
### Flyweight
|
|
507
|
+
|
|
508
|
+
**Intent**: Use sharing to support large numbers of fine-grained objects efficiently.
|
|
509
|
+
|
|
510
|
+
**When to Use**:
|
|
511
|
+
- An application uses a large number of objects
|
|
512
|
+
- Storage costs are high because of the sheer quantity of objects
|
|
513
|
+
|
|
514
|
+
**Structure**:
|
|
515
|
+
```
|
|
516
|
+
FlyweightFactory → Flyweight
|
|
517
|
+
↑
|
|
518
|
+
ConcreteFlyweight
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
**Implementation**:
|
|
522
|
+
```java
|
|
523
|
+
public interface Flyweight {
|
|
524
|
+
void operation(String extrinsicState);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
public class ConcreteFlyweight implements Flyweight {
|
|
528
|
+
private String intrinsicState;
|
|
529
|
+
|
|
530
|
+
public ConcreteFlyweight(String intrinsicState) {
|
|
531
|
+
this.intrinsicState = intrinsicState;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
public void operation(String extrinsicState) { }
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
public class FlyweightFactory {
|
|
538
|
+
private Map<String, Flyweight> flyweights = new HashMap<>();
|
|
539
|
+
|
|
540
|
+
public Flyweight getFlyweight(String key) {
|
|
541
|
+
if (!flyweights.containsKey(key)) {
|
|
542
|
+
flyweights.put(key, new ConcreteFlyweight(key));
|
|
543
|
+
}
|
|
544
|
+
return flyweights.get(key);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
**Pros**: Reduces storage, reduces search time
|
|
550
|
+
**Cons**: Increases complexity, may add runtime cost
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
### Bridge
|
|
555
|
+
|
|
556
|
+
**Intent**: Decouple an abstraction from its implementation so that the two can vary independently.
|
|
557
|
+
|
|
558
|
+
**When to Use**:
|
|
559
|
+
- You want to avoid a permanent binding between an abstraction and its implementation
|
|
560
|
+
- Both the abstractions and their implementations should be extensible by subclassing
|
|
561
|
+
|
|
562
|
+
**Structure**:
|
|
563
|
+
```
|
|
564
|
+
Abstraction → Implementor
|
|
565
|
+
↑ ↑
|
|
566
|
+
RefinedAbstraction ConcreteImplementor
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
**Implementation**:
|
|
570
|
+
```java
|
|
571
|
+
public interface DrawAPI {
|
|
572
|
+
void drawCircle(int radius, int x, int y);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
public class RedCircle implements DrawAPI {
|
|
576
|
+
public void drawCircle(int radius, int x, int y) { }
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
public abstract class Shape {
|
|
580
|
+
protected DrawAPI drawAPI;
|
|
581
|
+
|
|
582
|
+
protected Shape(DrawAPI drawAPI) {
|
|
583
|
+
this.drawAPI = drawAPI;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
public abstract void draw();
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
public class Circle extends Shape {
|
|
590
|
+
public Circle(DrawAPI drawAPI) {
|
|
591
|
+
super(drawAPI);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
public void draw() {
|
|
595
|
+
drawAPI.drawCircle(radius, x, y);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
**Pros**: Separates interface and implementation, improves extensibility
|
|
601
|
+
**Cons**: Increases complexity
|
|
602
|
+
|
|
603
|
+
---
|
|
604
|
+
|
|
605
|
+
## 3. Behavioral Patterns
|
|
606
|
+
|
|
607
|
+
### Strategy
|
|
608
|
+
|
|
609
|
+
**Intent**: Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
|
|
610
|
+
|
|
611
|
+
**When to Use**:
|
|
612
|
+
- Many related classes differ only in their behavior
|
|
613
|
+
- You need different variants of an algorithm
|
|
614
|
+
- An algorithm uses data that clients shouldn't know about
|
|
615
|
+
|
|
616
|
+
**Structure**:
|
|
617
|
+
```
|
|
618
|
+
Context → Strategy
|
|
619
|
+
↑
|
|
620
|
+
ConcreteStrategy
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
**Implementation**:
|
|
624
|
+
```java
|
|
625
|
+
public interface Strategy {
|
|
626
|
+
int doOperation(int num1, int num2);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
public class OperationAdd implements Strategy {
|
|
630
|
+
public int doOperation(int num1, int num2) {
|
|
631
|
+
return num1 + num2;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
public class Context {
|
|
636
|
+
private Strategy strategy;
|
|
637
|
+
|
|
638
|
+
public Context(Strategy strategy) {
|
|
639
|
+
this.strategy = strategy;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
public int executeStrategy(int num1, int num2) {
|
|
643
|
+
return strategy.doOperation(num1, num2);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
**Pros**: Eliminates conditional statements, provides different implementations
|
|
649
|
+
**Cons**: Clients must know about strategies
|
|
650
|
+
|
|
651
|
+
---
|
|
652
|
+
|
|
653
|
+
### Observer
|
|
654
|
+
|
|
655
|
+
**Intent**: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
|
|
656
|
+
|
|
657
|
+
**When to Use**:
|
|
658
|
+
- An abstraction has two aspects, one dependent on the other
|
|
659
|
+
- A change to one object requires changing others
|
|
660
|
+
- An object should be able to notify other objects without knowing who they are
|
|
661
|
+
|
|
662
|
+
**Structure**:
|
|
663
|
+
```
|
|
664
|
+
Subject → Observer
|
|
665
|
+
↑ ↑
|
|
666
|
+
ConcreteSubject ConcreteObserver
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
**Implementation**:
|
|
670
|
+
```java
|
|
671
|
+
public interface Observer {
|
|
672
|
+
void update(String state);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
public interface Subject {
|
|
676
|
+
void attach(Observer observer);
|
|
677
|
+
void detach(Observer observer);
|
|
678
|
+
void notifyObservers();
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
public class ConcreteSubject implements Subject {
|
|
682
|
+
private List<Observer> observers = new ArrayList<>();
|
|
683
|
+
private String state;
|
|
684
|
+
|
|
685
|
+
public void attach(Observer observer) { observers.add(observer); }
|
|
686
|
+
public void detach(Observer observer) { observers.remove(observer); }
|
|
687
|
+
|
|
688
|
+
public void setState(String state) {
|
|
689
|
+
this.state = state;
|
|
690
|
+
notifyObservers();
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
public void notifyObservers() {
|
|
694
|
+
for (Observer observer : observers) {
|
|
695
|
+
observer.update(state);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
**Pros**: Abstract coupling between Subject and Observer, support for broadcast communication
|
|
702
|
+
**Cons**: Unexpected updates, debugging difficulty
|
|
703
|
+
|
|
704
|
+
---
|
|
705
|
+
|
|
706
|
+
### Command
|
|
707
|
+
|
|
708
|
+
**Intent**: Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
|
|
709
|
+
|
|
710
|
+
**When to Use**:
|
|
711
|
+
- Parameterize objects by an action to perform
|
|
712
|
+
- Specify, queue, and execute requests at different times
|
|
713
|
+
- Support undo
|
|
714
|
+
- Support logging changes
|
|
715
|
+
|
|
716
|
+
**Structure**:
|
|
717
|
+
```
|
|
718
|
+
Invoker → Command ← Receiver
|
|
719
|
+
↑
|
|
720
|
+
ConcreteCommand
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
**Implementation**:
|
|
724
|
+
```java
|
|
725
|
+
public interface Command {
|
|
726
|
+
void execute();
|
|
727
|
+
void undo();
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
public class Light {
|
|
731
|
+
public void on() { }
|
|
732
|
+
public void off() { }
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
public class LightOnCommand implements Command {
|
|
736
|
+
private Light light;
|
|
737
|
+
|
|
738
|
+
public LightOnCommand(Light light) {
|
|
739
|
+
this.light = light;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
public void execute() { light.on(); }
|
|
743
|
+
public void undo() { light.off(); }
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
public class RemoteControl {
|
|
747
|
+
private Command command;
|
|
748
|
+
|
|
749
|
+
public void setCommand(Command command) {
|
|
750
|
+
this.command = command;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
public void pressButton() {
|
|
754
|
+
command.execute();
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
**Pros**: Decouples requester from performer, supports undo/redo
|
|
760
|
+
**Cons**: Many command classes
|
|
761
|
+
|
|
762
|
+
---
|
|
763
|
+
|
|
764
|
+
### State
|
|
765
|
+
|
|
766
|
+
**Intent**: Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
|
|
767
|
+
|
|
768
|
+
**When to Use**:
|
|
769
|
+
- An object's behavior depends on its state
|
|
770
|
+
- Operations have large, multipart conditional statements that depend on the object's state
|
|
771
|
+
|
|
772
|
+
**Structure**:
|
|
773
|
+
```
|
|
774
|
+
Context → State
|
|
775
|
+
↑
|
|
776
|
+
ConcreteState
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
**Implementation**:
|
|
780
|
+
```java
|
|
781
|
+
public interface State {
|
|
782
|
+
void handle(Context context);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
public class StartState implements State {
|
|
786
|
+
public void handle(Context context) {
|
|
787
|
+
System.out.println("In start state");
|
|
788
|
+
context.setState(new PlayingState());
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
public class Context {
|
|
793
|
+
private State state;
|
|
794
|
+
|
|
795
|
+
public Context() {
|
|
796
|
+
state = new StartState();
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
public void setState(State state) {
|
|
800
|
+
this.state = state;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
public void request() {
|
|
804
|
+
state.handle(this);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
**Pros**: Localizes state-specific behavior, makes state transitions explicit
|
|
810
|
+
**Cons**: Can result in many state classes
|
|
811
|
+
|
|
812
|
+
---
|
|
813
|
+
|
|
814
|
+
### Template Method
|
|
815
|
+
|
|
816
|
+
**Intent**: Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
|
|
817
|
+
|
|
818
|
+
**When to Use**:
|
|
819
|
+
- To implement the invariant parts of an algorithm once
|
|
820
|
+
- When common behavior among subclasses should be factored and localized
|
|
821
|
+
|
|
822
|
+
**Structure**:
|
|
823
|
+
```
|
|
824
|
+
AbstractClass ← ConcreteClass
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
**Implementation**:
|
|
828
|
+
```java
|
|
829
|
+
public abstract class Game {
|
|
830
|
+
// Template method
|
|
831
|
+
public final void play() {
|
|
832
|
+
initialize();
|
|
833
|
+
startPlay();
|
|
834
|
+
endPlay();
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
protected abstract void initialize();
|
|
838
|
+
protected abstract void startPlay();
|
|
839
|
+
protected abstract void endPlay();
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
public class Cricket extends Game {
|
|
843
|
+
protected void initialize() { System.out.println("Cricket initialized"); }
|
|
844
|
+
protected void startPlay() { System.out.println("Cricket started"); }
|
|
845
|
+
protected void endPlay() { System.out.println("Cricket finished"); }
|
|
846
|
+
}
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
**Pros**: Code reuse, common behavior in one place
|
|
850
|
+
**Cons**: Can be restrictive
|
|
851
|
+
|
|
852
|
+
---
|
|
853
|
+
|
|
854
|
+
### Chain of Responsibility
|
|
855
|
+
|
|
856
|
+
**Intent**: Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
|
|
857
|
+
|
|
858
|
+
**When to Use**:
|
|
859
|
+
- More than one object may handle a request
|
|
860
|
+
- You want to issue a request to one of several objects without specifying the receiver explicitly
|
|
861
|
+
|
|
862
|
+
**Structure**:
|
|
863
|
+
```
|
|
864
|
+
Handler → Handler
|
|
865
|
+
↑
|
|
866
|
+
ConcreteHandler
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
**Implementation**:
|
|
870
|
+
```java
|
|
871
|
+
public abstract class Handler {
|
|
872
|
+
protected Handler next;
|
|
873
|
+
|
|
874
|
+
public Handler setNext(Handler next) {
|
|
875
|
+
this.next = next;
|
|
876
|
+
return next;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
public abstract void handleRequest(int level);
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
public class LowHandler extends Handler {
|
|
883
|
+
public void handleRequest(int level) {
|
|
884
|
+
if (level <= 1) {
|
|
885
|
+
System.out.println("Low handler handles request");
|
|
886
|
+
} else if (next != null) {
|
|
887
|
+
next.handleRequest(level);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
**Pros**: Reduces coupling, adds flexibility
|
|
894
|
+
**Cons**: No guarantee of handling
|
|
895
|
+
|
|
896
|
+
---
|
|
897
|
+
|
|
898
|
+
### Mediator
|
|
899
|
+
|
|
900
|
+
**Intent**: Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly.
|
|
901
|
+
|
|
902
|
+
**When to Use**:
|
|
903
|
+
- A set of objects communicate in well-defined but complex ways
|
|
904
|
+
- You want to customize a behavior that's distributed between several objects
|
|
905
|
+
|
|
906
|
+
**Structure**:
|
|
907
|
+
```
|
|
908
|
+
Mediator
|
|
909
|
+
↑
|
|
910
|
+
ConcreteMediator ← Colleague
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
**Implementation**:
|
|
914
|
+
```java
|
|
915
|
+
public interface Mediator {
|
|
916
|
+
void notify(Component sender, String event);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
public class ConcreteMediator implements Mediator {
|
|
920
|
+
private ComponentA componentA;
|
|
921
|
+
private ComponentB componentB;
|
|
922
|
+
|
|
923
|
+
public void notify(Component sender, String event) {
|
|
924
|
+
if (event.equals("A")) {
|
|
925
|
+
componentB.reactOnA();
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
**Pros**: Limits subclassing, decouples colleagues
|
|
932
|
+
**Cons**: Mediator can become complex
|
|
933
|
+
|
|
934
|
+
---
|
|
935
|
+
|
|
936
|
+
### Iterator
|
|
937
|
+
|
|
938
|
+
**Intent**: Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
|
|
939
|
+
|
|
940
|
+
**When to Use**:
|
|
941
|
+
- To access an aggregate object's contents without exposing its internal representation
|
|
942
|
+
- To support multiple traversals of aggregate objects
|
|
943
|
+
|
|
944
|
+
**Structure**:
|
|
945
|
+
```
|
|
946
|
+
Aggregate → Iterator
|
|
947
|
+
↑ ↑
|
|
948
|
+
ConcreteAggregate ConcreteIterator
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
**Implementation**:
|
|
952
|
+
```java
|
|
953
|
+
public interface Iterator<T> {
|
|
954
|
+
boolean hasNext();
|
|
955
|
+
T next();
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
public interface Aggregate<T> {
|
|
959
|
+
Iterator<T> createIterator();
|
|
960
|
+
}
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
**Pros**: Supports variations in traversal, simplifies aggregate interface
|
|
964
|
+
**Cons**: Can be overkill for simple collections
|
|
965
|
+
|
|
966
|
+
---
|
|
967
|
+
|
|
968
|
+
### Memento
|
|
969
|
+
|
|
970
|
+
**Intent**: Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.
|
|
971
|
+
|
|
972
|
+
**When to Use**:
|
|
973
|
+
- A snapshot of an object's state must be saved so that it can be restored later
|
|
974
|
+
- A direct interface to obtaining the state would expose implementation details
|
|
975
|
+
|
|
976
|
+
**Structure**:
|
|
977
|
+
```
|
|
978
|
+
Originator ← Memento → Caretaker
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
**Implementation**:
|
|
982
|
+
```java
|
|
983
|
+
public class Memento {
|
|
984
|
+
private String state;
|
|
985
|
+
|
|
986
|
+
public Memento(String state) {
|
|
987
|
+
this.state = state;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
public String getState() { return state; }
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
public class Originator {
|
|
994
|
+
private String state;
|
|
995
|
+
|
|
996
|
+
public void setState(String state) { this.state = state; }
|
|
997
|
+
|
|
998
|
+
public Memento saveStateToMemento() {
|
|
999
|
+
return new Memento(state);
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
public void getStateFromMemento(Memento memento) {
|
|
1003
|
+
state = memento.getState();
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
**Pros**: Preserves encapsulation boundaries, simplifies originator
|
|
1009
|
+
**Cons**: Can be expensive
|
|
1010
|
+
|
|
1011
|
+
---
|
|
1012
|
+
|
|
1013
|
+
### Visitor
|
|
1014
|
+
|
|
1015
|
+
**Intent**: Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
|
|
1016
|
+
|
|
1017
|
+
**When to Use**:
|
|
1018
|
+
- An object structure contains many classes with differing interfaces
|
|
1019
|
+
- Many distinct and unrelated operations need to be performed on objects
|
|
1020
|
+
|
|
1021
|
+
**Structure**:
|
|
1022
|
+
```
|
|
1023
|
+
Visitor → Element
|
|
1024
|
+
↑ ↑
|
|
1025
|
+
ConcreteVisitor ConcreteElement
|
|
1026
|
+
```
|
|
1027
|
+
|
|
1028
|
+
**Implementation**:
|
|
1029
|
+
```java
|
|
1030
|
+
public interface Visitor {
|
|
1031
|
+
void visit(ConcreteElementA element);
|
|
1032
|
+
void visit(ConcreteElementB element);
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
public interface Element {
|
|
1036
|
+
void accept(Visitor visitor);
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
public class ConcreteElementA implements Element {
|
|
1040
|
+
public void accept(Visitor visitor) {
|
|
1041
|
+
visitor.visit(this);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
```
|
|
1045
|
+
|
|
1046
|
+
**Pros**: Easy to add new operations, gathers related behavior
|
|
1047
|
+
**Cons**: Hard to add new element classes
|
|
1048
|
+
|
|
1049
|
+
---
|
|
1050
|
+
|
|
1051
|
+
## 4. Pattern Selection Guide
|
|
1052
|
+
|
|
1053
|
+
### By Problem Type
|
|
1054
|
+
|
|
1055
|
+
| Problem | Pattern |
|
|
1056
|
+
|---------|---------|
|
|
1057
|
+
| Need single instance | Singleton |
|
|
1058
|
+
| Create objects flexibly | Factory Method |
|
|
1059
|
+
| Create object families | Abstract Factory |
|
|
1060
|
+
| Build complex objects | Builder |
|
|
1061
|
+
| Clone objects | Prototype |
|
|
1062
|
+
| Incompatible interfaces | Adapter |
|
|
1063
|
+
| Add responsibilities dynamically | Decorator |
|
|
1064
|
+
| Control access | Proxy |
|
|
1065
|
+
| Simplify complex interface | Facade |
|
|
1066
|
+
| Tree structures | Composite |
|
|
1067
|
+
| Share common state | Flyweight |
|
|
1068
|
+
| Separate abstraction from implementation | Bridge |
|
|
1069
|
+
| Switch algorithms | Strategy |
|
|
1070
|
+
| Event notification | Observer |
|
|
1071
|
+
| Encapsulate requests | Command |
|
|
1072
|
+
| State-dependent behavior | State |
|
|
1073
|
+
| Algorithm skeleton | Template Method |
|
|
1074
|
+
| Multiple handlers | Chain of Responsibility |
|
|
1075
|
+
| Complex interactions | Mediator |
|
|
1076
|
+
| Traverse collections | Iterator |
|
|
1077
|
+
| Save/restore state | Memento |
|
|
1078
|
+
| Add operations to structure | Visitor |
|
|
1079
|
+
|
|
1080
|
+
### By Code Smell
|
|
1081
|
+
|
|
1082
|
+
| Code Smell | Pattern Solution |
|
|
1083
|
+
|------------|------------------|
|
|
1084
|
+
| Large switch statements | State, Strategy |
|
|
1085
|
+
| Many conditionals | Strategy, State, Null Object |
|
|
1086
|
+
| Tight coupling | Observer, Mediator, Facade |
|
|
1087
|
+
| Hard to create objects | Factory, Builder |
|
|
1088
|
+
| Can't extend classes | Decorator, Adapter |
|
|
1089
|
+
| Complex subsystems | Facade |
|
|
1090
|
+
| Need to vary algorithms | Strategy, Template Method |
|
|
1091
|
+
| Many similar objects | Flyweight, Prototype |
|
|
1092
|
+
| Need to notify objects | Observer |
|
|
1093
|
+
| Need to encapsulate requests | Command |
|
|
1094
|
+
|
|
1095
|
+
### Pattern Relationships
|
|
1096
|
+
|
|
1097
|
+
```
|
|
1098
|
+
Creational ← → Structural ← → Behavioral
|
|
1099
|
+
│ │ │
|
|
1100
|
+
▼ ▼ ▼
|
|
1101
|
+
Factory Adapter Strategy
|
|
1102
|
+
Abstract Decorator Observer
|
|
1103
|
+
Singleton Proxy Command
|
|
1104
|
+
Builder Facade State
|
|
1105
|
+
Prototype Composite Template
|
|
1106
|
+
Flyweight Chain
|
|
1107
|
+
Bridge Mediator
|
|
1108
|
+
Iterator
|
|
1109
|
+
Memento
|
|
1110
|
+
Visitor
|
|
1111
|
+
```
|