Visitor Design Pattern

GOF Intent:
Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

هدف Visitor Pattern جدايي “ساختمان داده” از “منطق عملياتي” است.

براي درک بهتر اين Pattern مثالي را پي مي گيريم.

مثال:
در يک سيستم بانکي انواع حساب وجود دارد. از جمله حساب جاري، سپرده و غيره. روي هريک از اين انواع حساب بعضي عمليات از جمله واريز و برداشت، مانده گيري، محاسبه سود و غيره انجام مي شود، اما در مورد هر حساب به روش مخصوص به خود.

اگر در اين مثال Visitor Pattern را پياده کنيم چنين طراحي خواهيم داشت:

در حالت کلي ساختار Visitor Pattern بدين صورت است:

در ساختار فوق، Object Structure ساختار نگهدارنده عناصر Element است. ميتواند آرايه، ليست، درخت و غيره باشد.

نمونه کد:

public interface Element {
   public void accept(Visitor v);
   public String getName();
}


public class ConcreteElementA implements Element{
   private String name;

   public ConcreteElementA(String name){
      this.name = name;
   }

   public String getName(){
      return name;
   }

   public void accept(Visitor v) {
      v.visitConcreteElementA(this);
   }
}


public class ConcreteElementB implements Element{
   private String name;

   public ConcreteElementB(String name){
      this.name = name;
   }

   public String getName(){
      return name;
   }

   public void accept(Visitor v) {
      v.visitConcreteElementB(this);
   }

}


public interface Visitor {
   public void visitConcreteElementA(Element e);
   public void visitConcreteElementB(Element e);
}


public class ConcreteVisitorOperation1 implements Visitor{

   public void visitConcreteElementA(Element e) {
      System.out.println(“Operation1 for Element A run for “+e.getName());
   }

   public void visitConcreteElementB(Element e) {
      System.out.println(“Operation1 for Element B run for “+e.getName());
   }
}


public class ConcreteVisitorOperation2 implements Visitor{

   public void visitConcreteElementA(Element e) {
      System.out.println(“Operation2 for Element A run for “+e.getName());
   }

   public void visitConcreteElementB(Element e) {
      System.out.println(“Operation2 for Element B run for “+e.getName());
   }
}


public static void main(String[] args){
   ArrayList<Element> elementList = new ArrayList<Element>();
   elementList.add(new ConcreteElementA(“ElementA1″));
   elementList.add(new ConcreteElementA(“ElementA2″));
   elementList.add(new ConcreteElementB(“ElementB1″));
   elementList.add(new ConcreteElementB(“ElementB2″));

   Visitor v1 = new ConcreteVisitorOperation1();
   for (Element e : elementList){
      e.accept(v1);
   }
}

فايده هاي Visitor Pattern:

  • افزودن Operation هاي تازه را ساده مي کند.
  • Operation هاي مرتبط با هم را کنار هم قرار مي دهد.
عيب هاي Visitor Pattern:
  • افزودن Element جديد دشوار است. چون به ازاي هر Element بايد Operator هاي لازم هم در Abstract Visitor و هم در کليه Concrete Visitor ها اضافه شوند.
  • Encapsulation را نقض مي کند.

نتيجه:
بطور کلي از Visitor Pattern، زماني استفاده کنيد که کلاس هاي اصلي به ندرت تغيير مي کنند، اما لازم است در طول زمان Operator هاي جديدي به آنها اضافه شود. اگر خود کلاس تغييراتش زياد است، بهتر است از اين Pattern استفاده نشود و Operator ها در خود کلاس پياده شوند.



منبع ها:

  1. Design Patterns – Elements of Reusable Object Oriented Software (GOF) By Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides
  2. Visitor in Devlake

پست شده در Design Pattern

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

*


نُه × = 45

شما می‌توانید از این دستورات HTML استفاده کنید: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

تماس با من: admin@paspars.com