Separation Of Concerns är den första principen i SOLID och innebär att en klass bara ska göra en enda sak. I mitt exempel har vi en PriceCalculator klass som räknar ut hur mycket det kostar att hyra en film. Förutom att räkna ut priset kollar den vad det är för kundtyp och filmtyp. Switch och if satsen är inte helt otydligt men det går att få klassen betydligt tydligare. Nu har den fler ansvar och skulle man lägga till en kundtyp eller en filmtyp till skulle koden börja likna spagettikod och vara jobbig att underhålla.

 

Ett anrop till klassen ser ut såhär:

 

PriceCalculator priceCalculator = new PriceCalculator();

int price = priceCalculator.CalculatePrice(CustomerType.VIP, MovieType.Normal);

 

När CalculatePrice klassen anropas med VIP kund och Normal film kommer den att skicka tillbaks ett pris på 20 kr för att VIP kunden får 5 kr i rabatt. Här nedanför är koden för att komma fram till det.

 

public enum CustomerType

{

    Normal,

    VIP

}

 

public enum MovieType

{

    Normal,

    Transfer

}

 

public class PriceCalculator

{

    public int CalculatePrice(CustomerType customerType, MovieType movieType)

    {

        switch (customerType)

        {

            case CustomerType.Normal:

                if (movieType == MovieType.Normal)

                {

                    return 25 - 0;

                }

                else if (movieType == MovieType.Transfer)

                {

                    return 35 - 0;

                }

                break;

            case CustomerType.VIP:

                if (movieType == MovieType.Normal)

                {

                    return 25 - 5;

                }

                else if (movieType == MovieType.Transfer)

                {

                    return 35 - 5;

                }

                break;

        }

 

        return 0;

    }

}

 

 

Ett första steg för att få koden mer lättläst är att ta bort CalculatePrice klassens ansvar för att kolla kundtyp, filmtyp och vad det ska vara för rabatt. Vi delar upp det i två klasser. Kundtypen används bara för att ta reda på vad det ska vara för rabatt så vi skapar en kundklass med en property för rabatt. Filmtypen används för att bestämma vad det ska vara för pris på filmen så vi skapar en klass filmklass som har en property för pris. Genom att göra det här så blir det inte så mycket kvar att göra för PriceCalculator mer än att ta priset – rabatten och returnera värdet. Slutresultatet för PriceCalculatorklassen blir alltså:

 

    public class PriceCalculator

    {

        public int CalculatePrice(Customer customer, Movie movie)

        {

          return movie.Price - customer.Rebate;

        }

    }

 

Men hur ska vi göra för att på ett tydligt sätt visa att det finns olika filmtyper som har olika pris? Ett sätt är att skapa en basklass som heter film och har ett fast pris på 25 och sen göra en underklass som ärver den klassen och gör en override på priset.

 

    public class Movie

    {

        public virtual int Price { get { return 25; } }

    }

 

    public class TransferMovie : Movie

    {

        public override int Price { get { return 35; } }

    }

 

På precis samma sätt kan vi göra med kundklassen för att kunna sätta olika rabatt.

 

    public class Customer

    {

        public virtual int Rebate { get { return 0; } }

    }

 

    public class VIPCustomer : Customer

    {

        public override int Rebate { get { return 5; } }

    }

 

För att göra ett anrop för en VIP kund på en normal film nu så skiljer det inte så mycket från tidigare. Man byter ut Enum typerna till klasserna man skapat istället bara.

 

PriceCalculator priceCalculator = new PriceCalculator();

int price = priceCalculator.CalculatePrice(new VIPCustomer(), new Movie());

 

Returvärdet man får kommer att vara 20 kr precis som tidigare.

 

Separation Of Concerns är alltid bra att ha i bakhuvudet när man kodar och börjar få nestlade if satser eller switchsatser. Ibland går det att på ett smidigt sätt bryta isär det man gör och på så sätt få kod som är lättare att underhålla och tydligare att använda.