Tagged: software design

DRY Principle

I read a couple of books on software development lately and I stumbled upon some more principles of software design that I want to talk about. And the first and probably the most important one is this:

Don’t repeat yourself.

Well, this is new … I mean as soon as any programmer learns about functions and procedures, he knows, that it is way better to split things up into smaller reusable pieces. The thing is, this principle should be used in much broader terms. As in NEVER EVER EVER repeat any information in a software project.

The long version of the DRY principle, which was authored by Andy Hunt and David Thomas states

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

The key is, that it doesn’t apply only to the code. Every single time you have something stored in two places simultaneously, you can be almost certain, that it will cause pain at some point in the future of your project. It will sneak up on you from behind and hit you with a baseball bat. And then keep kicking you while you’re down. This is one of those cases in which foretelling future works damn well.

Authors of The Pragmatic Programmer show this on a great example with database schemes. At one point in your project you make up a database scheme, usually on a paper. Then you store it with your project somewhere in plain text or something. The people responsible for writing code will look in the file and create database scripts for creating the database and start putting various queries in the code.

What happened now? You have two definitions of the database scheme in your system. One in the text file and another as a database script. After while, the customer shows up and demands some additional functionality, that requires altering the scheme. Well, that shouldn’t be that much of a problem. You simply change the database script, alter the class that handles queries and go get some lunch. Everything works fine, but after a year or two, you might want to change the scheme a bit further. But you don’t remember a thing about the project, so you will probably want to look at the design first, to catch up. Or you hire someone new, who will look on the scheme definition. And it will be wrong.

Storing something multiple times is painful for a number of reasons. First, you have to sync changes between the representations. When you change the scheme, you have to change the design too and vice versa. That’s an extra work, right?  And as soon as you forget to alter both, it’s a problem.

The solution to this particular problem is code generation. You can create the database definition and a very simple script, that will turn it into the database script. Here’s a wonderful illustration (by Bruno Oliveira) of how that works :).

Repetitive tasks figure

Sources

Advertisements

Design Patterns: Bridge

Today I’m going to write some examples of Bridge. The design pattern not the game. Bridge is a structural pattern that decouples abstraction from the implementation of some component so the two can vary independently. The bridge pattern can also be thought of as two layers of abstraction[3].

Bridge pattern is useful in times when you need to switch between multiple implementations at runtime. Another great case for using bridge is when you need to couple pool of interfaces with a pool of implementations (e.g. 5 different interfaces for different clients and 3 different implementations for different platforms). You need to make sure, that there’s a solution for every type of client on each platform. This could lead to very large number of classes in the inheritance hierarchy doing virtually the same thing. The implementation of the abstraction is moved one step back and hidden behind another interface. This allows you to outsource the implementation into another (orthogonal) inheritance hierarchy behind another interface. The original inheritance tree uses implementation through the bridge interface. Let’s have a look at diagram in Figure 1.

Bridge pattern UML diagram

Figure1: Bridge pattern UML diagram

As you can see, there are two orthogonal inheritance hierarchies. The first one is behind ImplementationInterface. This implementation is injected using aggregation through Bridge class into the second hierarchy under the AbstractInterface. This allows having multiple cases coupled with multiple underlying implementations. The Client then uses objects through AbstractInterface. Let’s see it in code.

C++

/* Implemented interface. */
class AbstractInterface
{
    public:
        virtual void someFunctionality() = 0;
};

/* Interface for internal implementation that Bridge uses. */
class ImplementationInterface
{
    public:
        virtual void anotherFunctionality() = 0;
};

/* The Bridge */
class Bridge : public AbstractInterface
{
    protected:
        ImplementationInterface* implementation;

    public:
        Bridge(ImplementationInterface* backend)
        {
            implementation = backend;
        }
};

/* Different special cases of the interface. */

class UseCase1 : public Bridge
{
    public:
        UseCase1(ImplementationInterface* backend)
          : Bridge(backend)
        {}

        void someFunctionality()
        {
            std::cout << "UseCase1 on ";
            implementation->anotherFunctionality();
        }
};

class UseCase2 : public Bridge
{
    public:
        UseCase2(ImplementationInterface* backend)
          : Bridge(backend)
        {}

