Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace conditional with polimorphism how to

I would like to replace the if statements in the following recursive function with polimorphism.

i read alot about it, see several youtube videos but still, cannot see the way of actually doing it on my code (that was simplified for the purpose of this post)

what makes this task more difficult for me is the presence of a foreach statment at the begining of the function and the recursive call

thanks for the help

public void FlattenXml(XElement xml, string id = null)
{
    var elements = xml.Elements().ToList();
    foreach (var element in elements)
    {
        if (element.Name == "name1")
        {
            Func1();
        }
        if (element.Name == "name2")
        {
            Func2();
        }
        if (element.Name == "name3")
        {
            DoSomethingElse();
            FlattenXml(content, tempId);
            Func3();
        }
        else
        {
            DoSomethingCompletelyDifferent();
            FlattenXml(element, id);
        }
    }
    xml.Elements("name3").Remove();
}
like image 802
Limbo Avatar asked Oct 19 '17 14:10

Limbo


People also ask

How does polymorphism facilitate the Minimisation of conditional logic branching?

Polymorphism will break your complex class into several smaller simpler classes which clearly define which pieces of the code are related and execute together.

How do you use polymorphism?

Polymorphism is the ability of an object to take on many forms. The most common use of polymorphism in OOP occurs when a parent class reference is used to refer to a child class object. Any Java object that can pass more than one IS-A test is considered to be polymorphic.

What is polymorphism OOP?

Polymorphism is one of the core concepts of object-oriented programming (OOP) and describes situations in which something occurs in several different forms. In computer science, it describes the concept that you can access objects of different types through the same interface.


2 Answers

If you want to use design pattern with the beauty of code then I will suggest you to use Polymorphism, strategy pattern, and pattern search.

It will give the advantage of code enhancement and reusability.

Below code example:

public interface ISomeOperation
{
    string DoOperation(string data);
}

public class OperationA : ISomeOperation
{
    public string DoOperation(string data)
    {
        //implemention.  
        return data;
    }
}

public class OperationB : ISomeOperation
{
    public string DoOperation(string data)
    {
        //implemention. 
        return data;
    }
}

public class OperationC : ISomeOperation
{
    public string DoOperation(string data)
    {
        //implemention.  
        return data;
    }
}

public class OperationD : ISomeOperation
{
    public string DoOperation(string data)
    {
        //implemention.  
        return data;
    }
}

public class OperationContext
{
    private readonly Dictionary<string, ISomeOperation> _operationStrategy = new Dictionary<string, ISomeOperation>();

    public OperationContext()
    {
        _operationStrategy.Add("name1", new OperationA());
        _operationStrategy.Add("name2", new OperationB());
        _operationStrategy.Add("name3", new OperationC());
        _operationStrategy.Add("name4", new OperationD());
    }

    public string GetOperationData(string searchType, string data)
    {
        return _operationStrategy[searchType].DoOperation(data);
    }
}

//Driver Code:

 class Program
 {
    static void Main(string[] args)
    {
        var operationContext = new OperationContext();
        var elements = xml.Elements().ToList();
        foreach (var element in elements)
        {
            operationContext.GetOperationData(element.Name, element);
        }
    }
}

Node: Multiple methods should be called in one method.

like image 114
Gul Ershad Avatar answered Sep 20 '22 15:09

Gul Ershad


For this situation, polymorphism is understood through the concept of "types" and "behaviors". The three "names" indicate three different types - but you also have an "else", so there are four types to work with.

(Question - did you intend the ifs to be a full if/else chain? In this code, else is executed for "name1" and "name2". My answer depends on a full if/else chain...)

To make it a little easier to understand, consider this code:

public void FeedAnimals(Menagerie x)
{
    var animals = x.getAnimals()
    foreach (var animal in animals)
    {
        if (animal.Name == "cat")
        {
            FeedTheCat();
        } else if (animal.Name == "dog")
        {
            feedTheDog();
        } else if (animal.Name == "bees")
        {
            PutOnBeeSuit();
            foreach(bee in bees) FeedAnimals(new Menagerie() {bee});
        }
        else
        {
            CallAMeeting();
            FeedAnimals(new Menagerie() {employees});
        }
    }
}

(this is all pseudo-code, btw)

You can now see how each "animal" type is being "fed". But the act of feeding could be different. This is where polymorphism comes into play - you shift your thinking from making a decision about what should be done with the data to creating a "type" that has "behaviors" you can apply.

In this case, the general "type" is "animal" and the behavior is "feed". Polymorphism is the part where you differentiate from the general type into specific types:

class Animal {
  public function Feed() {}
}

class Cat inheritsfrom Animal {
  public function Feed() {}
}

class Bee inheritsfrom Animal {
  public function Feed() {}
}

class Dog inheritsfrom Animal {
  public function Feed() {}
}

class BeeHive {
  list of Bee bees
}

So now your logic can shift to something like:

public void FeedAnimals(List(of Animal) menagerie, string id = null)
{
    foreach (var animal in menagerie)
    {
        if (animal is Cat)
        {
          animal.Feed();
        } else if (animal is Dog)
        {
            animal.Feed();
        } else if (animal is Bee)
        {
            PutOnBeeSuit();
            animal.Feed();
        } else if (animal is BeeHive) {
          FeedAnimals animal.bees
        } else
        {
            CallAMeeting();
            animal.feed();
        }
    }
}

See how you end up calling ".Feed" all the time? That's a good thing. Since Cat, Dog, Bee inherit from animal, they actually have a different "Feed" function, and the language knows which one to call, based on what type is being referenced. And the type is automatically associated with the variable (behind the scenes).

So now, with one minor change to BeeHive, the code collapses to:

// new BeeHive class:
class BeeHive inheritsfrom Animal{
  list of Bee bees
  public function Feed() { 
    foreach(bee in bees) bee.Feed()
  }
}

// new, collapsed code
public void FeedAnimals(List( of Animal) menagerie, string id = null) {
  foreach(var animal in menagerie) {
    if (animal is Animal) {
      CallAMeeting()
    }
    animal.Feed()
  }
}

I hope this helps clear up the process of thinking through a polymorphism implementation.

Don't forget, this is ALL pseudo-code, and there ARE errors in the code. It's here to express concepts, it's not here to run (or even compile).

like image 39
theGleep Avatar answered Sep 20 '22 15:09

theGleep