Use visitor pattern to handle else if

Deadly 提交于 2019-12-11 19:04:12

问题


I wonder if there is any way to handle a simple condition with the visitor pattern or not?

For instance, if we have the below code, how can we apply the visitor pattern to it?

public class Elseif
{
    private int total;
    public int Condition(int x)
    {
        if(x==1)
        {
            total = 100;
        }
        else if(x==2)
        {
            total = 200;
        }
        return total;

    }
}

in other words how you want to write the overload for IVisitor interface ?

public interface IVisitor
{
    int Visitor(int x);
}

回答1:


The Visitor Pattern is for distinguishing different types, espacially if you have an object of an (abstract) superclass, and you want to do special things depending on the concrete type. That means, you can (and should) use it instead of an if-then-else with casting-tests.

The Visitor Pattern is not for distinguishing values.




回答2:


Maybe you are looking for Chain Of Responsibility pattern?

Let's say your have to calculate bonus and you use something like this

public double GetBonusRate(int workingDays, int numberOfSales)
{
    if(numberOfSales > 20)
    {
      return 1.5;
    }

    if(workingDays >= 20 && numberOfSales > 10)
    {
      return 1.2;
    }

    if(numberOfSales > 5)
    {
      return 1.0;
    }

    if(workingDays > 10)
    {
      return 0.1;
    }

    return 0;
}

You expect, that number of conditions will grow and you realize, that adding new condition in a wrong place will cause a bug.
Chain of responsibility gives you another approach.

var chain = new PerfectBonusRate();
chain.RegisterNext(new GoodBonusRate())
    .RegisterNext(new StandartBonusRate())
    .RegisterNext(new LazyBonusRate())
    .RegisterNext(new NoBonusRate());

var bonusRate = chain.GetBonusRate(10, 20);

Implementation

abstract class ChainElement
{
    ChainElement _next;

    public ChainElement RegisterNext(ChainElement next)
    {
        _next = next;
        return next;
    }

    public double GetBonusRate(int workingDays, int numberOfSales)
    {
        if(IsMatched(workingDays, numberOfSales))
        {
            return GetBonusValue();
        }

        return _next.GetBonusRate(workingDays, numberOfSales);
    }

    protected abstract bool IsMatched(int workingDays, int numberOfSales);

    protected abstract int GetBonusValue();
}

class PerfectBonusRate : ChainElement
{
    protected override bool IsMatched(int workingDays, int numberOfSales)
    {
        return numberOfSales > 20;
    }

    protected override double GetBonusValue()
    {
        return 1.5;
    }
}

class GoodBonusRate : ChainElement
{
    protected override bool IsMatched(int workingDays, int numberOfSales)
    {
        return workingDays >= 20 && numberOfSales > 10;
    }

    protected override double GetBonusValue()
    {
        return 1.2;
    }
}

//and the same for StandartBonusRate, LazyBonusRate...

class NoBonusRate : ChainElement
{
    protected override bool IsMatched(int workingDays, int numberOfSales)
    {
        return true;
    }

    protected override double GetBonusValue()
    {
        return 0.0;
    }
}



回答3:


Patterns used for solving some specific problems. Visitor pattern solves following problem - adding new capabilities to (composite) structure of objects without changing those objects. So, let me rephrase your question - how can I add new capabilities to structure of objects, without having structure of objects and capabilities to be added. That's like hammering nail with violin.

Remember - first goes problem. Then goes pattern which solves that problem. Not vice versa.

UPDATE so, what problem you code has? It does not follow Command-query separation principle. Same method performs an action (modifying total) and returns total to caller. I'd separated command and query to make your code more clear:

public int Total { get; set; }

public void DoSomething(int x)
{
    if(x == 1)
    {
        Total = 100;
        return;
    }

    if(x == 2)
    {
       Total = 200;
       return;
    }
}


来源:https://stackoverflow.com/questions/14613971/use-visitor-pattern-to-handle-else-if

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!