2a)機能の要求:Visitor

各機能を実現するときには、Visitor::Visitor で規定されたプロトコルに従います。

## --------------------             # Visitor::Visitor
class XVisitor:
    def visit_EllipseShape(self, e):
        raise NotImplementedError("%s.visit_EllipseShape"
            %self.__class__.__name__)
    def visit_PolygonShape(self, e):
        raise NotImplementedError("%s.visit_PolygonShape"
            %self.__class__.__name__)

ここで規定したメソッドを、子孫クラスで再定義しないと、実行時に例外 NotImplementedError を生成するとともに、そのクラス名を出力します。たとえば、メソッド visit_EllipseShape を実現しないと、実行時に次のようなメッセージを出力します。

NotImplementedError: SolidColorVisitor.visit_EllipseShape

すると、子孫クラス SolidColorVisitor で「必須の」メソッドを再定義していないのが分かります。


《Note》 abstract/interface などに象徴されるメカニズムは、些末な作業をコンパイラーに委ねられるので、初心者には重宝するかもしれません。そこに代えて、コンパイラーに任せっきりにするのでなく、プログラマーが自発的なメカニズムを注入できる仕組みがあると、便利です。すると、システム開発の初期に導入された意志決定に束縛される憂き目から解放されます。硬直した作業環境のもとでは、得てして後で見つかる革新的な手法の導入さえ躊躇しがちです。ハードウェア/ソフトウェアの特性を知ることで、プログラム(算譜)の質の向上が期待できるのと同様に、ヘッドウェアの特性を知っておくと、プログラミング(作譜)の質の向上が期待できます。□