Difference between decorator design pattern and visitor design pattern

12,283

Solution 1

Well, they are actually as different as they can be!

You use Decorator when you want to enhance existing object with some new, more-or-less transparent functionality like validation or caching. See example here: Should I extend ArrayList to add attributes that isn't null?

Visitor on the other hand is used when you have a hierarchy of classes and want to run different method based on concrete type but avoiding instanceof or typeof operators. See real-life example: Is This Use of the "instanceof" Operator Considered Bad Design?

Decorator works on an object, Visitor works on composite structure,

Visitor works on an inheritance hierarchy, Composite is a different GoF design pattern.

Decorator is Structural design pattern, visitor is Behavioral design pattern.

True, but it doesn't really help in understanding how they work?

See also

Solution 2

Design patterns are not meant to be categorized by the implementation differences but by when you should use one or the other one.

They serve for absolutely different purposes:

  • you will use decorator when you want to dynamically enrich the functionality of objects by providing single elements that decorate other objects so that they do actually add some behavior to them (in fact it is a structural pattern in the sense that it alters the structure of the objects you are woking with)
  • you will use visitor when you want to separate an algorithm from the objects it is used with. What you do is that you have this visitor which is passed to a multitude of different objects, usually a hierarchy, (they are said to accept the visitor), this visitor does specific operations according to the type of objects it is visiting in the specific moment. In this way you can have your visitor do whatever it wants with the specific objects without the need to specify these operations in the objects itself (that's why it is behavioral). It's a sort of having abstract methods that are not defined in the object itself.

Solution 3

They both "add functionality" to an existing object, without modifying the original class. The difference is:

With decorator You add functionality that wraps basic functionality that this object has (e.g. in addition to perform some basic action also write it to log, in addition to write a file to disk also encrypt it). This also allows us to create different combinations of decorators without subclassing each possible scenario.

With visitor You add a completely new behavior that you don't want to define as part of the basic component class itself (not even as a wrapper to basic functionality), for example because of single responsibility principle, open close principle etc. It's especially useful when that behavior will be different between different subclasses of the same type (if there isn't any complex structure of subclasses but just one class you could just create a new class and include the original class via composition and still achieve the goal of not affecting or modifying the original class). That way you can avoid code like if (a is ConcreteClass1) {...} else if (a is ConcreterClass2) {...} without writing virtual methods.

As a result of this difference, with decorator the client code calls the same method which is defined on the interface of the basic component class, it's just "decorated" with extra functionality now, while with visitor the client calls some general "accept" method and sends a visitor to it.

Solution 4

The way I interpret it, visitors represent actions that we may want to take on or with an object, but that are not necessarily inherent to an object, and are rather horizontal in relationship. For example, I could "make a marketing pitch" for a car, but I wouldn't program a car object to have a "createMarketingPitch" function because that would be a slippery slope towards creating many many functions on my car object.

On the other hand, a decorator is a pattern that layers functionality on top of an existing object, a vertical relationship that modifies how the object behaves when its normal functions are called. Additionally, whereas a visitor is coded to work with a class of objects, decorators can be assigned to specific instances of the object so that different instances of the same type behave differently than each other.

Solution 5

I like to think that decorator allows to avoid inheriting and then extending the class as is the general principle of OOP to prefer aggregation over inheritance, although you do inherit in a way. Here is a overly simplistic example

abstract class Chef{
  public abstract void Prepare();
}

class CookieMaker:Chef{         //Concrete class
   public override void Prepare()
    {
        //Bake in Oven
     }
 }

  // Decorator class
 // This chef adds chocolate topping to everything
 class ChocoChef:Chef{  

     public ChocoChef(Chef mychef)
     {
        this.chef = mychef; 
     }

     public override void Prepare()
     {
           // Add chocolate topping first
           chef.Prepare()
     } 
 }

I'v cut short some details for the sake of space. For example, you could abstract out a chef which adds any kind of topping and ChocoChef then becomes its concrete class. Now ChocoChef always adds chocolate toppings no matter what you're preparing. So now you can have either chocolate cookies or chocolate cake by passing the correponding Chef to its constructor. The visitor on the other hand acts on objects and decides to do something based on the object that it is visiting.

class Student{
     // Different visitors visit each student object using this method
     // like prize distributor or uniform inspector
     public Accept(IVisitor v)
     {
         v.Visit(this)
     }
}

 // Visitor visits all student OBJECTS
class PrizeDistributor:IVisitor{
     public override void Visit(Student s)
     {
           //  if(s has scored 100)
           // Award prize to s
     }
}
Share:
12,283
Tilak
Author by

Tilak

profile for Tilak on Stack Exchange, a network of free, community-driven Q&A sites http://stackexchange.com/users/flair/327255.png .NET Software programmer with interest in WPF, Linq, Debugging, Multithreading, and Design Patterns. Profile

Updated on June 05, 2022

Comments

  • Tilak
    Tilak about 2 years

    I believe to understand the intent of Decorator and Visitor design pattern.

    Though i can list following differences

    1. Decorator works on an object, Visitor works on composite structure,
    2. Decorator is Structural design pattern, visitor is Behavioral design pattern.

    When i think deep down, i cannot convince myself what is the real difference between the two.