C言語で「生産性」や「信頼性」のあるコードを書きたいと考えている方のために、GoFのデザインパターンをC言語で実装したサンプルコードを提供します。
C言語でオブジェクト指向の考え方を用いることが「生産性」や「信頼性」に有効であることは、すでに認知されていると思いますが、デザインパターンを使いこなすことで、オブジェクト指向をより効果的に使えるようになります。
そこで本記事ではGoFのデザインパターンを題材とし、C言語の場合どのように適用していけばよいのかサンプルコードと合わせて解説・紹介していきます。
前準備
C言語でオブジェクト指向
GoFのデザインパターンはオブジェクト指向が前提となっていますので、C言語でのオブジェクト指向の書き方を学んでおく必要があります。
ネット上でもいくつか記事があるので、それを読んでいただいても構いませんが、書籍で体系立って学んだ方が効率的です。おすすめの書籍が2冊ありますので、ご紹介しますね。
『モダンC言語プログラミング』の方が開発環境まで話が入っているので、内容の幅広さはこちらの方が上です。しかし、オブジェクト指向の基本的な解説は少なめです。
『テスト駆動開発による組み込みプログラミング』の方がオブジェクト指向の解説が手厚いです。ネット上ではこちらの方が人気な気がします。
どちらか一冊でも十分ですが、余裕があれば両方読んでみてください。
GoFのデザインパターン
GoFのデザインパターンの解説はTECHSCOREさんの記事が秀逸です。これを読むことでオブジェクト指向とデザインパターンの素晴らしさを理解できます。
サンプルコードはJavaで書かれていますが、簡単なコードですし解説も丁寧なので、Javaがわからなくても理解しやすいでしょう。
本記事ではTECHSCOREさんのサンプルコードをベースにして、C言語に移植していきます。GoFのデザインパターンを知っている人も知らない人も、一度目を通してから後述の記事を読んでください。
https://www.techscore.com/tech/DesignPattern/index.html/
TECHSCOREさんのJava版のコードと、本記事のC言語版のコードを比較することで、よりC言語でのデザインパターンの適用方法が理解しやすくなるでしょう。
GoFのデザインパターンのC言語サンプル
TECHSCOREさんの記事の順番に合わせて並べておきました。順番に読んでも良いですし、必要な箇所だけ掻い摘んでいただいても構いません。
パターン | 記事 |
1. Iterator | C言語でIteratorパターン |
2. Adapter | C言語でAdapterパターン |
3. TemplateMethod | C言語でTemplateMethodパターン |
4. FactoryMethod | C言語でFactoryMethodパターン |
5. Singleton | C言語でSingletonパターン |
5. Prototype | C言語でPrototypeパターン |
7. Builder | C言語でBuilderパターン |
8. AbstractFactory | C言語でAbstractFactoryパターン |
9. Bridge | C言語でBridgeパターン |
10. Strategy | C言語でStrategyパターン |
11. Composite | 準備中 |
12. Decorator | 準備中 |
13. Visitor | 準備中 |
14. ChainOfResponsibility | 準備中 |
15. Facade | 準備中 |
16. Mediator | 準備中 |
17. Observer | 準備中 |
18. Memento | 準備中 |
19. State | 準備中 |
20. Flyweight | 準備中 |
21. Proxy | 準備中 |
22. Command | 準備中 |
23. Interpreter | 準備中 |
ソースコードは全てGitHubに置いてありますので自由にご利用ください。
https://github.com/yuksblog/c_gof_design_pattern
C言語でデザインパターンを採用する際の注意点
2つほど注意していただきたいことがあります。
1つ目は、なんでもかんでもデザインパターンを適用すれば良いというわけではないですよ、ということです。
デザインパターンありきの設計ではなく、アプリケーションの本来あるべき姿を明確にし、適切な箇所に適切なパターンを使いましょう。これはデザインパターンを学ぶ時に良く言われることですね。そうは言ってもついつい忘れてしまいがちなので、再度認識しておきましょう。
2つ目は、デザインパターンを適用する際、サンプルコードの形にこだわり過ぎず柔軟に設計してくださいね、ということです。
C言語はオブジェクト指向言語ではないので、JavaやC#などと似た書き方はできても、完全に同じことはできません。代表的なところでは多重継承は実現は難しいですよね。でも、デザインパターンはインタフェースをよく使うので、複数パターンの採用時には多重継承を使いたくなることは往々にしてあります。
そんな時どうすれば良いでしょうか?私だったら重要でない方のインタフェースをやめてしまいます。例えば、IteratorパターンのAggregate.iterator()メソッドはインタフェースでなくても、そんなに困らないですよね?確かに再利用性は落ちますが、影響は小さいはずです。
こういったことは他にも出てくるかもしれませんが、その都度、どういった形で適用するのがよいか、頭を柔らかくして考えてみてくださいね。
では、良きデザインパターン・ライフを送ってください。