Kotlin The Future Of Android Development

An Introduction
Until recent past, Android app development was extensively done through the Java programming language and Java 6, which came in existence since 2006, two years before the release of Android devices.

Kotlin language is advent by JetBrains in 2011.As soon as did Kotlin reached at 1.0 status early in 2016 then at Google I/O 2017 in April, Google announced that Kotlin would be forever supported as a first class programming language for Android development. Moreover, the latest released of Android Studio 3.0 also supports Kotlin.

Kotlin is first statically typed and cross-platform language with out of box type interference which will ease developers to create or develop application for multiple platforms. Continue reading “Kotlin The Future Of Android Development”

SOLID architecture principles in C#

About SOLID

SOLID are basically 5 principles, which will help to create good software architecture. All design patterns are based on these SOLID principles.
These principles provide simple ways to move from tightly coupled code and little encapsulation to the desired results of loosely coupled and encapsulated real needs of a business properly, that can easily understandable and scalable.

SOLID is basically an acronym of the following:

  • S is single responsibility principle (SRP)
  • O stands for open closed principle (OCP)
  • L Liskov substitution principle (LSP)
  • I interface segregation principle (ISP)
  • D Dependency inversion principle (DIP)
  1. Single Responsibility Principle (SRP) 

A class should take one responsibility and there should be one reason to change that class.

Let us imagine one multipurpose tool which is a combination of so many different tools that contain knife, nail cutter, screw driver, etc. So are you willing to buy this tool for your daily work? Because there is a problem with this tool, which contains so many different tools, and if you want to add any other new tool to it, then you need to change the base and that is not good idea at all.

This is a bad architecture to introduce into any system, which may be harmful to existing system. It will be better if nail cutter can only be used to cut the nail or knife can only be used to cut vegetables.

Now check below C# example.

public class SmartPhone
    {
        public int SmartPhone_Id { get; set; }
        public string SmartPhone_Name { get; set; }


        public bool InsertIntoSmartPhoneTable(SmartPhone sp)
        {
            // Add SmartPhone details in database
            return true;
        }

        public void GenerateReport(SmartPhone sp)
        {
            // Generate Report
        }
 }

In above displayed example, you can see that “SmartPhone” class that is taking 2 responsibilities, first responsibility is to insert new SmartPhone details in database and second responsibility is to generate report based on SmartPhone details.

Here we can identify that, “SmartPhone” class should not take the responsibility for report generation because suppose some days after end user (may be your customer) asked you to give a facility to generate the report in Excel, PDF or any other reporting format, then this class will not be useful, and need to be changed which is not good practice.

So according to SRP principle, one class should take one responsibility at a time, so we have to  write one different class for report generation functionality, so that any changes in report generation functionality should not affect the “SmartPhone” class, as below.

public class SalesReportGeneration
{
    public void GenerateReport(SmartPhone sp)
    {
        // Report reneration with SmartPhone data.
    }
}

Hence this Single Responsibility Principle (SRP), which gives us a good way of identifying classes at the design phase of an application and that, makes you think of all the ways a class can change.

2. Open Closed Principle (OCP)
The Open Closed Principle says that, “A software module/class is open for extension and closed for modification”.
In other words, “Open for extension” means, we need to design our module/class for application/system in such a way that the new functionality can be added only when new requirements are generated or required by end user. “Closed for modification” means, we have already developed a module/class and which is go through unit testing. We should not make any changes/modification to that module/class unless and until we find any bugs/issues.
Now take our same “SalesReportGeneration” class as an example of this principle, which we had created earlier.

public class SalesReportGeneration
    {
        public string ReportType { get; set; }

        public void GenerateReport(SmartPhone sp)
        {
            if (ReportType == "EXCEL")
            {
                // Generate report in Excel Format
            }

            if (ReportType == "PDF")
            {
                // Generate report in PDF Format
            }
        }
    }

If you check this code, than can you identify what is the problem with the code? There are so many “If” clauses are there and if we want to introduce another new report type like ‘CSV’ and ‘WORD’, then we have to write another ‘if’ clauses, that will satisfies both types of reports.

Here, this “SalesReportGeneration” class should be open for extension but closed for modification. But what should we do, that will satisfy our new report type?

public class ISalesReportGeneration
    {
        public virtual void GenerateReport(SmartPhone sp)
        {
            // Report generation with SmartPhone data.
        }
    }

    public class CrystalReportGeneration : ISalesReportGeneration
    {
        public override void GenerateReport(SmartPhone sp)
        {
            // Report generation with SmartPhone data.
        }
    }

    public class PDFReportGeneration : ISalesReportGeneration
    {
        public override void GenerateReport(SmartPhone sp)
        {
            // Report generation with SmartPhone data.
        }
    }

Hence, when you want to introduce a new report types, then only need to inherit from “ISalesReportGeneration” interface. So “ISalesReportGeneration” interface is open for extension but closed for modification.

3.Liskov Substitution Principle (LSP)

The Liskov Substitution Principle (LSP) states that “you should be able to use any derived class instead of a parent class and have it behave in the same manner without modification”. That ensures that a derived class does not affect the behavior of the parent class. In other words that a derived class must be substitutable for its base class.

This principle is just an extension of the Open Close Principle and it means that we must ensure that new derived classes extend the base classes without changing their behavior.

