Skip to content

Commit 41267fc

Browse files
committed
Merge branch 'develop'
2 parents 723c557 + dc28323 commit 41267fc

9 files changed

Lines changed: 323 additions & 11 deletions

File tree

WebSite/content/blog/blog_00026.en.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,4 @@ Combined with screen sharing and channel-based organization, the experience can
108108
One can only hope that more members of one's environment adopt Zed...
109109
Even without that, Zed remains an excellent IDE, but for this specific feature, broader adoption would enhance its utility.
110110

111-
Wishing you a productive and pleasant experience using Zed.
111+
Wishing you a productive and pleasant experience using Zed.

WebSite/content/blog/blog_00028.en.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,4 +355,4 @@ sequenceDiagram
355355

356356
That’s it for this article. Next time we'll cover another GoF pattern with C++ examples and mermaid diagrams. The implementations shown here are simplified for learning; evaluate requirements (threads, lifecycle, testability) carefully before adopting in production.
357357

358-
— Pan-kun
358+
Thanks for reading — Pan-kun!

WebSite/content/blog/blog_00028.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,10 @@ s0.Say();
337337

338338
## まとめ
339339

340-
- シングルトンは「ただ1つのインスタンス」を保証する便利なパターンだが、設計上のトレードオフを必ず考慮する必要があります
341-
- C++ では C++11 以降の関数内静的変数(Meyers')がお手軽で安全な実装方法の一つである
342-
- 明示的な制御が必要な場合は `std::call_once` を使うと良い
343-
- 大規模なシステムやテスト性が重視されるシステムでは、依存性注入やファクトリなどの手法を検討することを推奨する
340+
シングルトンは「ただ1つのインスタンス」を保証する便利なパターンだが、設計上のトレードオフを必ず考慮する必要があります
341+
C++ では C++11 以降の関数内静的変数(Meyers')がお手軽で安全な実装方法の一つです。
342+
明示的な制御が必要な場合は `std::call_once` を使うと良いでしょう。
343+
大規模なシステムやテスト性が重視されるシステムでは、依存性注入やファクトリなどの手法を検討することを推奨します。
344344

345345
参考・出典を記します
346346

WebSite/content/blog/blog_00029.en.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,4 @@ References:
235235

236236
That's it—stay tuned for future articles covering Abstract Factory, Builder, and other creational patterns. The sample code here is simplified for learning; evaluate carefully before adopting patterns in production.
237237
238-
— Pan-kun
238+
Thanks for reading — Pan-kun!

WebSite/content/blog/blog_00030.en.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,4 +242,4 @@ References (primary)
242242

243243
That's it — I'll cover another GoF pattern next time. The sample code here is simplified for learning; evaluate and adapt thoroughly before using in production.
244244

245-
— Pan-kun!
245+
Thanks for reading — Pan-kun!

WebSite/content/blog/blog_00031.en.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,4 @@ References:
162162
163163
I'll cover another GoF pattern next time. The code samples shown here are simplified for learning purposes — review and adapt them to your production requirements before use.
164164
165-
That's all from Pan-kun!
165+
Thanks for reading — Pan-kun!

WebSite/content/other/blog_00032.en.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ recommended: true
88
thumbnail: assets/img/ogp.png
99
---
1010

11-
Hello! Pan here.
11+
Hello! I'm Pan-kun.
1212

1313
This post covers the Builder pattern from the GoF (Gang of Four) design patterns.
1414
I explain it practically with sample code in C++, how to design it, when to apply it, and important caveats.
@@ -135,4 +135,4 @@ References and sources:
135135
136136
That's it for this post. Next time I'll cover another GoF pattern. The code shown here is simplified for learning purposes — when adopting patterns in production, make sure to adapt them to your project requirements.
137137
138-
Thanks for reading — Pan.
138+
Thanks for reading — Pan-kun!
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
---
2+
title: GoF Design Patterns - Adapter
3+
date: 2026-02-04
4+
category: Coding
5+
description: A practical guide to the Adapter pattern from the GoF collection:concepts, when to use it, a C++ implementation example, implementation notes, and references.
6+
tags: [Coding, DesignPattern]
7+
recommended: true
8+
thumbnail: assets/img/ogp.png
9+
---
10+
11+
Hello! I'm Pan-kun.
12+
13+
This post covers the Adapter pattern from the GoF (Gang of Four) design patterns.
14+
I explain it practically, including a C++ sample, how to implement it, when to use it, pitfalls to watch out for, and a Mermaid diagram for visualization.
15+
16+
## Introduction
17+
18+
The Adapter pattern provides a wrapper that connects incompatible interfaces, allowing an existing class to be adapted to the interface expected by clients.
19+
20+
Benefits:
21+
- You can adapt existing code or third-party libraries to a new interface without changing their implementation.
22+
23+
Drawbacks:
24+
- Proliferation of wrappers can scatter design responsibilities and reduce readability and maintainability.
25+
- The added indirection can also introduce runtime overhead.
26+
27+
## Use cases
28+
29+
Common scenarios where you would create an Adapter include:
30+
31+
- Integrating a legacy API or library into a new application interface.
32+
- When different modules expose incompatible interfaces but you cannot modify the existing implementation.
33+
- Creating a thin boundary that makes it easy to swap implementations during testing (though using mocks can be simpler when applicable).
34+
35+
## Structure
36+
37+
An Adapter implements the Target interface and internally invokes the Adaptee's operations while performing any required conversions.
38+
39+
```mermaid
40+
classDiagram
41+
class Target {
42+
<<interface>>
43+
+request()
44+
}
45+
class Adaptee {
46+
+specificRequest(params)
47+
}
48+
class Adapter {
49+
+Adapter(adaptee)
50+
+request()
51+
}
52+
Target <|.. Adapter
53+
Adapter o-- Adaptee : adapts
54+
```
55+
56+
## C++ implementation example
57+
58+
Below is a concise C++ example.
59+
60+
```cpp
61+
// Example: the client expects to call Target::request()
62+
struct Target {
63+
virtual ~Target() = default;
64+
virtual void request() = 0; // method the client expects
65+
};
66+
67+
// Existing (unchangeable) class
68+
class Adaptee {
69+
public:
70+
void specificRequest(const std::string& params) {
71+
// Complex call in an existing API
72+
std::cout << "Adaptee::specificRequest with " << params << std::endl;
73+
}
74+
};
75+
76+
// Adapter: implements Target while adapting Adaptee
77+
class Adapter : public Target {
78+
public:
79+
explicit Adapter(std::shared_ptr<Adaptee> adaptee)
80+
: adaptee_(std::move(adaptee)) {}
81+
82+
void request() override {
83+
// Perform necessary translation before calling adaptee
84+
std::string translated = translate();
85+
adaptee_->specificRequest(translated);
86+
}
87+
88+
private:
89+
std::string translate() {
90+
// Actual translation logic; simplified here.
91+
return "translated-params";
92+
}
93+
94+
std::shared_ptr<Adaptee> adaptee_;
95+
};
96+
97+
// main.cpp usage
98+
auto adaptee = std::make_shared<Adaptee>();
99+
std::unique_ptr<Target> target = std::make_unique<Adapter>(adaptee);
100+
target->request(); // the client only knows Target
101+
```
102+
103+
Key points:
104+
- Perform data-format conversion, error handling, and method mapping as needed.
105+
- There are inheritance-based and delegation-based adapters; choose according to your use case.
106+
In short: inheritance-based adapters leverage class inheritance, while delegation-based adapters implement an interface and forward calls to a contained object.
107+
108+
## Implementation notes
109+
110+
1. Keep translations simple
111+
- Avoid loading the Adapter with excessive logic or business rules; that inflates its responsibility.
112+
- If possible, extract translation logic into a separate module.
113+
114+
2. Make ownership and lifecycle explicit
115+
- In C++, pointer types determine the relationship between Adapter and Adaptee.
116+
- Manage ownership clearly to avoid leaks and double frees.
117+
118+
3. Consider performance
119+
- Heavy translations on hot paths become performance bottlenecks.
120+
- Consider caching translated results when appropriate.
121+
122+
4. Preserve testability
123+
- A thin Adapter is easier to unit-test.
124+
- Make Adaptee mockable where practical.
125+
126+
5. Provide logging and robust error handling
127+
128+
## Common anti-patterns
129+
130+
Typical bad practices when applying this pattern:
131+
132+
- Putting substantial domain logic into the Adapter.
133+
- Adding Adapter layers indiscriminately across a project, deepening call chains.
134+
- Ignoring semantics lost during conversion or exceptional cases thrown by the adaptee.
135+
136+
## Practical adoption checklist
137+
138+
- Can you modify the existing code directly? If not, an Adapter is a reasonable choice.
139+
- Is the translation logic simple? If it's complex, consider an intermediary service or a Facade.
140+
- Do frequency and performance constraints tolerate the translation cost? If not, evaluate alternative designs.
141+
- Is there a test strategy? Ensure you can use mocks or integration tests as needed.
142+
143+
## Conclusion
144+
145+
The Adapter is a practical and commonly used pattern for bridging incompatible interfaces. However, careless proliferation of Adapters can complicate design. Make responsibilities explicit and localize translation logic when you use this pattern.
146+
Pay special attention to ownership, exception and error handling, performance, and testability when implementing an Adapter.
147+
148+
References:
149+
150+
[!CARD](https://sourcemaking.com/design_patterns/adapter)
151+
152+
[!CARD](https://en.wikipedia.org/wiki/Adapter_pattern)
153+
154+
That's it for now — next time I'll cover another GoF pattern.
155+
The examples in this article are simplified for learning purposes; evaluate them carefully against your requirements before adopting them in production.
156+
157+
Thanks for reading — Pan-kun!
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
---
2+
title: GoFデザインパターン - アダプタ編
3+
date: 2026-02-04
4+
category: Coding
5+
description: GoFコレクションにおけるアダプタパターン実践ガイド:概念、使いどころ、C++の実装例、注意点と出典を実用的に解説します
6+
tags: [Coding, DesignPattern]
7+
recommended: true
8+
thumbnail: assets/img/ogp.png
9+
---
10+
11+
こんにちは、パン君です。
12+
13+
今回は GoF(Gang of Four)のデザインパターンのアダプタ編になります。
14+
サンプルコード(C++)、作り方、使うタイミング、注意点、mermaid図による可視化などを含めて実用的に解説します。
15+
16+
## はじめに
17+
18+
アダプタは互換性のないインターフェース同士をつなぐ ラッパー を提供し、クライアントが期待するインターフェースに既存のクラスを適合させるためのデザインパターンです。
19+
20+
利点としては
21+
既存コードや外部ライブラリを変更せずに新しいインターフェースへ適合できることです。
22+
23+
欠点は
24+
ラッパーが増えると設計が分散し可読性や保守性の低下を招くことです。
25+
また、間接化によるランタイムのコスト増も発生します。
26+
27+
## ユースケース
28+
29+
代表的に下記のようなケースで作成されるパターンです。  
30+
31+
- 古い API / ライブラリを新しいアプリケーションインターフェースに統合したいとき。
32+
- 異なるモジュール間でインターフェースの不一致があるが、既存実装を変更できないとき。
33+
- テスト時に実装を差し替えるための薄い境界を作りたいとき(ただし Mock を使える場合はそちらの方が簡潔な場合もある)。
34+
35+
## 構造
36+
37+
Adapter は Target のインターフェースを実装し、内部で Adaptee の操作を呼び出して必要な変換を行います。
38+
39+
```mermaid
40+
classDiagram
41+
class Target {
42+
<<interface>>
43+
+request()
44+
}
45+
class Adaptee {
46+
+specificRequest(params)
47+
}
48+
class Adapter {
49+
+Adapter(adaptee)
50+
+request()
51+
}
52+
Target <|.. Adapter
53+
Adapter o-- Adaptee : adapts
54+
```
55+
56+
## C++ 実装パターン
57+
58+
以下は簡潔な C++ の例です。
59+
60+
```cpp
61+
// 例: クライアントは Target::request() を使うことを期待している
62+
struct Target {
63+
virtual ~Target() = default;
64+
virtual void request() = 0; // クライアントが期待するメソッド
65+
};
66+
67+
// 既存の(変更できない)クラス
68+
class Adaptee {
69+
public:
70+
void specificRequest(const std::string& params) {
71+
// 既存 API の複雑な呼び出し
72+
std::cout << "Adaptee::specificRequest with " << params << std::endl;
73+
}
74+
};
75+
76+
// Adapter: Target を実装しつつ Adaptee を適合させる
77+
class Adapter : public Target {
78+
public:
79+
explicit Adapter(std::shared_ptr<Adaptee> adaptee)
80+
: adaptee_(std::move(adaptee)) {}
81+
82+
void request() override {
83+
// 必要な変換を行ってから adaptee を呼ぶ
84+
std::string translated = translate();
85+
adaptee_->specificRequest(translated);
86+
}
87+
88+
private:
89+
std::string translate() {
90+
// 実際の変換ロジック。ここでは単純化。
91+
return "translated-params";
92+
}
93+
94+
std::shared_ptr<Adaptee> adaptee_;
95+
};
96+
97+
// main.cpp
98+
auto adaptee = std::make_shared<Adaptee>();
99+
std::unique_ptr<Target> target = std::make_unique<Adapter>(adaptee);
100+
target->request(); // クライアントは Target のみを意識する
101+
```
102+
103+
ポイントとして
104+
必要に応じてデータ形式の変換、エラーハンドリング、複数メソッドのマッピングを行うようにしましょう。
105+
また、継承ベースと委譲ベースがありますが、ユースケースに寄って使い分けしてください。
106+
端的に説明すると、継承ベースはクラスの継承を活用し、委譲ベースはインターフェースの実装です。
107+
108+
## 実装上の注意点
109+
110+
1. 単純な変換に留める
111+
Adapter に過度のロジックやビジネスルールを詰め込みすぎると責務が肥大化します。
112+
可能なら変換ロジックは別モジュールに切り出しましょう。
113+
2. 所有権とライフサイクルを明確にする
114+
C++ ではポインタの種類により Adapter と Adaptee の関係が変わります。
115+
リーク・二重解放を避けるために明示的に管理しましょう。
116+
3. パフォーマンスの考慮
117+
頻繁に呼ばれるパスで重い変換を行うと性能ボトルネックになります。
118+
必要なら変換済みキャッシュを検討しましょう。
119+
4. テストしやすさを保つ
120+
Adapter を薄く保つことで単体テストが簡単になります。
121+
Adaptee をモック可能にしておくと良いです。
122+
5. ログ・エラーハンドリングを整備する
123+
124+
## よくあるアンチパターン
125+
126+
下記はこのデザインパターンを利用する際に起きる悪い例です。
127+
128+
- Adapter に大量のドメインロジックを入れる。
129+
- プロジェクト全体で無差別に Adapter 層を追加してしまい、呼び出しチェーンが深くなる。
130+
- 変換で失われる意味や例外ケースを無視する。
131+
132+
## 実務での採用判断チェックリスト
133+
134+
- 既存コードを直接変更できないか?(変更不可なら Adapter が妥当)
135+
- 変換ロジックは単純か? 複雑なら中間サービスやファサードでの整理が必要か?
136+
- 頻度・性能要件は許容できるか?(変換コストが高ければ別設計を検討)
137+
- テスト戦略は確立できるか?(Mock や Integration テストの整備)
138+
139+
## まとめ
140+
141+
アダプタは「互換性のないインターフェースを橋渡しする」ための実用的かつよく使われるパターンです。
142+
ただし、Adapter を安易に量産すると設計が複雑化するため、責務を明確にし変換ロジックを局所化して使うことが重要です。
143+
実装では所有権、例外・エラー、性能、テストのしやすさを特に注意してください。
144+
145+
参考・出典を記します
146+
147+
[!CARD](https://sourcemaking.com/design_patterns/adapter)
148+
149+
[!CARD](https://en.wikipedia.org/wiki/Adapter_pattern )
150+
151+
それでは、次回は別の GoF パターンについても解説していきます。
152+
この記事で紹介した実装は学習目的に簡素化しています。
153+
実プロダクションで採用する際は要件に合わせて十分に検討してください。
154+
155+
以上、パン君でした!

0 commit comments

Comments
 (0)