        void someFunctionality()
        {
            std::cout << "UseCase2 on ";
            implementation->anotherFunctionality();
        }
};

/* Different background implementations. */

class Windows : public ImplementationInterface
{
    public:
        void anotherFunctionality()
        {
            std::cout << "Windows" << std::endl;
        }
};

class Linux : public ImplementationInterface
{
    public:
        void anotherFunctionality()
        {
            std::cout << "Linux!" << std::endl;
        }
};

int main()
{
    AbstractInterface *useCase = 0;
    ImplementationInterface *osWindows = new Windows;
    ImplementationInterface *osLinux = new Linux;

    /* First case */
    useCase = new UseCase1(osWindows);
    useCase->someFunctionality();

    useCase = new UseCase1(osLinux);
    useCase->someFunctionality();

    /* Second case */
    useCase = new UseCase2(osWindows);
    useCase->someFunctionality();

    useCase = new UseCase2(osLinux);
    useCase->someFunctionality();

    return 0;
}

Download complete source file from github.

Python


class AbstractInterface:

    """ Target interface.

    This is the target interface, that clients use.
    """

    def someFunctionality(self):
        raise NotImplemented()

class Bridge(AbstractInterface):

    """ Bridge class.
    
    This class forms a bridge between the target
    interface and background implementation.
    """

    def __init__(self):
        self.__implementation = None

class UseCase1(Bridge):

    """ Variant of the target interface.

    This is a variant of the target Abstract interface.
    It can do something little differently and it can
    also use various background implementations through
    the bridge.
    """
    
    def __init__(self, implementation):
        self.__implementation = implementation

    def someFunctionality(self):
        print "UseCase1: ",
        self.__implementation.anotherFunctionality()

class UseCase2(Bridge):
    def __init__(self, implementation):
        self.__implementation = implementation

    def someFunctionality(self):
        print "UseCase2: ",
        self.__implementation.anotherFunctionality()

class ImplementationInterface:
    
    """ Interface for the background implementation.

    This class defines how the Bridge communicates
    with various background implementations.
    """

    def anotherFunctionality(self):
        raise NotImplemented

class Linux(ImplementationInterface):

    """ Concrete background implementation.

    A variant of background implementation, in this
    case for Linux!
    """

    def anotherFunctionality(self):
        print "Linux!"

class Windows(ImplementationInterface):
    def anotherFunctionality(self):
        print "Windows."

def main():
    linux = Linux()
    windows = Windows()

    # Couple of variants under a couple
    # of operating systems.
    useCase = UseCase1(linux)
    useCase.someFunctionality()

    useCase = UseCase1(windows)
    useCase.someFunctionality()

    useCase = UseCase2(linux)
    useCase.someFunctionality()

    useCase = UseCase2(windows)
    useCase.someFunctionality()

Download complete source file from github.

Summary

The Bridge pattern is very close to the Adapter by it’s structure, but there’s a huge difference in semantics. Bridge is designed up-front to let the abstraction and the implementation vary independently. Adapter is retrofitted to make unrelated classes work together [1].

Sources

  1. http://sourcemaking.com/design_patterns/bridge
  2. http://www.oodesign.com/bridge-pattern.html
  3. http://en.wikipedia.org/wiki/Bridge_pattern

Design Patterns: Adapter

And back to design patterns! Today it’s time to start with structural patterns, since I have finished all the creational patterns. What are those structural patterns anyway?

In Software Engineering, Structural Design Patterns are Design Patterns that ease the design by identifying a simple way to realize relationships between entities.

The first among the structural design patterns is Adapter. The name for it is totally appropriate, because it does exactly what any other real-life thing called adapter does. It converts some attribute of one device so it is usable together with another one. Most common adapters are between various types of electrical sockets. The adapters usually convert the voltage and/or the shape of the connector so you can plug-in different devices.

The software adapters work exactly like the outlet adapters. Imagine having (possibly a third-party) class or module you need to use in your application. It’s poorly coded and it would pollute your nicely designed code. But there’s no other way, you need it’s functionality and don’t have time to write it from scratch. The best practice is to write your own adapter and wrap the old code inside of it. Then you can use your own interface and therefore reduce your dependence on the old ugly code.