Check the below picture. “Membership” is a parent class and Standard, Business and Premium are the child classes, inhering from “Membership” class.

Let us check below C# code.

public abstract class MemberShip
    {
        public virtual string GetMemberShipDetails(int memberId)
        {
            return "Base MemberShip";
        }
        public virtual string GetDiscountDetails(int memberId)
        {
            return "Base Discount";
        }
    }

    public class PremiumMemberShip : MemberShip
    {
        public override string GetMemberShipDetails(int memberId)
        {
            return "Child MemberShip";
        }
        public override string GetDiscountDetails(int memberId)
        {
            return "Child Discount";
        }
    }

    public class BusinessMemberShip : MemberShip
    {
        public override string GetMemberShipDetails(int memberId)
        {
            return "Child MemberShip";
        }
        public override string GetDiscountDetails(int memberId)
        {
            return "Child Discount";
        }
    }

    public class StandardMemberShip : MemberShip
    {
        public override string GetMemberShipDetails(int memberId)
        {
            return "Child MemberShip";
        }
        public override string GetDiscountDetails(int memberId)
        {
            throw new NotImplementedException();
        }
    }

Now, check the below code and that will violate the LSP principle. You can notice that for class “StandardMemberShip”, you will get exception for not implemented and that is violating LSP.

List<MemberShip> memberShipList = new List<MemberShip>();

memberShipList.Add(new PremiumMemberShip());
memberShipList.Add(new StandardMemberShip());

int memberId = 1245;

foreach (MemberShip e in memberShipList)
{
    e.GetDiscountDetails(memberId);
}

When we write above code, then gives below exception.

So to solve this issue, need to break the whole thing in 2 different interfaces, “IMemberShip” and “IDiscount” and implement according to passed memberId.

   public interface IMemberShip
   {
       string GetMemberShipDetails(int memberId);
}

   public interface IDiscount
   {
       string GetDiscountDetails(int memberId);
      }

4. Interface segregation principle (ISP)
The Interface Segregation Principle means “that clients should not be required or forced to implement interfaces which they do not use at all. Instead of that, we are splitting one big interface into smaller interfaces, which serves specific purpose to client about which methods he is interested more.”

Let us take an example, there is one database which is used for storing data of all types of membership details of all members (includes Standard, Business and Premium Membership). Now how can we define our interface “IMemberShip” in better way?

public interface IMemberShip
{
    bool AddMemberShipDetails();
}

And all types of member class will inherit this interface for storing membership details. As we are storing Standard, Business and Premium Membership details, and if we want only Standard Membership details. For this purpose, let we add one method to our interface.

public interface IMemberShip
{
    bool AddMemberShipDetails();

    bool ShowMemberShipDetails(int memberId);
}	

But this code breaks some rules. Here we are showing Standard Membership details also. So to solve this problem, we introduce one more Interface as below.

    public interface IAddMemberShipOperation
    {
        bool AddMemberShipDetails();
    }

    public interface IShowMemberShipOperation
    {
        bool ShowMemberShipDetails(int memberId);
}

As from above code, we had created two separate intercases, “IAddMemberShipOperation”, that only add MemberShip details, and “IShowMemberShipOperation” interface only fetch and display MemberShip details.

So we had distributed two different operations, to Add details and Get details.

5. Dependency inversion principle (DIP)

The Dependency Inversion Principle (DIP) states that high-level modules/classes should not depend on low-level modules/classes of an application. Both should depend upon abstractions. Second point is that, abstractions should not depend upon details of an application. Details should depend upon abstractions.

In simple words, you can not write any tightly coupled code in your application, because that will becomes difficult to manage once your application grows from small scale to large scale. If one class depends on another class, then we need to change that class if something code changes are required in that dependent class. To avoide this type of situation, we always try to write loosely couple code.

Let say this example is used for add error log details in our application.

public class MemberShip
    {
        private EmailLogger objError = new EmailLogger();
        public virtual void AddLogger()
        {
            try
            {
                // code goes here
            }
            catch (Exception ex)
            {
                objError.Handle(ex.ToString());
            }
        }
    }

When we have to write different log details like Event Viewer, Email Logger, File Logger etc, then this will not help.

So we can modify our code as below;

public interface IAppLogger
    {
        void Handle(string error);
    }

    public class FilesLogger : IAppLogger
    {
        public void Handle(string error)
        {
            System.IO.File.WriteAllText(@"c:\Error.txt", error);
        }
    }

    public class EventViewerLogger : IAppLogger
    {
        public void Handle(string error)
        {
            // log errors for event viewer
        }
    }

    public class EmailLogger : IAppLogger
    {
        public void Handle(string error)
        {
            // Send Exception in email
        }
    }

MemberShip iMemberShip = new MemberShip(new EmailLogger());

Conclusion of SOLID principles

S stand for SRP (Single responsibility principle):- A class should take care of only one responsibility.

O stand for OCP (Open closed principle):- Extension should be preferred over modification.

L stand for LSP (Liskov substitution principle):- A parent class object should be able to refer child objects seamlessly during runtime polymorphism.

I stand for ISP (Interface segregation principle):- Client should not be forced to use an interface if it does not need it.

D stand for DIP (Dependency inversion principle):- High level modules should not depend on low level modules but should depend on abstraction.