Design patterns – Visitor

Visitor is a behavioural pattern. It is used to perform some action on group of similar object without editing these objects. Updating logic is in visitor, rather than implemented in visited objects.
Imagine the case where you have many employees and you want to update theirs salary. We can use Visitor pattern for it. Salary update logic can be implemented in SalaryUpdatingVisitor and then any employee don’t know this logic.

This is our Employee class. Using it’s properties Visitor can update the Salary.

    interface IEmployee
    {
        double Salary { get; set; }
        int ExperienceLevel { get; set; }
        int SkillsLevel { get; set; }

        /// <summary>
        /// Starts visitor's work.
        /// </summary>
        /// <param name="v"></param>
        void Accept(IEmployeeVisitor v);
    }
	
    class Employee : IEmployee
    {
        public Employee(string firstName, string lastName, double salary, int experience, int skills)
        {
            FirstName = firstName;
            LastName = lastName;
            Salary = salary;
            ExperienceLevel = experience;
            SkillsLevel = skills;
        }

        public string FirstName { get; set; }
        public string LastName { get; set; }

        public double Salary { get; set; }
        public int ExperienceLevel { get; set; }
        public int SkillsLevel { get; set; }

        public void Accept(IEmployeeVisitor v)
        {
            Console.WriteLine($"{LastName} accepted {v.GetType().Name}.");
            v.Visit(this);
        }

    }

Our visitor – it’s implementation constains only one method Visit which takes as a parameter IEmployee.

    interface IEmployeeVisitor
    {
        /// <summary>
        /// Contains logic to perform on visited object.
        /// </summary>
        /// <param name="e"></param>
        void Visit(IEmployee e);
    }
	
	class SalaryUpdatingVisitor : IEmployeeVisitor
    {
        public void Visit(IEmployee e)
        {
            if (e.ExperienceLevel * e.SkillsLevel <= 10)
            {
                Console.WriteLine("Cheesy worker, no pay rise.");
                return;
            }
            else if (e.ExperienceLevel * e.SkillsLevel <= 20)
            {
                Console.WriteLine("Small payrise applied.");
                e.Salary += 100;
            }
            else
            {
                Console.WriteLine("Nice payrise applied.");
                e.Salary += 500;
            }
        }
    }

And now the usage. Let’s create a few employees and update theirs salaries using visitor.

        public static void VisitorUsage()
        {
            var visitor = new SalaryUpdatingVisitor();
            var employees = new List<IEmployee>();
            employees.Add(new Employee("John", "Smith", 2000, 10, 5));
            employees.Add(new Employee("Alice", "White", 1500, 2, 6));

            foreach (var e in employees)
            {
                e.Accept(visitor);
            }
        }
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s