Especially, when the code comes from a third-party module you have no control on whatsoever. They could change something which would result in breaking your code on many places. That’s just unacceptable.

Adapter pattern example

UML example of adapter pattern

Here is an example class diagram of adapter use. You see there is some old interface which the adapter uses. On the other end, there is new target interface that the adapter implements. The client (i.e. your app) then uses the daisy fresh new interface. For more explanation see the source code examples bellow.

C++

typedef int Cable; // wire with electrons

/* Adaptee (source) interface */
class EuropeanSocketInterface
{
    public:
        virtual int voltage() = 0;

        virtual Cable live() = 0;
        virtual Cable neutral() = 0;
        virtual Cable earth() = 0;
};

/* Adaptee */
class Socket : public EuropeanSocketInterface
{
    public:
        int voltage() { return 230; }

        Cable live() { return 1; }
        Cable neutral() { return -1; }
        Cable earth() { return 0; }
};

/* Target interface */
class USASocketInterface
{
    public:
        virtual int voltage() = 0;

        virtual Cable live() = 0;
        virtual Cable neutral() = 0;
};

/* The Adapter */
class Adapter : public USASocketInterface
{
    EuropeanSocketInterface* socket;

    public:
        void plugIn(EuropeanSocketInterface* outlet)
        {
            socket = outlet;
        }

        int voltage() { return 110; }
        Cable live() { return socket->live(); }
        Cable neutral() { return socket->neutral(); }
};

/* Client */
class ElectricKettle
{
    USASocketInterface* power;

    public:
        void plugIn(USASocketInterface* supply)
        {
            power = supply;
        }

        void boil()
        {
            if (power->voltage() > 110)
            {
                std::cout << "Kettle is on fire!" << std::endl;
                return;
            }

            if (power->live() == 1 && power->neutral() == -1)
            {
                std::cout << "Coffee time!" << std::endl;
            }
        }
};

int main()
{
    Socket* socket = new Socket;
    Adapter* adapter = new Adapter;
    ElectricKettle* kettle = new ElectricKettle;

    /* Pluging in. */
    adapter->plugIn(socket);
    kettle->plugIn(adapter);

    /* Having coffee */
    kettle->boil();

    return 0;
}

Download example from Github.

Python

# Adaptee (source) interface
class EuropeanSocketInterface:
    def voltage(self): pass

    def live(self): pass
    def neutral(self): pass
    def earth(self): pass

# Adaptee
class Socket(EuropeanSocketInterface):
    def voltage(self):
        return 230

    def live(self):
        return 1

    def neutral(self):
        return -1

    def earth(self):
        return 0

# Target interface
class USASocketInterface:
    def voltage(self): pass

    def live(self): pass
    def neutral(self): pass

# The Adapter
class Adapter(USASocketInterface):
    __socket = None

    def __init__(self, socket):
        self.__socket = socket

    def voltage(self):
        return 110

    def live(self):
        return self.__socket.live()

    def neutral(self):
        return self.__socket.neutral()

# Client
class ElectricKettle:
    __power = None

    def __init__(self, power):
        self.__power = power

    def boil(self):
        if self.__power.voltage() > 110:
            print "Kettle on fire!"
        else:
            if self.__power.live() == 1 and \
               self.__power.neutral() == -1:
                print "Coffee time!"
            else:
                print "No power."

def main():
    # Plug in
    socket = Socket()
    adapter = Adapter(socket)
    kettle = ElectricKettle(adapter)

    # Make coffee
    kettle.boil()

    return 0

if __name__ == "__main__":
    main()

Download example from Github.

Summary

The adapter uses the old rusty interface of a class or a module and maps it’s functionality to a new interface that is used by the clients. It’s kind of wrapper for the crappy code so it doesn’t get your code dirty.

Sources

Interface Segregation Principle in Software Design

ISP, not Internet Service Provider, but Interface Segregation Principle is the last of the famous principles of SOLID object-oriented software design. It was introduced by Robert C. Martin in his series of articles in 1996. Intention of this principle is to avoid creation of “fat” interfaces.

