使いどころ
* Validation処理(妥当性チェック)⇒ Validationなら、以下の「Visitorパターンを使うべきケース」での「要素の型(クラス)に応じて、行う処理が異なる」に当てはまる
http://www.aerith.net/design/Visitor-j.html
サンプル
IVisitor.cs (訪れて処理を行う用インターフェイス)
public interface IVisitor
{
void Visit(Person obj);
void Visit(BodyInfo obj);
}
Visitor.cs (IVisitorを継承して、具体的な処理を記述)
public class Visitor : IVisitor
{
public List<string> errorList = new List<string>();
public void Visit(Person obj)
{
errorList.Clear();
if (obj.id < 0)
{
errorList.Add("不正なidです");
}
if (obj.age < 0)
{
errorList.Add("不正な年齢です");
}
if (string.IsNullOrWhiteSpace(obj.name))
{
errorList.Add("名前を入力して下さい");
}
}
public void Visit(BodyInfo obj)
{
errorList.Clear();
if (obj.id < 0)
{
errorList.Add("不正なidです");
}
if (obj.height < 0)
{
errorList.Add("不正な身長です");
}
if (obj.weight < 0)
{
errorList.Add("不正な体重です");
}
if (obj.bmi < 0)
{
errorList.Add("不正な体重です");
}
}
}
IAcceptor.cs (処理を受け入れる用インターフェイス)
public interface IAcceptor
{
void Accept(IVisitor visitor);
}
Person.cs (IAcceptorを継承して、Visit()をコールする)
public class Person : IAcceptor
{
public int id;
public string name;
public int age;
public void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
}
BodyInfo.cs (IAcceptorを継承して、Visit()をコールする)
public class BodyInfo : IAcceptor
{
public int id;
public double height;
public double weight;
public double bmi;
public void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
}
Form1.cs (View)
private void button1_Click(object sender, EventArgs e)
{
var obj1 = new Person();
int id;
if(!int.TryParse(this.textBox1.Text,out id))
{
this.label1.Text = "error";
}
else
{
obj1.id = id;
}
obj1.name = this.textBox2.Text;
int age;
if (!int.TryParse(this.textBox3.Text, out age))
{
this.label2.Text = "error";
}
else
{
obj1.age = age;
}
this.Validate(obj1);
}
private void button2_Click(object sender, EventArgs e)
{
var obj2 = new BodyInfo();
int id;
if (!int.TryParse(this.textBox1.Text, out id))
{
this.label1.Text = "error";
}
else
{
obj2.id = id;
}
double height;
if (!double.TryParse(this.textBox2.Text, out height))
{
this.label2.Text = "error";
}
else
{
obj2.height = height;
}
double weight;
if (!double.TryParse(this.textBox3.Text, out weight))
{
this.label3.Text = "error";
}
else
{
obj2.weight = weight;
}
double bmi;
if (!double.TryParse(this.textBox4.Text, out bmi))
{
this.label4.Text = "error";
}
else
{
obj2.bmi = bmi;
}
this.Validate(obj2);
}
private void Validate(IAcceptor obj)
{
Visitor visitor = new Visitor();
obj.Accept(visitor);
this.label5.Text = string.Empty;
if (visitor.errorList.Count > 0)
{
foreach (var error in visitor.errorList)
{
this.label5.Text += error;
this.label5.Text += "\n";
}
}
else
{
this.label5.Text = "OK";
}
}
参考資料
http://www.nulab.co.jp/designPatterns/designPatterns2/designPatterns2-5.htmlhttp://hamasyou.com/archives/000260