Risipa de key_press | Programare

Programare .Net | Tehnici de programare | Tutoriale | Lectii si exemple

Risipa de key_press | Programare - Programare .Net | Tehnici de programare | Tutoriale | Lectii si exemple

Open/Closed Principle

De cele mai multe ori, sarcinile pe care le primeste un programator constau in adaugarea de functionalitati pornind de la un cod existent. Modificare vechiului cod poate afecta functionarea corecta a programului. OCP propune ca structura aplicatie sa fie realizata in asa fel incat noile functionalitati sa fie adaugate cu minimul de modificari aduse vechiului cod.

Consideram ca am respectat primul principiu din SOLID, Single Responsability Principle. Avand codul scris in clase si metode robuste, obiectivul nostru acum este, conform OCP, ca acestea sa nu mai fie modificate niciodata, chiar si in eventualitatea schimbarii specificatiilor. Cand o singura si o simpla schimbare in codul programului va genera o cascada de schimbari in module dependente, este clar un “bad design”, iar programul va deveni fragil.

Open/Closed Principle

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

“Open for extension” – comportamentul poate fi extins conform eventualelor modificari ale specificatiilor.
“Close for modification” – codul existent nu trebuie modificat.

Pornim de la un exemplu scris gresit. Avem clasele Robot si EnvironmentChecker care se supun SRP.

    public class Robot
    {
        public void Start()
        { 
            //
        }
    }

    public class EnvironmentChecker
    {
        public bool Check()
        {
            bool condition1Result = CheckCondition1();
            bool condition2Result = CheckCondition2();

            return condition1Result && condition2Result;
        }

        private bool CheckCondition1()
        {
            return true;
        }

        private bool CheckCondition2()
        {
            return true;
        }
    }

In clasa Program, in cazul in care conditiile sunt indeplinite, pot apela metoda Start a obiectului robot.

    class Program
    {
        static void Main(string[] args)
        {
            var robot = new Robot();

            //check conditions for starting the robot
            var envChecker = new EnvironmentChecker();
            if (envChecker.Check())
            {
                Console.WriteLine("Starting");
                robot.Start();
            }
        }
    }

Problema este atunci cand vom incerca sa adaugam noi conditii, va trebuie sa aducem modificari clasei EnvironmentChecker. Va trebui sa adaugam o metoda privata pentru fiecare conditie noua si sa modificam si metoda Check. Pentru a evita acest lucru, vom incerca sa aplicam principiul OCP.

Cream o interfata care va fi implementata de fiecare conditie (reprezentata de o clasa).

   public interface ICondition
    {
        bool Check();
    }

    public class Condition1 : ICondition
    {
        public bool Check()
        {
             //implementare
             return true;
        }
    }

    public class Condtion2 : ICondition
    {
        public bool Check()
        {
            //implementare
            return true;
        }
    }

In clasa EnvironmentCkecker, metoda Check va primi o lista de conditii, o va itera si va returna rezultatul verificarii.

    public class EnvironmentChecker
    {
        public bool Check(List<ICondtion> lstCondtion)
        {
            foreach (var condtion in lstCondtion)
                if(condtion.Check() == false)
                    return false;
            
            return true;
        }
    }

In Program.cs, se va crea lista formata din conditiile supuse verificarii si transmisa metodei Check.

    class Program
    {
        static void Main(string[] args)
        {
            var robot = new Robot();

            var conditionLst = new List<ICondtion>()
                                   {
                                       new Condition1(),
                                       new Condtion2(),
                                   };

            var envChecker = new EnvironmentChecker();
            if (envChecker.Check(conditionLst))
            {
                Console.WriteLine("Starting");
                robot.Start();
            }
            else
                Console.WriteLine("Failed...");

            Console.Read();
        }
    }

In acest moment, daca as vrea sa adaug o a treia conditie, se va observa ca doar extind codul, nu aduc modificari asupra lui. Imi voi crea o noua clasa Condition3 care va implementa interfata ICondition.

Open/Closed Principle este foarte puternic. In OOP, acesta poate fi implementat in doua moduri: Meyer’s Open/Closed Principle si Polymorphic Open/Closed Principle.

Category: Uncategorized

Your email address will not be published. Required fields are marked *

*