0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで実装するPrototypeパターン:オブジェクトの複製による柔軟な生成戦略

Posted at

概要

Prototype(プロトタイプ)パターンは、
インスタンスの生成をコンストラクタ(__init__)によらず、既存オブジェクトを複製(clone)することで実現する設計パターンである。

同じ構造のオブジェクトを大量に生成したい場合や、初期化コストが高いオブジェクトの再利用などに有効。
複雑な構築ロジックをカプセル化し、コピーによる柔軟な生成制御が可能となる。


1. なぜPrototypeが必要か?

❌ 毎回コンストラクタで初期化すると、設定・構築処理が重複する

user = User("admin", permissions=["read", "write", "delete"])

似たような構造のオブジェクトを都度構築するのは非効率


✅ ベースとなるオブジェクトを複製し、必要に応じて差分だけ上書き

admin = prototype.clone()
admin.name = "root"

共通の構造をコピーして活用できるため、保守性と効率が高まる


2. 基本構造

✅ Prototypeインターフェース

import copy

class Prototype:
    def clone(self):
        return copy.deepcopy(self)

✅ 利用クラスの定義

class User(Prototype):
    def __init__(self, name, permissions):
        self.name = name
        self.permissions = permissions

    def show(self):
        print(f"User: {self.name}, Permissions: {self.permissions}")

✅ 使用例

base_user = User("template", ["read", "write"])
admin_user = base_user.clone()
admin_user.name = "admin"
admin_user.permissions.append("delete")

guest_user = base_user.clone()
guest_user.name = "guest"
guest_user.permissions = ["read"]

base_user.show()   # template, ["read", "write"]
admin_user.show()  # admin, ["read", "write", "delete"]
guest_user.show()  # guest, ["read"]

出力:

User: template, Permissions: ['read', 'write']  
User: admin, Permissions: ['read', 'write', 'delete']  
User: guest, Permissions: ['read']

3. Python的応用:copy.copy vs copy.deepcopy

from copy import copy, deepcopy

a = [1, 2, [3, 4]]
shallow = copy(a)
deep = deepcopy(a)

a[2].append(5)
print(shallow)  # [1, 2, [3, 4, 5]] ← 浅いコピーは内部リストを共有
print(deep)     # [1, 2, [3, 4]]     ← 深いコピーは独立している

浅い vs 深い の違いは、Prototype設計において極めて重要


4. 実務ユースケース

✅ テンプレートオブジェクトからの生成

フォーム、ユーザー、設定など共通構造の複製


✅ 初期化コストの高いオブジェクトの再利用

DB接続、外部リソース、構文解析済み構造など


✅ テスト・モック用の状態複製

状態を維持したまま環境をコピーしてシナリオ分岐


✅ ゲームにおけるエンティティ・アイテムの生成

元データから個体差を持たせて生成


5. よくある誤用と対策

❌ clone() における浅いコピーが意図せず副作用を引き起こす

→ ✅ deepcopy()をデフォルトとし、明示的な制御が必要なときのみ copy() を使用


❌ 複製後に必須の初期化を忘れると、不完全なオブジェクトになる

→ ✅ clone後に initialize() 的なメソッドを呼び出すパターンを設計に含める


❌ データと振る舞いを分離しないまま複製して状態を混乱させる

→ ✅ 状態とロジックの分離(データクラス化・DI設計)を併用


結語

Prototypeパターンとは、“作るのではなく、写すことで構造を再利用する設計”である。

  • コンストラクションの重さを回避し、共通構造の複製により生成の効率性を確保
  • 状態のコピーを前提とするため、柔軟かつ迅速なインスタンス展開が可能
  • Pythonでは copy モジュールによって、シンプルに強力なPrototype戦略を実現できる

Pythonicとは、“繰り返すより、写してから変えること”。
Prototypeパターンはその複製の知性を、設計の俊敏性として表現する技法である。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?