Archivi tag: solid

SOLID principles by example: Dependency inversion

This is the last blog post about the SOLID principles in object-oriented programming and we talk about the Dependency Inversion Principle (DIP).

Screenshot_1

The principle states:

A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend on details. Details should depend on abstractions.

Continua a leggere SOLID principles by example: Dependency inversion

SOLID principles by example: Interface segregation

This post continues the analisys of the SOLID principles and it’s about the Interface Segregration Principle (ISP).

Screenshot_1.png

Definition

The interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use.

Continua a leggere SOLID principles by example: Interface segregation

SOLID principles by examples: Liskov Substitution Principle

In this post we’re going to explore the third of the SOLID principles: the Liskov Substitution Principle (LSP).

The most practical definition of this principle was written by Robert C. Martin in his book Agile Software Development, Principles, Patterns, and Practices.

Subtypes must be substitutable for their base types.

The concept was introduced by Barbara Liskov in 1987. The formal definition is:

Let q(x) be a property provable about objects x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T.

For our daily activities we must remember that a subclass should override the parent class’ methods in a way that doesn’t break functionality from a consumers’s point of view.

Example


abstract class MusicalInstrument
    {
        public abstract void PlayANote();
    }

class Piano : MusicalInstrument
    {
        public override void PlayANote()
        {
            PressKey();
        }

        private void PressKey()
        {
            //Press a piano key.
        }
    }

class Saxophone : MusicalInstrument
    {
        public override void PlayANote()
        {
            Blow();
        }

        private void Blow()
        {
            //Blow air into the instrument.
        }
    }

The evergreen example

To better underestand LSP let’s examine this classic example. It’s a classic because it’s easy to understand and very meaningful. We start with this question:

Is a square a special rectangle in OOP?

We try to answer this question with this simple class hierarchy: a Rectangle as base class and a Square class that inherits from it. In the Square class we override the behavior of the setters to enforce that the the Heigth and Width properties have the same value.

class Rectangle
    {
        public virtual float Heigth { get; set; }
        public virtual float Width { get; set; }
        public virtual float Area
        {
            get { return Heigth * Width; }
        }
    }

class Square : Rectangle
    {
        private float _heigth;

        private float _width;

        public override float Heigth
        {
            get
            {
                return _heigth;
            }
            set
            {
                _heigth = value;
                _width = value;
            }
        }

        public override float Width
        {
            get
            {
                return _width;
            }
            set
            {
                _width = value;
                _heigth = value;
            }
        }
    }

Now we have to remember that a subclass must override the base class in a way that it doesn’t break functionality from a client’s POV. We write these two tests to check.


[TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestWithRectangle()
        {
            Rectangle sut = new Rectangle();
            sut.Heigth = 3;
            sut.Width = 7;

            Assert.AreEqual(21, sut.Area);
        }

        [TestMethod]
        public void TestWithSquare()
        {
            Rectangle sut = new Square();
            sut.Heigth = 3;
            sut.Width = 7;

            Assert.AreEqual(21, sut.Area); //This test will fail. Area equals 49.
        }

    }

So it’s clear that in OOP a square isn’t a particulare case of a rectangle. How can we do to better organize these classes? The typical approach consists of creating an abstract class (or an interface). For example

abstract class Shape
    {
        public abstract float Area { get; }
    }

 class Rectangle : Shape
    {
        public float Heigth { get; set; }
        public float Width { get; set; }
        public override float Area
        {
            get { return Heigth * Width; }
        }
    }

    class Square : Shape
    {
        public float Edge { get; set; }

        public override float Area
        {
            get { return Edge * Edge; }
        }
    }

Now our code states that both the Rectangle class and the Sqare class are Shapes which is true. Our code is also safer and we don’t have any situation where a client will receive unexpected values.

TL;DR

In this post we explored the Liskov Substituion Principle (LSP) and we learned that it’s not true that real-life objects always maps to the same OOP structure / class ecosystem. When also tried to improve the wrong example with the simple technique of adding an abstraction layer (the Shape class).

SOLID principles by examples: open/closed