A fat (or polluted) interface comes from extending current interface with some functionality that is useful only to a subset of entities that depends on it. This phenomenon leads eventually to creation of dummy methods just to be able to use the interface. And that’s bad. Dummy methods are dangerous and also violate the LSP. The ISP as wrote the author declares that

Clients should not be forced to depend upon interfaces that they do not use.

Each interface should have clearly defined purpose and make reasonable abstraction of a part of the current problem. The best practice (in my opinion) is to use multiple inheritance when implementing the interfaces. This method will separate things that don’t logically belong together on the abstraction level and clean wrong dependencies in our code. But it also allow us to couple them back together in objects, that cover multiple things and work on the same data.

Let me show an example of how it should not look like. This is an interface for a car.

/* Bad example */
class CarOperation
{
    public:
        virtual void steer(int degrees) = 0;
        virtual void pullHandbrake() = 0;
        virtual void accelerate() = 0;

        virtual void shift(int gear) = 0;

        virtual void toggleAirConditioning() = 0;
};

There are a couple common things you can do with a car. Every car usually has a steering wheel, an acceleration pedal and possibly even a handbrake. But what about those cars with automatic transmission? They don’t allow the driver to shift gears, so what should they do with the shift method? The interface enforces it’s implementaion. And again with air conditioning. Some cars don’t have an air conditioner. The way here is to split CarOperationinterface into a couple smaller ones.

class BasicCarOperation
{
    public:
        virtual void steer(int degrees) = 0;
        virtual void pullHandbrake() = 0;
        virtual void accelerate() = 0;
};

class GearboxCarOperation
{
    public:
        virtual void shift(int gear) = 0;
};

class AirConditioningCarOperation
{
    public:
        virtual void toggleAirConditioning() = 0;
};

class AlfaRomeo166 : public BasicCarOperation, GearboxCarOperation, AirConditioningCarOperation
{
    /* Implementation of all the interfaces. */
};

class SkodaFavorit136L : public BasicCarOperation, GearboxCarOperation
{
    /* No air conditioning for old cars. */
};

The clients that will use the concrete cars won’t look at them directly as AlfaRomeo166 or SkodaFavorit136L. They will operate them through the interfaces. If some client function wants to turn on a air-conditioning it will look like this

void beCool(AirConditioningCarOperation* vehicle)
{
    vehicle->toggleAirConditioning();
}

That’s the beauty of interface segregation principle. You get exactly what you need, nothing more and nothing less, which makes the code easier to maintain, reuse and saves you from a cascade of unpredictable errors, when you decide to modify existing code.

Sources

Dependency Inversion Principle

DIP or Dependency Inversion Principle is yet another guideline for the software designers that work in object-oriented environment. It’s the D in SOLID and it has one huge advantage over the other principles: in case it doesn’t work for you, you can always get some tortilla chips to help (they work wonderfully with dip ;-)).

This principle was introduced by Robert C. Martin in his article in 1996. He points out that the usual way of dependency design among software project is to make general high-level modules dependent on the low-level utilities and mechanism that do the hard (and in most cases also not very interesting) work. This way of dependency makes the high level modules very hard to reuse without many modifications (and people often thing “why the hell didn’t I wrote it again”). And this is wrong.

The high-level modules are key part of the application. That’s where the heart of the application actually is. The algorithm that knows how to use the lower-level modules to achieve the desired functionality of our application. And we want to reuse that without having to modify every third line, so what do we do?

Mr. Martin proposes the Dependency Inversion Principle, which says

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

It’s a little tough one to understand at first, so let me explain. The principle states, that there should be some additional layer between high and low level modules — the layer of abstractions. The author says, that there should be an interface (or abstraction) defined between those two modules on whom should both depend. That way high level modules don’t work directly with the low level classes. Low level classes implement the interfaces. In case you’d like to take some module out and use it elsewhere, you don’t need to touch anything inside that module. You simply take it out and implement the interfaces upon which the module depends. Isn’t that awesome?

The second part (part B.) makes clear that the abstractions (or interfaces) should not be designed according to the low level modules (the details). That’s something that might come naturally to a lazy coder “yeah, I’ll just duplicate the header file, make all methods pure virtual and I’m good to go”, no. The interfaces have to be implemented on the same level of abstraction as the high level module otherwise they’re more than useless.

