ポリモーフィズムとカプセル化の実践

多相性の実装パターン

多相性は異なるオブジェクトが同一のインターフェースで異なる振る舞いを実現する仕組みです。例えば、形状計算の場面で円と四角形が共通メソッドで処理されるケースが典型例です。

形状計算の具体例

from abc import ABC, abstractmethod

class GeometricShape(ABC):
    @abstractmethod
    def compute_area(self):
        pass

class CircularShape(GeometricShape):
    def __init__(self, radius):
        self.radius = radius
    
    def compute_area(self):
        return 3.14159 * self.radius ** 2

class RectangularShape(GeometricShape):
    def __init__(self, base, height):
        self.base = base
        self.height = height
    
    def compute_area(self):
        return self.base * self.height

def show_area(geometry):
    print(f"計算結果: {geometry.compute_area()}")

circle = CircularShape(7)
rectangle = RectangularShape(5, 9)
show_area(circle)    # 出力: 計算結果: 153.938
show_area(rectangle) # 出力: 計算結果: 45

この実装ではshow_area関数が形状の種類に依存せず、共通のcompute_areaメソッドを呼び出します。このアプローチにより、新規形状クラスを追加しても既存コードの修正が不要になるため、拡張性が向上します。

カプセル化の実践手法

カプセル化は内部状態を隠蔽し、外部からのアクセスを制御する設計原則です。データの整合性を保ちつつ、実装の変更が外部に影響しないようにします。

プロパティによるアクセス制御

class FinancialAccount:
    def __init__(self, owner, start_balance):
        self.owner = owner
        self.__amount = start_balance  # 内部管理用属性

    @property
    def balance(self):
        return self.__amount

    @balance.setter
    def balance(self, new_value):
        if new_value < 0:
            raise ValueError("残高はゼロ以上である必要があります")
        self.__amount = new_value

    def add_funds(self, deposit):
        if deposit > 0:
            self.__amount += deposit

    def deduct_funds(self, withdrawal):
        if 0 < withdrawal <= self.__amount:
            self.__amount -= withdrawal

my_account = FinancialAccount("佐藤", 5000)
my_account.add_funds(2000)
print(my_account.balance)  # 出力: 7000
my_account.balance = 10000  # プロパティ経由で値更新
print(my_account.balance)  # 出力: 10000

この例ではbalanceプロパティを介して値の妥当性検証を実施しています。内部実装が変更されても、外部からの呼び出し方法を変更する必要がなく、保守性が向上します。

クラスメソッドと静的メソッドの活用

class DataProcessor:
    @classmethod
    def create_from_json(cls, json_data):
        # JSONデータを解析してインスタンスを生成
        return cls(json_data["data"]["value"])

    @staticmethod
    def convert_units(value, from_unit, to_unit):
        conversion_factors = {
            ("m", "cm"): 100,
            ("cm", "m"): 0.01
        }
        return value * conversion_factors.get((from_unit, to_unit), 1)

json_config = {"data": {"value": 42}}
processor = DataProcessor.create_from_json(json_config)
print(DataProcessor.convert_units(5, "m", "cm"))  # 出力: 500

クラスメソッドはファクトリーパターンとして、静的メソッドは単純な変換処理に最適です。メソッドの種類を適切に選択することで、コードの目的が明確になり、再利用性が向上します。

タグ: ポリモーフィズム カプセル化 Python プロパティ クラスメソッド

8月22日 02:32 投稿