Fundamental concepts of OOP
One of the first items that should be introduced when first embarking on learning OOP is the concept of PIE:
In OOP the term polymorphism refers to the action of an class that derives from other class(es) and can perform the behaviour of it’s base classes or define new behaviour (representing more than one type).
For more information I recommend visiting the MSDN Polymorphism C# Programming Guide
The act of deriving an class from an existing class, the derived class can be referred to as the subclass with the class that was derived from being referred to as the superclass.
Inheritance can be thought of as an “is-a” relationship, for more information visit the MSDN Inheritance C# Programmers Guide
Encapsulation hides the details of how an object performs behaviour, by protecting our users from knowing how an object works they can simply use the object without having to obtain details of it’s inner workings. This has a number of benefits:
- The object is easier to work with
- If the inner workings change, the user should not need to change
More information can be found on wikipedia
Once we have learned these concepts the next challenge is knowing how to apply them effectively.
Principles of Class Design
A lot of times people ask how to get better at designing OO systems and the responses usually involve the person studying design patterns, however I believe that more use can be gained by studying the principles of class design, these are the principles that are at the core of each of the design patterns.
The principles of class design was compiled by OO guru Robert C. Martin in the book Agile Software Development, Principles, Patterns, and Practices This is one of the best books I own and if you don’t own a copy I highly recommend it getting one!
The 5 principles are:
OCP – Open Closed Principle
SRP – Single Responsibility Principle
LSP – Liskov’s Substitution Principle
DIP – Dependency Inversion Principle
ISP – Interface Segregation Principle
These principles should not been seen as principles that should be followed 100% as you will see it is near impossible to do so however should be seen as principles we should try to adhere to as much as possible.
OCP was coined by Bertrand Meyer, it states that a class should be closed modification while open for extensibility, main ways to achieve this involve making good use of abstractions by allowing changes to made via subclasses or overriding method behaviour.
SRP states that a class should have one, and only one, reason to change, this can be achieved by separating out responsibility to appropriate objects (highly cohesive classes) and to not have one class perform varied activities.
LSP was coined by Barbara Liskov and at it’s core states that a derived class should be substitutable with it’s base class, an example of not conforming to this is by misuse of inheritance.
If we take an example of a rectangle class and say we want to add another shape class of square we could inherit from the existing rectangle class however the behaviour of a square does not conform to that of a rectangle (a rectangle can have varying heights and widths, a square cannot), if a user changes the height of a rectangle the width will unaffected however if we changed to the height against a square we would also need to change the width to match.
Dependency Inversion Principle
DIP states that we should depend upon abstractions and not depend on concrete types, this is in practice impossible in all cases as we need to create an instance of a class at some point. However by depending on abstractions rather than concrete classes (some design patterns help accomplish this) we make our code more loosely coupled and protects us from the most feared word in software design “change” 🙂
Interface Segregation Principle
ISP can be thought to relate to SRP if a class has a very large interface it will generally trying to perform too much work, a side-effect of not conforming to this principle is that clients that only use a subset of a very large interface are at risks to changes in other areas of the same interface, by breaking the interface up we can reduce the likelihood that a client will be affected by changes to the interface.
Design patterns in OOP are a collection of recurring software designs that can be applied into common scenarios and assigned a name.
The most common set of design patterns are known as the GoF (Gang of Four) design Patterns this book can be a difficult read when first learning about design patterns, instead I would recommend using GoF Design Patterns as a reference and instead getting a copy of Head First Design Patterns this is an excellent book and even covers some of the principles shown above. You can also visit dofactory.com which has lots of examples of the GoF design patterns in C#