Example of Dependency Inversion

That would be the principle in theory. Let’s see some examples from user interfaces. We’ll have a Window class with two buttons.

class Button
{
    public:
        void makeVisible();
};

class Window
{
    Button* okButton;
    Button* cancelButton;

    Window()
    {
        okButton = new Button;
        okButton->makeVisible();

        cancelButton = new Button;
        cancelButton->makeVisible();
    }

};

The problem here is, that if the Button implementation changes, we’ll have to go here and change the constructor as well. We don’t want that, because the Window class were a subject of a lot of tests, it passed and any additional messing around in it might introduce errors into the class. Using the abstraction layer the situation would look like this

class IButton
{
    public:
        static virtual IButton* getInstance() = 0; // factory method
        virtual void show() = 0;
};

class Window
{
    IButton* okButton;
    IButton* cancelButton;

    public:
        Window()
        {
            okButton = IButton::getInstance();
            okButton->show();

            cancelButton = IButton::getInstance();
            cancelButton->show();
        }
};

class Button : public IButton
{
    public:
        void show();
};

Now, as you can see, there’s an interface IButton and both Button and Window depend on this interface. And that’s the dream. You can take the window and the interface place into an another application, implement the interface and you’re good to go! Note the factory method I used to be able to get the correct instance of buttons.

Sources

Design Patterns: Renderer

This post about design patterns will be a little unusual. To this day, I was going through a generally recognized set of design patterns that was introduced by the Gang of Four in Design Patterns: Elements of Reusable Object-Oriented Software. But today I want to introduce to you a useful design bit I came up with, while I was working on my bachelor’s thesis. I call it Renderer.

The problem I had was simple — unbelievable mess in my application’s source code. I was working on a procedural approach to rendering cities. And believe me, a city is kind of big-ass model to draw. There’s awful lot of rendering of different things on different places. And when it comes together it’s a giant blob of instructions. So I needed some way of structuring this rendering code and making it readable and if-I-got-lucky also extensible (don’t judge me, the due date was really haunting me in my sleep at the time). Finally I came up with a tree-like data structure.

What is a Renderer?

Glad you asked! It’s a class that renders stuff. The concept is reeeeeally simple, but it’s very powerful when you need to structure your code properly. The definition of the class is as simple like this

class Renderer
{
    public:
        virtual void render();
};

It’s actually more like interface. Every Renderer must implement this interface. The render() routine renders the content of the current renderer. The beauty of this concept is in the fact, that you can organize your renderers into a tree. The top-level renderer will render the object by delegating rendering of different parts to other renderers. This makes your code nicely structured as well as modular and reusable. Take for instance rendering of a car.

Cars can be visually relatively complex objects and it wouldn’t be nice to have all the rendering code in one class. If you wanted to draw a different car you’d have to write everything again even though that wheels are virtually the same in both models. But with using the renderer pattern, things would look like this

class CarRenderer : public Renderer
{
    CarBodyRenderer *body;
    WheelRenderer *wheels[4];
    WindowRenderer windshield;

    public:
        void render()
        {
            body->render();
            windshield->render();

            for (int i = 0; i < 4; i++)             {                 wheels[i]->render();
            }
        }
};

class CarBodyRenderer : public Renderer
{
    SpoilerRenderer* spoiler;
    HoodRenderer* hood;
    SkeletonRenderer* skeleton;
    DoorRenderer* doors[5];
    public:
         void render();
};

I guess you get the idea. You decompose the object into a set of smaller entities and render them instead. This decomposition can go on virtually forever, in extreme cases you could be able to render a car from pixels using this design pattern and still be able to look at your code and understand it. Anyway, let me know if you find this pattern useful!

Sources

Liskov Substitution Principle

Another principle of object-oriented software design, the L in SOLID, the Liskov Substitution Principle! But first a little background and some theory (feel free to skip right to the practical part of the post). The principle is called after Barbara Liskov, who initially introduced it in 1987. Prof. Liskov first defined it like this

What is wanted here is something like the following substitution property: If
for each object O1 of type S there is an object O2 of type T such that for all
programs P defined in terms of T, the behavior of P is unchanged when O1 is
substituted for O2 then S is a subtype of T.

