Factoryパターン(4) - 引数にクラスを渡すAbstract Factory


前回、Abstract Factroyクラスを作りました。こんどは、それをさらにTemplate Method化します。

#前回作った、Factroryクラス
class JunggleOrganismFactory(object):
    def new_animal(self, name):
        return Tiger(name)
    
    def new_plant(self, name):
        return Tree(name)

class PondOrganismFactory(object):
    def new_animal(self, name):
        return Duck(name)
    
    def new_plant(self, name):
        return WaterLily(name)

どちらもnew_$$$ で返すオブジェクトの種類以外は全く同じです。

そこで!その部分をTemplate Method化します。
Factroryクラスのコンストラクタに渡すのはもちろんクラスオブジェクトです。

#前回作った、Factroryクラス
class OrganismFactory(object):
    def __init__(self, animal_class, plant_class):
        self.animal_class = animal_class
        self.plant_class = plant_class
        
    def new_animal(self, name):
        return self.animal_class(name)
    
    def new_plant(self, name):
        return self.plant_class(name)

jungle_organism_factory = OrganismFactory(Tiger, Tree)
pond_organism_factory = OrganismFactory(Duck, WaterLily)

jungle = Habitat(10, 5, jungle_organism_factory)
jungle.simulate_one_day()

pond = Habitat(10, 5, pond_organism_factory)
pond.simulate_one_day()

どうも、話が循環しているようです。個々のクラスを指定するのを避けるために、Abstract Factoryを作ったはずです。しかし、これではまた間違えて、虎と藻を一緒においてしまうかもしれません。

実際は違います。

いずれにせよ、誰かが返すクラスの組み合わせを知っていなければなりません。Abstract Factroyの意義は、クラスの組み合わせについての責務を分離する事なのです。