[rtoc_mokuji title="" title_display="" heading="h3" list_h2_type="" list_h3_type="" display="" frame_design="" animation=""]
デザインパターンとは。勉強することでどんなメリットがあるか

デザインパターンとは、オブジェクト指向をどのように使えば、効率的に再利用性の高いコードを作成することができるのか、そのパターンをまとめたものです。
生成に関するパターン、構造に関するパターン、振る舞いに関するパターンの3つに分類されています。
- 生成に関するパターン
| 名前 | 概要 |
|---|---|
| Builder | あるオブジェクトを作成する場合に作成するクラスと作成されるクラスに分ける |
| Singleton | 一度しかインスタンスを作成できないことを保証して、再作成時に一度作成したインスタンスを返す |
| Prototype | 原型の意味。インスタンスのコピーを作成する |
| Factory Method | Builderと似ていて、作成するクラスと作成されるクラスを分ける。作成するクラスと作成されるクラスは、それぞれ継承したサブクラスを持ち、作成する側とされる側でサブクラス同士を対応づける |
| Abstract Factory | Factory Methodをより複雑化したもの |
- 構造に関するパターン
| 名前 | 概要 |
|---|---|
| Adapter | クラスとクラスをつないで、クラス間の違いを解消する |
| Bridge | ある機能をもつクラスのインタフェース間をつないで、機能追加を行う |
| Composite | 階層構造を用いて、ディレクトリ、ファイルのように、あるクラスのインスタンスに別のクラスのインスタンスを入れられるようにする |
| Decorate | あるクラスの処理に別のクラスのもつ特定の処理を追加する |
| Facade | ユーザから呼び出されて、各クラスの処理を呼び出し、クラスの関連しあった複雑な処理を実現する |
- 振る舞いに関するパターン
| 名前 | 概要 |
|---|---|
| Chain Of Responsibility | 複数のクラスの処理をつないで、インプットのチェックなどを行う |
| Command | コマンドをコントローラに設定して、中身を意識せず実行できるようにする |
| Interpreter | 階層構造を用いて、SQLなどの規則性のある構文を解釈する |
| Iterator | ループさせて、集合の中身の要素を取り出す |
| Mediator | オブジェクト間の仲介となってオブジェクト同士のデータの受け渡しなどを行う |
| Memento | オブジェクトのバックアップを作成して、元に戻せるようにする |
| Observer | オブジェクトを監視して、状態に変更がないか確認する。 |
| State | 状態(朝、昼、夜など)に応じて、処理をわけて実行する |
| Strategy | ユーザが選択した戦略(ゲームのコンピュータの強さなど)に応じて、処理をわけて実行する |
| Template Method | 外部からは同じインターフェースを提供して、同じように呼び出されるようにして具体的な処理はサブクラス内に定義し、場合に応じて内部で実行される処理を変える |
| Visitor | 既存のクラスに対して、新たな操作を追加したいしたり、特に複数のクラスにまたがった処理を作成したりする。 |
pythonでもdecorator関数などデコレータパターンは標準で用意されていますが、他にも実装して使うことがあります。
デザインパターンは、プログラマとして覚えておくべきことです。
ソフトウェア開発の初期において、同じような問題が生じることがよく発生しました。
それらの問題に対して解決策を与えたのがデザインパターンです。
GoF(ギャング・オブ・フォー)と呼ばれるソフトウェアエンジニアの4人によって作成されました。
デザインパターンを知ることで以下のメリットがあります。
- 言うまでも、作成するコードを改善することができ、きれいなコードを書くことができるようになります
- 他の開発者と意識を合わせることができます。つまり、「ここの実装は○○パターンを用いよう」という会話で認識を合わせられます。逆にデザインパターンを知らないとプログラマとのハイレベルな会話に参加できないかもしれません。
- 面接などで聞かれた場合に、答えることができます。
Pythonでデザインパターンをする上で覚えておくこと(抽象クラス、インタフェース)

インタフェースとは、メソッドが全て抽象メソッドとなっているクラスです。
Pythonの抽象クラスとインタフェースは、Javaのようにabstract, interfaceなどと言った予約語があるわけではなくて、標準ライブラリのabcクラスを継承する必要があります。
つまり、
from abc import ABC あるいは、 from abc import ABCMetaでインポートして、
class ClassA(ABC) もしくは、class ClassA(metaclass=ABCMeta)とクラスを宣言すると、そのクラスを抽象クラスとして定義できるようになります。
実際にコードを見ていきましょう。
- 抽象基底クラスのサンプルコード
abstractproperty, abstractmethod, abstractclassmethod,
abstractstaticmethod, ABC, ABCMeta
)
class BaseAbstractClass(ABC): # 抽象クラスとして宣言
# class BaseAbstractClass(metaclass=ABCMeta)でもよい
@abstractproperty # 抽象プロパティ(継承先で初めて定義される)
def value(self):
pass
@abstractmethod # 抽象インスタンスメソッド(継承先で初めて定義される)
def print_value(self):
pass
@abstractclassmethod # 抽象クラスメソッド(継承先で初めて定義される)
def write_value(cls, value):
pass
@abstractstaticmethod # 抽象スタティックメソッド(継承先で初めて定義される)
def print_static():
pass
class MyClass(BaseAbstractClass): # 抽象クラスを継承する
_value = 'Default Value'
@property
def value(self): # プロパティを実装(これを実装しないとエラーになります)
return self._value
def print_value(self): # インスタンスメソッドを実装(これを実装しないとエラーになります)
print('value = {}'.format(self.value))
@classmethod # クラスメソッドを実装(これを実装しないとエラーになります)
def write_value(cls, value):
with open('tmp.txt', mode='w', encoding='utf-8') as fh:
fh.write(value)
@staticmethod # スタティックメソッドを実装(これを実装しないとエラーになります)
def print_static():
print('staticメソッド')
def print_a(): # 普通にメソッドを記述する
print('A')
SOLIDの原則とは
| 名前 | 概要 |
|---|---|
| 単一責任の原則 | 各クラスは1つだけの機能を提供し責任を持つべきとする原則。一つのクラスに色んなことを詰め込みすぎない |
| 開放閉鎖の原則 | クラスは拡張がしやすい構造にして、クラスを修正することはあまりなく、コード追加して拡張をするようにする。 |
| リスコフの置換原則 | サブクラスはそのスーパークラスの代用ができなければいけない。あるスーパークラスのインスタンスを引数として実行する関数、メソッドでは、そのサブクラスを引数にとっても実行できなければいけない |
| インタフェース分離の原則 | 1つのインタフェースに色んなメソッドを詰め込みすぎない。複数のインタフェースに分ける |
| 依存性逆転の原則 | 抽象化は詳細に依存しない。サブクラスを持たずにそのスーパークラスを利用するようにする。 |
Udemyでデザインパターンを学ぼう

ここからは、宣伝が入ります。
Udemyでデザインパターンの講座を出していまして、ありがたいことに高評価を頂いています。
デザインパターンだけでなく、pythonの基本的な内容、コードを良くきれいに書くにはどうするのかについてもいろいろと紹介しています。
これまで説明しましたようにデザインパターンは、プログラマにとって知っておくべきことです。是非、ご受講ください!
講座の内容
- python開発用の環境構築
- pythonの基本文法
- 綺麗なコードを書く方法、命名規約、コーディング規約、コメント文の書き方等
- SOLIDの原則
- デザインパターン