This definition is a little other way around. It says (at least I read it like this), “if you can substitute each O1 with some O2, it’s safe to say, that S is a subtype of T”. But there are cases (not that rare) in which S is subtype of T, but the objects aren’t substitutable (and that’s bad). It was later rephrased and published in a paper by Barbara Liskov and Jeannette Wing in 1994. The formulation changed to

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.

This is a little better. Now it says that if something works for objects of type T, it should work for objects of type S as well in case that S is a subtype of T. And that’s the Liskov Substitution Principle. Robert C. Martin later described it in one of his articles like this

Functions that use pointers or references to base
Classes must be able to use objects of derived classes
Without knowing it.

Now, that’s how most of us like our software principles, right? No weird letters or signs — straight-forward and easy to understand. I like the theory though :-). Anyway, how is this good in practice in the regular everyday coding? Let’s have a look at some examples. One of the most typical violation is Square-Rectangle class hierarchy.

One would think that having a Square class that is a subclass of Rectangle could be a good idea, right? The relationship represented Square is a Rectangle seems to work, so let’s do it.

class Rectangle
{
    int width;
    int height;

    public:
        int getWidth() { return width; }
        int getHeight() { return height; }

        virtual void setWidth(int value) { width = value; }
        virtual void setHeight(int value) { height = value; }
};

Pretty straight-forward declaration. The square is a rectangle which width and height are equal. So we redefine the set methods.

class Square : public Rectangle
{
    public:
        void setWidth(int value)
        { width = value; height = value; }
        void setHeight(int value)
        { width = value; height = value; }
};

This modification will make sure, that our square has always all sides equal. Then consider having a function like this

bool test(Rectangle &rectangle)
{
    rectangle.setWidth(2);
    rectangle.setHeight(3);

    return rectangle.getWidth() * rectangle.getHeight() == 6;
}

This function tests the interface of Rectangle. But what happens when you pass a reference to a Square to it? It will break, because of the side effect of the set methods, that keeps the Squarea square. So, where’s the problem here?

The square is a rectangle, but does not share the same behaviour. And that’s a deal-breaker when it comes to inheritance in software. The LSP clarifies that in OOD the is a relationship applies to public behavior of objects.

Bertrand Meyer also explored the topic in Design by Contract. He states

…when redefining a routine [in a derivative], you may only replace its
precondition by a weaker one, and its postcondition by a stronger one.

Preconditions are something that must be true in order to the method to execute and postconditions are always true after the method has been executed. This rule really helps me when I design something. Basically it says, that you can only reduce the set of preconditions and only extend the set of postconditions. In other words, the new routine cannot require anything more than the original one (but can require even less) and cannot yield anything less then the original one (but can also return something on top of that).

In context with the square-rectangle problem, there were no preconditions, but there was one postcondition to the setHeight() method. The postcondition assumed, that the set method for height won’t change the width (that’s a perfectly justified assumption). And this precondition was broken by the redefined routine of Square.

Inheritance is very powerful and important concept in object-oriented design. But it’s also easy to get it dead wrong. The Liskov Substitution Principle should make you thing more about the relationship, when you create one and help avoid eventual oh-moment coming your way.

Sources

Single Responsibility Principle

Single responsibility principle, or SRP is another of the SOLID guidelines for software designers. It’s especially useful in object-oriented design. The name suggests, that it will have something to do with decomposing the problem up to the point, where each entity in the system has one and only one responsibility. The principle alone states,

“There should never be more than one reason for class to change.”

Right, but where, the heck, is the responsibility we’re talking about? You see, a responsibility can be pretty hard to define and using the word directly would have definitely started a couple of fights. So the author defined it precisely as a ‘reason to change’. Let’s have a look at some example.

Here is a definition of my old MySQL class. It has interface for establishing and closing connection to a remote MySQL server and sending a query and receiving and processing the query result.

class MySQL
{
    public:
        bool connect();
        void disconnect();

        bool executeQuery(std::string queryString);
        MySQLResult* getQueryResult();
};

This class  has two reasons to change (i.e. responsibilities). It handles the initialization and closing of a connection to database server and also communication with the server (executing SQL queries). The two reasons to change are:

  • MySQL server will now accept only encrypted connections
  • The server implementation changes and it will respond differently to some queries

