コンピュータプログラミング において、シングルサービングビジターパターンはデザインパターンの一つです。その目的は、割り当てられ、一度だけ使用され、その後削除されるビジター(ほとんどのビジターがこれに該当します)の実装を最適化することです。
ビジターがメモリに保持される必要がない場合は、シングルサービング・ビジターパターンを使用する必要があります。これは、オブジェクトの階層構造を訪問して単一のタスクを実行する場合(例えば、ビジターパターンとコンポジットパターンを併用する場合など)によく当てはまります。例えば、3Dシーン内のカメラの数を数える場合などです。
ビジターをメモリ上に保持する必要がある場合は、通常のビジターパターンを使用する必要があります。これは、ビジターが、後で使用するためにメモリ上に保持する必要のある多数のパラメーターで構成されている場合(たとえば、3Dシーンレンダラーのレンダリングオプションを保存する場合)に発生します。
しかし、プログラム全体でそのようなビジターが1つしか存在しない場合は、それをシングルサービングビジターとシングルトンの両方として実装するのが良いでしょう。そうすることで、シングルサービングビジターをパラメータを変更せずに後で呼び出すことができるようになります(この場合、「シングルサービングビジター」という表現は、ビジターを複数回使用できるため、不適切な表現です)。
単一サービスビジターは、静的メソッドを介して呼び出されます。
パラメータがない場合、これは ですが、パラメータがある場合、 となります。SingleServingVisitor::applyTo(e);SingleServingVisitor::applyTo(e,a,b);
シングルトンとして実装した場合:
SingleServingVisitor :: setA ( a ); SingleServingVisitor :: setB ( b ); SingleServingVisitor :: applyTo ( e );applyTo()。applyTo()、単一のビジターが作成され、その後破棄されるため、時間がかかります。一方、シングルトンは割り当てを1回しか実行しません。template < typename A , typename B > class SingleServingVisitor { protected : SingleServingVisitor () = default ; public : ~ SingleServingVisitor () = default ;static void applyTo ( Element & e ) { e.accept ( SingleServingVisitor < A , B > ( )) ; }virtual void visitA ( A & a ) = 0 ; virtual void visitB ( B & b ) = 0 ; };シングルサービングビジターを初期化する必要がある場合は、パラメータを静的メソッドを通して渡す必要があります。
static void applyTo ( Element & elem , const A & a , const B & b ) { elem.accept ( SingleServingVisitor < A , B > ( a , b ) ) ; }この実装により、以下のことが保証されます。
テンプレート< typename A , typename B > class SingleServingVisitor { protected : A a ; B b ;SingleServingVisitor () = default ;// 注: instance() メソッドは public である必要はありませんstatic SingleServingVisitor & instance () noexcept { static SingleServingVisitor ssv ; return ssv ; } public : ~ SingleServingVisitor () = default ;static void applyTo ( Element & e ) noexcept { e.accept ( instance ( )) ; }// パラメータにアクセスするための静的メソッドstatic void setA ( const A & a ) noexcept { this -> a = a ; }static void setB ( const B & b ) noexcept { this -> b = b ; }virtual void visitA ( A & a ) = 0 ; virtual void visitB ( B & b ) = 0 ; };