switch 擬で記述すると
expr = "3 4 +" expr = "3 4 + 2 *" parser = Parser() cal = Polish() for e in expr.split(" "): e = parser.scan(e) e.switch({ Value: cal.value, Op : cal.op, }) print cal.evaluate()
# -------------------------- class Polish: def __init__(self): self.stack = [] def value(self, e): self.stack.append(e) def op(self, e): op2 = self.stack.pop() op1 = self.stack.pop() value = eval("%s %s %s"%(op1, e, op2)) self.stack.append(value) def evaluate(self): return self.stack.pop() # -------------------------- class Token: def __repr__(self): return "%s"%self.value def switch(self, dispatch): return dispatch[self.__class__](e) class Value(Token): def __init__(self, value): self.value = int(value) class Op(Token): def __init__(self, value): self.value = str(value) # --------------------------
ポリモフィズムを利用すると
前述したように、if と別れる「始め一歩」がポリモフィズムの導入を検討してみることです。それが「末の千里」へと誘います。
expr = "3 4 +"
expr = "3 4 + 2 *"
parser = Parser()
cal = Polish()
for e in expr.split(" "):
e = parser.scan(e)
e.evaluate(cal)
print cal.evaluate()
ポリモフィズムを利用すると、switch 擬と比べて、簡潔で見通しの良いコードを記述できます。要求仕様の変更にも柔軟に対処できるだけでなく、動的スキーマの適用が可能になります。
# -------------------------- class Token: def __repr__(self): return "%s"%self.value def switch(self, dispatch): return dispatch[self.__class__](e) class Value(Token): def __init__(self, value): self.value = int(value) def evaluate(self, cal): cal.value(self) class Op(Token): def __init__(self, value): self.value = str(value) def evaluate(self, cal): cal.op(self) # --------------------------