処理の流れは同じだが、場合によって処理の中身を変更したい場合に使えるパターン。
基本的な処理の流れの定義
public abstract class AbstractFoo{
public virtual void Process(){
Initialize();
ProcessMain();
Terminate();
}
public abstract void Initialize();
public abstract void ProcessMain();
public abstract void Terminate();
}
抽象クラスにしているのはこのクラス単体でインスタンス生成できなくするため。
実際の処理の中身を書く
public class FooImplementationA : AbstractFoo{
public void Initialize(){
// do something
}
public void ProcessMain(){
// do something
}
public void Terminate(){
// do something
}
}
public class FooImplementationB : AbstractFoo{
public void Initialize(){
// do something another type
}
public void ProcessMain(){
// do something another type
}
public void Terminate(){
// do something another type
}
}
利用
単純にインスタンス生成して使う場合
var fooA = new FooImplementationA ();
fooA.Process();
var fooB = new FooImplementationB ();
fooB.Process();
ファクトリー使うならこう
class FooFactory{
public Foo GetFoo(string type){
if(type == "A") return new FooImplementationA ();
if(type == "B") return new FooImplementationB ();
}
}
var factory = new FooFactory();
var foo = factory.GetFoo("A");
foo.Process();
DI使うならこう
var builder = new ContainerBuilder();
builder.RegisterType<FooImplementationA>()
.As<Foo>
.InstancePerLifetimeScope() ;
var container = builder.Build();
var foo = container.Resolve<Foo>();
foo.Process();
構成によって FooImplementationA か FooImplementationB かのどちらかを登録するようにすれば、実行時に構成ごとに使う実装を切り替えられる。