This violates the single responsibility principle. It would be a bad design to put together two things that change for different reasons. It might not seem that bad now, but the system will evolve and change. What now seem reasonable solution might kill you later on. The way I would now design things is this:

class MySQLConnection
{
    public:
        bool open(); /* former connect() */
        void close(); /* former disconnect() */
};

class MySQLQuery
{
    MySQLConnection* session;

    public:
        bool execute(std::string queryString);
        MySQLResult* getResult();
};

While SRP is fairly simple principle, it’s pretty hard to get it right. Putting responsibilities together is something that comes naturally to us and the separation (e.g. splitting the class into several smaller ones) might not seem as elegant at first. When I look back at some of my earlier designs, well, to be honest, I rarely stumble upon a class that conforms to this principle. When I look again, I can really see, how would the separation help reduce the complexity of the design and made my code easier to read and understand.

Following this principle religiously is definitely not a good idea, but it’s good to know it’s there and sometimes (especially, when you see a 500 lines in my_class.h) think, ‘Hey, would splitting my class to a couple more help?’. Usually it does :-P.

Sources

The ‘Oh’ Moment

There’s a little thing in software development I like to call the ‘Oh moment‘. I first noticed it when I was working on my bachelor’s thesis (and I was getting those all the time). Let me explain the situation a bit. You’re working on a project, not particularly easy one and finally after a couple of sleepless nights and rather unspecified amount of coffee, you come up with a solution. It seems just perfect. Clean, elegant, looks cool due to all the fancy inheritance, Mum will be proud.

Then first thing tomorrow morning, you start to eagerly write the code. It’s all good until it comes, ‘Oh, man’. One more thing (there always is) that you didn’t take into account and it just won’t work this way. It might work eventually, after some further modifications, but the result won’t be nearly as elegant nor clean. Not even mentioning the sweet inheritance tree. And there goes your excitement. After experiencing an oh-moment, your goal is no longer to create a good piece of software, but to get it done as fast as you can and then run away from it as far as possible.

The excitement from your ideas, good feeling about your work and satisfaction with the results is, in my opinion a key component in software development. Everybody likes doing a good job. And it’s really bad (for you and the project), if you don’t find the results good enough. But how to enjoy the job from the beginning to end?

You need to eliminate the Oh-moments. The more experience you get, the less Oh-moments you experience. But you cannot take them out of the equation entirely. Sh*t happens, and when it does, you need to be ready to minimize the consequences. However, there are couple of methods, that I personally find very helpful in this matter.

Wait

Never and I mean NEVER implement your design right away. It’s good to do something else for a while (my personal favorite is re-factoring and documenting the existing code) and then get back to it. If you still can’t see anything wrong with it, your chances of encountering an Oh-moment in the future are decreasing.

Show It to Others

A great way of avoiding oh moments is explaining your design to a team-mate or a friend. You will see it from whole another perspective and this will help you discover any unwanted surprises wrapped in the design.

Design in Iterations

Generally the later you get the flaw the bigger issue it is, so if you’ve stumbled upon an Oh-moment after a year of development, well, may the force be strong with you. But If you sit back once in a while and think a little further into the future of your application, you might find the dead end fast enough, before you get surrounded in it by a group of guys with knives and baseball bats craving for your wallet.

SOLID Object-Oriented Design

What is a solid object-oriented design? Like, strong, steady, you know or not a liquid or something? Well, who knows? Unless it’s written in CAPITALS! In that case it’s a acronym introduced by Robert C. Martin in the early 2000s which stands for five basic principles of object-oriented programming and design. What are these principles?

The principles (or guidelines), when applied together intend to make it more likely, that a programmer will create a system, that is easy to maintain and extend over time. These guidelines are here simply to make our lives a little easier. They’re certainly not to be followed religiously (including laying a fierce wrath upon anyone who dares to break them). If you find out, that your design abides them, good for you! If it doesn’t and you know the reason why, it’s no problem either :-).

I find them very helpful, especially when it comes to evaluating my work and that’s why I decided to take a break from design patterns for a while and go through the SOLID set of principles first.

Sources