Showing posts with label Design patterns. Show all posts
Showing posts with label Design patterns. Show all posts

Monday, May 04, 2020

The startegy pattern




The Strategy pattern defines a family of algorithms whose individual behaviours are encapsulated allowing them to be interchangeable. Strategy lets the algorithm vary independently from clients that use it. You can use this pattern to implement the Open/Close principle. 



Problem 


I'm building a digital wallet, users can choose the kind of encryption they need to protect their data with. Since the process of encrypting is the same. That is choosing their data, performing the encryption and storing it, we do not wish to duplicate the process for each new encryption type. Also, we want the flexibility to create new encryptions in the future and not affect the existing encrypted data. The Strategy Pattern can do just this.   

Analysis 


We need to be able to encapsulate the encryption algorithms and switch between them at runtime. Without the client being aware of the algorithms themselves. 

Solution 


First, we define an encryption interface IEncryption. We can now create different algorithms as the implementation of this interface. We now have three encryption classes class SHA1, class SHA256 and class SHA512 that implement the IEncryption interface. Then we create an Encryption Service class called EncryptionService that maintains the reference to the algorithms and decouples the client form the actual encryption classes. Alternatively, we could have substituted the interface with an Abstract class, this would allow us to define a default encryption to use.


Illustration 







Code


  public class Program
    {
        private static void Main(string[] args)
        {
            List encsvc = new List { new EncryptionService(new SHA1()), new EncryptionService(new SHA256()), new EncryptionService(new SHA512()) };

            foreach (var con in encsvc)
            {
                con.DoEncryption();
            }

            Console.ReadKey();
        }
    }


    public interface IEncryption

    {
        public void Encrypt();
    }


    public class SHA1 : IEncryption

    {
        public void Encrypt()
        {
            Console.WriteLine(
              "Encrypt using SHA1");
        }
    }

    internal class SHA256 : IEncryption

    {
        public void Encrypt()
        {
            Console.WriteLine(
              "Encrypt using SHA256");
        }
    }

    internal class SHA512 : IEncryption

    {
        public void Encrypt()
        {
            Console.WriteLine(
              "Encrypt using SHA512");
        }
    }

    internal class EncryptionService

    {
        private IEncryption encryption;


        public EncryptionService(IEncryption encryption)
        {
            this.encryption = encryption;
        }

        public void DoEncryption()
        {
            encryption.Encrypt();
        }
    }
}

Friday, February 10, 2012

The Adapter Pattern



The adapter pattern is used to match one interface with another. This is a useful pattern to use when implementing Interface Segregation Principles.

Problem  

I'm building a digital simulator called FarmAnimals that can build farm animals with many capabilities. Some of these capabilities I wish to implement on my own and for others Id like to use an external source like a library. I have found a library called ZooLib that offers animal capabilities that I'd like to use. But the ZooLib library classes implement an interface that is very different to the one implemented by my classes in FarmAnimals. Thankfully there's an Adapter pattern to  the rescue!

Analysis 

I've decided to create a Goat using my FarmAnimals application. FarmAnimals contains an Interface 
IFarmAnimal which defines a method called getDietaryType(). All animals need to eat is a given and so I expect all my animal classes to implement IFarmAnimal.

The ZooLib library has a useful function getFamily() that can help identify the family my animals belong to. I want to use  this feature in FarmAnimals. But my Goat class implements an IFarmAnimal interface and the getFamily which is part of the MountainGoat class in ZooAnimals implements an interface called IZooAnimals which is a completely different interface.

Solution 

Create an abstract base class called ZooAnimalAdapter that implements both interfaces. It delegates all my IFarmAnimal operations to the concrete subclasses in this case Goat and builds wrappers around the IFarmAnimal which are also available as part of my Goat class.

Code


Contents of the ZooLib library

public interface IZooAnimal
{
    void getFamily();
}

public class MountainGoat : IZooAnimal
{
    public void getFamily()
    {
        Console.WriteLine("Family : Bovidae");
    }
}

Contents of my FarmAnimal application

public interface IFarmAnimal
{
   void getDietaryType();
}


public abstract class ZooAnimalAdapter:IFarmAnimal,IZooAnimal
{
   public abstract void getDietaryType();
   public void getFamily()
   {
      IZooAnimal za = new MountainGoat();
      za.getFamily();
   }
}

public class Goat: ZooAnimalAdapter
{
   public void getDietaryType()
   {
      Console.WriteLine("Diet: Herbivor");
   }
}
public class Program
{
   static void Main(string[] args)
   {
       Goat g = new Goat();
       g.getFamily();
       g.getDietaryType();
       Console.ReadKey();
   }
}