4
\$\begingroup\$

I was doing some sample example which were perfectly fine. But, when I read about SOLID design principle, I had to change my code.

I have implemented DIP and DI (Constructor Injection) in my code. Please let me know whether I have implemented successfully or not.

Old code before SOLID design principlss:

class Program
{
    static void Main(string[] args)
    {
        Higherclass obj = new Higherclass("Female");
        obj.CallLowerClass();
        Console.ReadLine();
    }

}

public class Higherclass
{
    public readonly string sex;
    lowerClass_Male objLowerClass_Male = null;
    lowerClass_Female objLowerClass_Female = null;

    public Higherclass(string _sex)
    {
        sex = _sex;
    }


    public void CallLowerClass()
    {
        if (sex == "Male")
        {
            objLowerClass_Male = new lowerClass_Male();
            objLowerClass_Male.DoSomeAction();
        }
        else
        {
            objLowerClass_Female = new lowerClass_Female();
            objLowerClass_Female.DoSomeAction();
        }

    }
}

public class lowerClass_Male
{
    public void DoSomeAction()
    {
        Console.WriteLine("Hey It's Male. Do Some Action");
    }
}

public class lowerClass_Female
{
    public void DoSomeAction()
    {
        Console.WriteLine("Hey It's FeMale. Do Some Action");
    }
}

Newly modified code:

class Program
{
    static void Main(string[] args)
    {
        //Now, It depends on my requirement to call any sex class.Let's Say, I want to call Female Class.
        lowerClass_FeMale objLowerfemale = new lowerClass_FeMale();
        Higherclass obj = new Higherclass(objLowerfemale);
        obj.CallLowerClass();
        Console.ReadLine();
    }

}

public interface ISex
{
    void DoSomeAction();
}

public class lowerClass_Male : ISex
{
    public void DoSomeAction()
    {
        Console.WriteLine("Hey It's Male. Do Some Action");
    }
}

public class lowerClass_FeMale : ISex
{
    public void DoSomeAction()
    {
        Console.WriteLine("Hey It's FeMale. Do Some Action");
    }
}

public class Higherclass
{
    public ISex MySexInterface = null;
    public Higherclass(ISex objISex)
    {
        this.MySexInterface = objISex;
    }

    public void CallLowerClass()
    {
        MySexInterface.DoSomeAction();
    }

}
\$\endgroup\$
5
\$\begingroup\$

The new code seems OK to me.

One way to know if you're on the right way is trying to unit test your code. In the old code you couldn't unit test the higher class, as you needed to create real instances of the lower classes inside the code, so you needed to test both the higher and the lower classes at the same time.

In the new code you can test the lower classes and the higher class separately, as now you can inject a mock of the ISex interface into the higher class and test that the proper methods of the lower classes are invoked.

Note that you have two options to inject the lower class. If the lower class is only going to help in one method of the higher class, maybe it will be better to inject the lower class as a parameter of that method. If the lower class is going to help all along the higher class, then pass it as a parameter of the constructor, as you have it now.

| improve this answer | |
\$\endgroup\$
5
\$\begingroup\$

Adding to @Carlos' Alejo answer there is one more idicator that tells you whether you are on the SOLID side of the force :-]

If you tried to add another sex to your first model you couldn't do it without modifying the CallLowerClass method and its switch. It violates the Open/Closed Principle.

With the second model that is based on an abstraction ISex you just create a new class and you're done. It's open for extension but closed for modification.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You're quite right, nice point! \$\endgroup\$ – Charlie Sep 11 '16 at 18:31
0
\$\begingroup\$

In addition to what @t3chb0t has indicated. In your first implementation, the CallLowerClass could have benefitted from Dependency Injection

public void CallLowerClass(LowerClass_Sex sex)
    {
        sex.DoSomeAction();            
    }

that would have avoided the use of if ..else statement. This is assuming the LowerClass_Sex is an abstract class or interface where the Male and Female classes can inherit from. This can also be done in the second implementation

  • Since lowerClass_Male and lowerClass_FeMale contain only four liners of code.. you should consider using Struct. As a struct can also implement an interface ie ISex and contain methods and other fields.
  • I would suggest restricting your Console.WriteLine to your Main method rather than having it in those classes
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ If the OP did this in the first implementation then it would be actually the second implementation so he would only have one of them where both were the second one - am I right? ;-P \$\endgroup\$ – t3chb0t Sep 12 '16 at 14:24
  • \$\begingroup\$ @t3chb0t still confused with your question . Are you talking about the Dependency Injection in my first paragraph \$\endgroup\$ – Siobhan Sep 12 '16 at 14:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.