This post continues the analisys of the SOLID principles started some blog posts ago. This is the turn for the Open Closed Priciple (OCP).

The definition

An object/entity should be open for extension but closed for modification.

What we are basically talking about is to design our modules, classes and functions in a way that when a new functionality is needed, we should not modify our existing code but rather write new code that will be used by existing code.

Continua a leggere SOLID principles by examples: open/closed

SOLID principles by examples: single responsability

This blog post will explain with simple examples the Singe Responsabily Principle of SOLID agiles principles to better understand how we can improve our daily coding activites. In future post I’ll cover the other four priciples.

The Definition

A class should have only one reason to change.

Defined by Robert C. Martin in his book Agile Software Development, Principles, Patterns, and Practices it is the first of the five SOLID agile principles. What it states is very simple, however achieving that simplicity is not so obvious.

Continua a leggere SOLID principles by examples: single responsability

SOLID principles by examples: introduction

SOLID is a common acronym in the software development world. It’s useful to remeber five best practices to design classes in a object oriented language. It means:



Initial

Stands for

Concept

SRP Single Responsability Principle A class should have only a single responsability.
OCP Open Closed Principle Software entities should be open for extension but closed for modification.
LSP Liskov Substitution Principle Objects in a program should be replaceable with instances of theri subtypes without altering the correctness of that program.
ISP Interface Segregation Principle Many client-specific interfaces are better than one general purpose-interface.
DIP Dependency Injection Principle

One should depend upon abstractions, not concretions.

These concepts are easy to understand when we read them, but what does it mean to apply them in our daily coding activities? What do we have to do?

In the next posts we’ll go through each concept with coding examples because as someone much smarter than me said:

Tell me and I’ll foget, show me and I might remember. Involve me and I will remember. – Confucius

Gold-plating

Qualche settimana fa non conoscevo questo termine.

Avete presente quel momento in cui si sta sviluppando qualcosa e il pensiero comincia a prendere la tangente: “Ma se succedesse anche questo allora c’è bisogno di quest’altro. A questo punto all’ora potrei implementare questa funzione!”. Oppure: “Aggiungiamo anche questa funzione perché magari può succedere che…”. Quando sentiamo queste frasi dette da qualcun altro o che girano per la nostra testa dovremmo immediatamente tirare il freno a mano. Quello che sta succedendo è, molto probabilmente, gold-plating. Stiamo facendo più del richiesto.

Quando sviluppiamo un software che sia su commessa o che sia per essere proposto nel mercato, dovremmo fare ogni sforzo possibile per implementare solo ed esclusivamente quelle funzioni che sono state analizzate e confermate in fasi precedenti allo sviluppo. Se stiamo affrontando un esercizio accademico, o per studio, allora ci può stare ma non esistono altre eccezioni.

I motivi?

  • Potremmo sviluppare qualcosa di non gradito;
  • Potremmo addentrarci nello sviluppo di qualcosa che, involontariamente, peggiora la situazione del progetto perché più complessa del previsto;
  • Si compromette la buona riuscita del progetto perché si sta dedicando tempo a qualcosa che  non era stato inserito nella pianificazione;
  • Potremmo scatenare effetti collaterali in altre parti del software a cui non abbiamo pensato;
  • Aumentano i costi;
  • Il committente non sta pagando per quelle righe di codice.

Il concetto del gold-plating non si applica solo a livello di progetto ma a tutti gli strati di una progettazione software:

  • Se stiamo sviluppando una classe potremmo inserire funzioni non strettamente di sua competenza;
  • In una interfaccia utente potremmo mettere troppe funzioni che ne complicano l’utilizzo;
  • In una tabella di un db potremmo mettere colonne che causano ridondanze che devono essere mantenute per niente.
  • Un metodo di una classe potrebbe voler fare troppe cose e diventare un monolite.

Come programmatori dovremmo sempre essere sull’attenti quando stiamo implementando qualcosa: meno scriviamo e meno danni facciamo, meno danni facciamo e più è alta la probabilità di fare qualcosa che funziona.