使いどころ
* 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