GoF – Abstract Factory Pattern

What a wild summer it has been. With everything going on in the world, it’s important to take a moment to reflect on what’s going well, right now. With non-essential travel on pause, I haven’t needed to travel for work. Which means I’ve had more time to enjoy the summer with family, and more time to code and dream up blog posts. I think COVID has also had some positive impacts on society, I’ve definitely noticed a focus on hygiene in public these days, and that is wonderful.

In my reflection, I was recalling earlier this year when I read the famous Gang of Four book “Design Patterns : Elements of Reusable Object Oriented Software” – Gamma, Johnson, Vlissides, Helm. If you’ve not heard of this book, it’s basically considered the bible when it comes to Design Patterns in Software. This was the first time I had read the book. Yes — I developed software professionally for this long, and had never read this book. It was about time. I could basically feel the snickers and sneers as I walked the isles of my local grocery store. “You’ve not read Design Patterns by GoF?” “What kind of software developer are you?” Now, in reality this was just my chronic case of impostor syndrome creeping up my spine. Even though I had read countless articles on design patterns, and dove Head First into a myriad of them when I read “Head First Design Patterns“. It still didn’t measure up, I hadn’t read the real thing. So in January, I did it. I bought the e-book, and I read it. I wouldn’t say it was a cover to cover read. Like I said, it wasn’t my first pattern rodeo. A lot of the patterns, I had learned about, seen, or even implemented before. So it was more of a refresher than anything else. The book is well written, though a bit dated. What I found nice was that the examples were in C++. Anyways, this isn’t a review on the book. It was just something that came and went, back in January. Then during the COVID pandemic, I’ve been scratching my head for blog post ideas. I wish I possessed the type_traits that some of these other bloggers possess to seemingly pull insightful ideas out of their brains, and write delicate and succinct posts packed with code and useful information. I felt that I should go back to basics, and do a post or two on the cult classic GoF Design Pattern book, update it with modern C++, and put my own Peter spin on the patterns.

“You’re losing our attention; we don’t want to hear about your life. Get on with the post.” — Reddit

Call it what you want to call it. Kismet, fate, alphabetical sorting, the first design pattern in the book. I landed on the Abstract Factory pattern. If you’re unfamiliar with the pattern the definition is to “provide an interface for creating families of related objects without specifying their concrete classes”. What this means, is that the Abstract Factory, is an interface to an object that will create a bunch of objects, and hand them off as interfaces. I’ve taken the liberty to copy the UML from the book.

As you can see from the UML, the Abstract Factory is used by clients to put an opaque layer, or interface between the actual implementation, and the caller. As we all know, this is done through a programming paradigm called polymorphism. The factory is abstract to our client, as well as the objects that it is creating. So, the abstract factory, creates a family of abstract objects that the client can work with. The canonical example of this would be a windowing system, whereby you can have different display systems, that all expose the same family of objects. Consider Linux and Windows windowing systems, they all have windows, button controls, scrollbars, etc. So when working with a windowing system, it could make sense to apply the Abstract Factory Pattern.

I’ll use the original GoF example as my starting point. Though, I’m going to apply modern C++ to it, so it won’t be line for line the same as the example in the book. As well, I won’t detail the map components Maze, Wall, Room, Door, as I don’t feel their necessary to illustrate the point.

class AbstractMazeFactory
{
public
    virtual ~MazeFactory() = default;
    virtual std::unique_ptr<Maze> MakeMaze() =0;
    virtual std::unique_ptr<Wall> MakeWall() =0;
    virtual std::unique_ptr<Room> MakeRoom(int room) =0;
    virtual std::unique_ptr<Door> MakeDoor(Room &r1, Room &r2) = 0;
};

std::unique_ptr<Maze> CreateMaze(AbstractMazeFactory &factory)
{
    auto maze = factory.MakeMaze();
    auto room1 = factory.MakeRoom(1);
    auto room2 = factory.MakeRoom(2);
    auto door = factory.MakeDoor(*room1, *room2);

    room1->SetSide(North, factory->MakeWall());
    room1->SetSide(East, door);
    room1->SetSide(South, factory->MakeWall());
    room1->SetSide(West, factory->MakeWall());

    maze->AddRoom(room1);

    room2->SetSide(North, factory->MakeWall());
    room2->SetSide(East, factory->MakeWall());
    room2->SetSide(South, factory->MakeWall());
    room2->SetSide(West, door);

    maze->AddRoom(room2);

    return maze;
}

We’ve separated the logic of creating the maze from the construction of the maze components, as well as their actual implementation. To take advantage, you just need to implement concrete components, and derive from the AbstractFactory which will return these components.

class EnchantedMaze : public Maze { ... };
class EnchantedWall : public Wall { ... };
class EnchantedDoor : public Door { ... };
class EnchantedRoom : public Room { ... };

class MazeFactory : public AbstractMazeFactory { ... };

class EnchantedMazeFactory : public MazeFactory
{
public:

    virtual std::unique_ptr<Room> MakeRoom(int room) override
    {
         return std::make_unique<EnchantedRoom>(room, CastSpell());
    }
    
   virtual std::unique_ptr<Door> MakeDoor(Room &r1, Room &r2) override
   {
         return std::make_unique<DoorNeedingSpell>(r1, r2);
   }

private:
    Spell* CastSpell();
};

This decoupling enables you to change the implementation of your components, without having to disrupt the creation algorithm. If you’re worried about compiling, when you modify your components it’s not necessary to recompile CreateMaze.

The book outlines the following benefits and liabilities

  1. It isolates concrete classes. The pattern funnels creation through a single interface. Which ensures a single point in which your application must create objects. Because the application must interact with both the factory, and its components via their interfaces details of their implementation remain opaque to the outside algorithms.
  2. It makes exchanging product families easy. Because a client interacts through a single interface, it makes changing this interface as easy as an assignment to a new factory. However, each factory must supply entire product family as a whole.
  3. It promotes consistency among products. Because the factory dictates creation of a group of related items, which will likely be codependent. Since it forces a single source for creation, it makes enforcing this easy.
  4. Supporting new products is difficult. Although changing the factory is easy, creating a new product family is often not. It means defining and implementing a new factory, as well as the entire product set.

You can start to smell when this pattern is helpful, if you’re starting to invent creative ways to change implementation of sets of components within your system. Or, if you’re starting to mix the structure of your application, with component implementation details.

The problem with this GoF patterns is that it results in a lot of boilerplate code. If we look at the AFP (Abstract Factory Pattern), you have to create the factory interface. Then for each family of products you have to implement the concrete classes. This type of repetition tends to get worked around in clever fashions, which can often become unmaintainable nightmares.

My intention with this post (series of posts?) was to make a library that makes using the GoF patterns accessible, and reduces the amount of boilerplate needed. As well as modernizing the solutions, and being creative where I could. It’s hard to top something that’s lasted the test of time like this. I also wanted to make the library easy to use, hard to use wrong, and to illustrate the use of the intended pattern.

When we boil down the Abstract Factory, we have two major components. We have the factory itself, and the family of components. The factory is a set of methods that create, and return each component objects. Which means that for N components in a family, you’ll have N factory functions in the factory. This was my first thought was to remove that boilerplate cost. But how? Well, if we ask ourselves the question of what each factory function is, it’s specifying the type to create at compile time. In C++ we have a neat tool for generalizing functions based on type at compile time. It’s called template programming. So we can start there, let’s look at a simple widget factory example. How would we want to use it.

void create_screen(abstract_widget_factory &factory)
{
    auto w = factory.create<window>(); 
    auto b = factory.create<Button>();
    
    b->set_text("Hello World");
    w->add_widget(b);

   w->show();
};

My initial thought was to do something with template specialization, but the wall that I kept running into is that the Abstract Factory pattern makes heavy use of runtime polymorphism. The template system is compile-time. What does this mean? In the example CreateScreen above, the actual concrete type of the factory, doesn’t need to be known past that it is an AbstractWidgetFactory, and through the miracle of virtual function dispatching, it will land in the appropriate function for the concrete class when the call is dispatched. Template functions are similar, in that they allow you to apply a function to an interface (read concept), but the actual type must be specified at compile time. The reason for this, to vastly simplify it, implements the template function for the given type, instead of you having to write it yourself. Because of this, when you’re trying to replace boilerplate, using the template system typically comes in handy. In order to implement the function above, you would need to define the AbstractWidgetFactory along the lines of

class abstract_widget_factory
{
public:
   virtual ~abstract_widget_factory() = default;

   template <typename T>
   virtual std::unique_ptr<T> create() = 0;
};

This isn’t valid C++, and it makes sense as to why. Because in order to have the pure virtual function (=0), the inherited class must implement the function. But the function is a template, it can be any number of different instantiations of the function. Therefore, what does the concrete class actually implement? Thus, this is no-bueno.

Given that we know the set of objects we’re creating, I thought I may be able to solve this with a concept. However, I came to the conclusion that this would just push the boilerplate code I was trying to avoid with the runtime interface, I would have to write with the concept. I’ll admit my level of comfortably with concepts is quite low, and I only conceptualized the idea. I didn’t actually try and implement it. If you have an idea of how to tackle this with concepts, I am all ears!

So where does this leave us? How can we combine runtime decisions, with compile-time decisions? What does that even mean, or look like? First, what are the runtime decisions we’re trying to make, and what are the compile time decisions? The compile time decision, is the choice of the abstract component we want to use, in this case Button, or Window. In the GoF example, Maze, Wall, Room, etc… The runtime choice is the actual factory class, which by nature of the pattern, should dictate the implementations of the components.

In my research, I found a Dr. Dobb’s (RIP) article from 2001, by Herb Sutter and Jim Hyslop. the article is written in story form, which makes it a pretty fun read. The best part, the story was actually exactly the problem I was trying to solve. I was still trying to solve the problem on my own, so I avoided reading the article in-depth until after I had a working model. Though, I did use it to gut check that my idea that a registry for creation was a track I wanted to go on. So I landed on this.

class abstract_factory
{
public:
     template <typename BaseT>
     std::unique_ptr<BaseT> create()
     {
          // semi-pseudo code
          auto creator = creators_[BaseT::type_id()];
          // something like creator->create<...>();
          // return it.
     }

protected:
    template <typename BaseT, typename DerivedT>
    void map()
    {
        // creators_[BaseT::type_id()] = I need something here;
    }

private:
    std::map<const char*, creator?> creators_;

};

Then, a client could use the factory something like this.

class linux_widget_factory : public abstract_factory
{
public:
     linux_widget_factory()
     {
          map<button, linux_button>();
          map<window, linux_window>();
     }
};

void create_screen(abstract_factory &factory)
{
    auto w = factory.create<window>(); 
    auto b = factory.create<button>();
    
    b->set_text("Hello World");
    w->add_widget(b);

   w->show();
}

int main()
{
    linux_widget_factory f;
    create_screen(f);
}

Future Peter here: One of the problems that the Dr.Dobb’s article suffered from, was that the singleton factory was on a per-hierarchy basis. In that, you could only create one base type, with multiple derived types. As well, being a singleton doesn’t allow for different factories for different families of components.

This implementation looks pretty good, and it works like the GoF Abstract Factory. You’re able to hide the implementation of a family of objects, behind one class which forces the client to go through its interface. It’s just how do we make this work? What we’re really trying to do, is to package up the creation into a function that can be called. When we package it up, we want to hide away any type specific information because this will allow for type generalization, and then when we call the creation we want to as if by a miracle re-hydrate the type for the object we’re creating. There’s a technique for what we’re trying to do. You might know what I’m talking about from some of my previous articles, or you’re just familiar with it. It’s called type erasure. Like the Sutter / Hyslop factory, we’ll make our factory creation function work on a base type. The most base type, void. Then through the miracle of templates, we’ll reassign the type when the client calls create.

If you’re unfamiliar with type erasure, I’ll give a quick overview, and leave a couple of references to articles I’ve read in the past at the bottom.

Basically, any kind of runtime polymorphism is a form of type erasure, you’re hiding away the concrete type to work with a more generic type. Typically when we refer to type erasure in C++, we mean hiding all the type information away. Since we want to work with all types, we’ll have to remove any type information.

Disclaimer: Don’t try what you’re about to see at work. Using type erasure in this way removes the type safety provided by the compiler.

// We want to hide the creation behind some interface.
class creator_base
{
public:
    virtual ~creator_base() = default;
    virtual void *create() = 0;
};

Now, we’ve turned creation of our objects upside down, and hid it behind a very generic interface. When we call create, we’ll get back a void pointer, that’s all a void pointer. Unbeknownst to the compiler it’s actually our concrete object, we’ve just effectively turned off type safety for this call.

The next part of type erasure is to embed the actual type behind the interface. In our case, it looks something like this.

template <typename T>
class creator : public creator_base
{
public:
   virtual void* create() override final
   {
        auto t = std::make_unique<T>();
        return t.release();
   }
};

Easy — so now creator<linux_button> will create a linux_button, and return the opaque void handle to it. Now all that’s left when we’re creating is to flip the object over to the base type we want.

class abstract_factory
{
public:
     template <typename BaseT>
     std::unique_ptr<BaseT> create()
     {
          // semi-pseudo code
          auto creator = creators_[BaseT::type_id()];
          void *obj = creator->create();
          return std::unique_ptr<BaseT>(obj);
     }

protected:
    template <typename BaseT, typename DerivedT>
    void map()
    {
        creators_[BaseT::type_id()] = std::make_unique<creator<DerivedT>>();
    }

private:
    std::map<const char*, std::unique_ptr<creator_base>> creators_;

};

The last piece of this puzzle is the BaseT::type_id(). What I did in my first iteration, was to just stamp this on to my base product classes like this. This is changed to a different pattern in the actual implementation.

class button
{
public:
   static constexpr const char* type_id() { return "button"; }
public:
   virtual ~button() = default;
   virtual void click() =0; 
   virtual void set_text(const std::string &text) =0;
};

My original goal was to reduce the boilerplate of the original GoF pattern. Which, I did. The major boilerplate that occurs is in the factory. Each product create call would be at minimum 4 lines. Which has been reduced to a single line registration function. I also think this has one up on the Dr. Dobb’s implementation in that we’re using the compiler a bit more heavily, and we don’t limit the product classes to a single hierarchy. You can find the eeyore library here.

All in all this was a fun exercise, and I look forward to doing it again. Until then stay healthy, and happy coding!

PL

I know quite certainly that I myself have no special talent; curiosity, obsession and dogged endurance, combined with self-criticism, have brought me to my ideas.
– Albert Einstein

YEG C++ Lightning Talks

Tuesday, Sep 15, 2020, 6:30 PM

Online event
,

2 Members Attending

Have you ever spent 15 minutes diving into the semantics of const correctness at a round table, only to have your Grandmother and Aunt look at you like you’re out of your mind? Maybe you dream of abstract syntax trees, while your eyes glaze over as your friends dive into their COVID wedding plans. If any of this sounds like you, read on! Express yo…

Check out this Meetup →

Join us virtually for our YEG C++ lightning talks!

References:

What is Type Erasure – Arthur O’Dwyer
Conversations: Abstract Factory, Template Style – Herb Sutter & Jim Hyslop
Understanding Abstract Factory Pattern – Harshita Sahai

Leak Free, by Design

C++ is a brilliant language, one that has had my heart for many years. Though with the rise in web applications, more developers are finding themselves working in full stack web applications. Which almost never utilize C++. This can be seen in the 2020 StackOverflow developer survey, where 69.7% of professional developers are utilizing JavaScript and 62.4% HTML / CSS, compared to C++ measly 20.5%. This saddens me, because even though I too dabble in those languages, I would hazard a guess that a large majority of those professional developers have never even seen C++, let alone worked with it. It’s the unfortunate side of demand side economics. Unfortunately, I suspect that the closest a vast majority of JavaScript developers have ever gotten to a memory leak is a post on /r/ProgrammerHumor. And the closest thing to a crash is a big red blob in the console. However, there’s good reason why it’s such an accessible language, and why people can throw together applications so rapidly. JavaScript is a scripting language, and it was thrown together in ’95 to be exactly that, and it is still roughly that. Even with 2.5 decades to evolve, it’s still a web scripting language. You don’t have to understand much past basic logic to put together an application, and with the wealth of libraries you don’t need much to really make something cool. Now, contrast this with a language like C++, where without a bit of grit and determination, it’s hard to get off the ground. Even once you do, you’re working with a black console fronted green text. Gone are the days where you could whip together a cool console app that asked your friends questions, and spit out some silly answers, or even let them play a game. If it’s not Fortnite, it’s not cool, and if it’s not on my phone I don’t want to see it. It’s no wonder why those StackOverflow numbers are the way they are. The sad thing is that many people don’t understand that languages like JavaScript are built on the shoulders of giants, and as flashy as JavaScript web apps are, you don’t build operating systems, real time mission critical systems, and real console or PC games, in languages like JavaScript. As much as they want it to, it just can’t happen. The problem is, that people are afraid of languages like C++. It’s scary to offer your 19 year old intern the keys to the Ferrari. If he doesn’t understand what he’s getting himself into, it’s relatively easy to drive that thing into a wall. It’s much easier to let him ride the JavaScript moped around the block. This is the problem that modern C++ developers need to address. In my opinion, with the recency of the modernization of C++, and the Microsoft open-source movement, I feel that there has been a resurgence in C++. But we need to fight for this, we need to educate, and we need to push the features of the language that make it safe, by design.

About eight weeks ago, I was contacted by a gentlemen by the name of Artem Razin. He was contacting me, because in the relatively small C++ community, he was looking to get word out about his product DeLeaker. He wanted me to write a review about the product. Truth be told. I’m not writing this blog to give product reviews, so I originally declined. I just want to work on my writing skills, and share some of my knowledge. However, I also want to be an active member of the community, and here someone was reaching out to test their product, and help them share it with the world. That being said, I downloaded and tested out the application. Needless to say, the application does what it says. It integrates into Visual Studio, and it detects leaks of all kinds, and it does this with little to no impact on your application. The problem is, I don’t have a real C++ application to try it on. Most of my hobby C++, is with libraries, and other fun toys, so I can’t say how it runs in the real world. But my curiosity struck me more than anything for how this thing worked. So, Artem and I went back and forth, as I questioned him about how the application did what it did, and how it got its start. I started putting together how I could craft a blog post about it. Since my blog is about understanding, education, and uncovering mysteries. What could I write? Ahhh ha. I had it, my post would be about lifting the covers on an application like DeLeaker. How would we go about detecting leaks in applications? When I started my research, it was pretty straightforward, I just had to figure out how to hook an application, and detect memory allocations. On Windows, it’s relatively straight-forward. Though, as I worked on it, I thought to myself about JavaScript, and other languages where this wasn’t necessary. I imagined a world, where we didn’t have to worry about this in C++. A world where leaks in C++, were a thing of the past. Then I realized that, that is the theme of this post. Creating leak free applications, by design.

What’s wrong with this code?

void foo()
{
     faucet *moen = new faucet();
     moen->run();
}

I’ll give you a hint, it’s a memory leak, a rather obvious one of course. The problem is that leaks don’t always look like this. They can hide in plain sight.

void foo()
{
    faucet *moen = new faucet();
    moen->run();
    delete moen;
}

No leak, right? Wrong. How can that be, we’ve got a paired delete for our new.? The problem is that since exceptions are the default mechanism for handling errors in C++, we have to be wary of them. This means that the run() method, could potentially throw an exception. If it does, and it’s caught somewhere higher up, we’ll never call the delete, and we’ll have the same outcome as the method above. A little leak.

If you’re a veteran, you already know this, and you know the answer for this. Use a smart pointer. For those of you who aren’t veterans, and you don’t know. A smart pointer is the encapsulation of a very powerful pattern in C++, called RAII. Resource Allocation Is Initialization. What this means, is that all allocated resources should be attained in initialization, and subsequently let go in destruction. In this case, heap-allocated in construction, and delete in destruction. This way, the code becomes memory safe, just by using the “smart pointer”. Smart pointers, are used to represent ownership, and ownership is a very powerful concept in C++.

#include <memory>
void foo()
{
    auto moen = std::make_unique<faucet>();
    moen->run();
}

You’ll notice that the code is much similar to our first try, except now it won’t leak. I’ve included the <memory> header, that’s where you’ll find these tools. You’ll also notice the removal of the * and type, for the keyword auto. Well, for our JavaScript and C# readers, that’s similar to the var keyword. The reason I’ve used it, is that the type is no longer a faucet, nor is it a pointer. When we use make_unique, we’re actually creating a wrapper object called a unique_ptr which is handling the allocation and deallocation of our faucet type, through the miracle of templates, and it acts just like a pointer to a faucet. The type of moen however, is now std::unique_ptr<faucet>.

Here we are at 1200 words, and the morale of the story is this use smart pointers, and you’ll never ever ever have a leak again in your life. Sorry Artem. 🙂 If only life was that simple. The problem with real code, and not contrived simplified blog code, is that it’s never that cut and dry. The reason why JavaScript is easier, is because you don’t have to think about design. You can just code a tangled rats-nest of JavaScript, and it can still be a functional working application. Needless to say you can shoehorn your C++ application into the category of “functional”, and “working”, with enough trial and error as well. Obviously the answer to Leak Free code, isn’t just “use smart pointers”.

faucet * make_faucet()
{
    faucet *moen = new faucet();
    moen->run();
    return moen;
}

In this example, we want to start our faucet, and pass it back to the caller. Unfortunately, unless the caller knows they need to call delete, we could have a leak. As well, we’ve also opened ourselves up for the potential of an exception causing the leak. Use smart pointers.

#include <memory>
std::unique_ptr<faucet> make_faucet()
{
    auto moen = std::make_unique<faucet>();
    moen->run();
}

Great. This works the same. Smart pointers are heating up!

#include <memory>
std::unique_ptr<faucet> make_faucet()
{
    auto moen = std::make_unique<faucet>();
    moen->run();
}

void turn_on_hot(std::unique_ptr<faucet> f)
{
    f->turn(dir::right, 0.75);
}

int main()
{
    auto f = make_faucet();
    turn_on_hot(f);
}

Oops! error C2280: 'std::unique_ptr<faucet,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function. If you’ve programmed with modern C++ for any length of time using smart pointers, you know what this is. This is definitely scary to a beginner. Have you ever programmed in JavaScript, and gotten a compilation error that told you, you were referencing a deleted function? Oh wait. Nevermind. Regardless, for a beginner this error is difficult to reason about. The simple answer, is that you can’t copy a unique_ptr, the author has deleted this function. For good reason, if you understand it, but if you’re coming from a world where you just pass everything to everything, and you don’t even know what this is. It’s scary af, as the kids say.

The problem is that smart pointers alone, are not the key to writing safe, leak free applications. Just because I have a garage full of tools, doesn’t make me a mechanic. So where does this leave us? One of the most powerful features of C++, that many other languages don’t have, is well defined object lifetime. In C++, we can know exactly when objects come to life, and exactly when they’re destroyed. In my opinion, this is one of the most powerful language features, especially when you’re trying to write safe, leak-free code. In order to do this it means we must both understand and design with this in mind.

What is Object Lifetime when it comes to C++? According to cppreference.com lifetime definition, “A runtime property: for any object or references, there is a point of execution of a program when it’s lifetime begins, and there is a moment when it ends.” For an object, it’s life begins when the storage for it is obtained, and any initialization has been completed. The objects life ends, when the destructor call starts, or the storage has been released. Now, as an exercise to the reader to understand the other caveats, and lifetime of references. Understanding this, we can start to plan our programs so that the lifetime of our objects is a well-known principle of our application. This becomes important, because it will impact the type of smart pointers you use, and how you go about passing those pointers around. The choices you make for lifetime, will also impact how you model ownership in your application, but we’ll get to that.

Let’s start with our lifetime model. How long does an object live in our application? The simplest approach is often the best. The simplest approach here, is to break an object lifetime up into either short-lived or long-lived. In “Writing High Performance .NET Code”, author Ben Watson suggests to beat the garbage collector, you should make the objects either really long lived i.e. the lifetime of the application, or really short lived i.e. function scope. This evades the most costly part of garbage collection where the object is relocated. I feel that the same mentality holds true in C++, not for the cost of the garbage collection, but for the mental cost it incurs to reason about whether an object should still be there or not. If we know an object has a long lived lifetime, then we know it should be safe to pass this object around by reference without worry of it dangling. However, if we know it’s a short-lived object, then we have to think twice before we pass references to it. This model also applies relatively to objects that contain children. So long as a parent object is the sole owner of the child, then it is safe to assume the parent will outlive the child. It makes code like this, valid.

class parent;
class child
{
public:
    child(parent &p) : parent_(p), life_(10) {}
    void feed();
private:
    int life_;
    parent &parent_;
};

class parent
{
public:
    parent(int life) : life_(life) {}
    void give_birth()
    {
          children_.emplace_back(*this);
    }
    void feed_children()
    {
         for(auto &child : children_)
             child.feed();
    }
    void subtract_life(int val)
    {
        life_-=val;
    }
private:
    int life_;
    std::vector<child> children_;
};

void child::feed() 
{
   life_ += 10;
   parent_.subtract_life(10);
}

int main()
{
    parent p(100);
    p.give_birth();
    p.feed_children();
}

In this example, we know that the parent owns all the little vampiric children, so they can be sure that it’s safe to suck the life from their parent.

It’s important to remember the distinction between stack and heap allocated objects. A stack allocated object one like p above, will live the lifetime from the line after it’s defined on, to the closing brace it resides within. A heap allocated object will live from the line after new, to the line which delete is called. You can have long and short lived stack objects, and long and short lived heap objects. Though typically, you’ll want short lived objects to live on the stack, and sometimes you’ll want long lived objects to live on the heap. However, it can also make sense to have long lived objects that are on the stack, allocated at the beginning of your program and live until it completes.

If we understand object lifetime and ownership model, it can start to paint a picture in our mind about how we can use RAII and object passing semantics to ensure that our applications are leak free. In fact, we can design our applications in a way that we know there isn’t a leak. We can do this with 3 basic steps.

  1. Subscribe to RAII, ensure any sandwich code is properly encapsulated in an RAII wrapper, which acquires the resource in the constructor, and releases the resource in the destructor. Use smart pointers for heap allocation of objects.
  2. Define a well known ownership and lifetime model. Define long and short lived objects, and have the longer lived objects own the shorter lived objects, where possible.
  3. Based on ownership and lifetime, choose the appropriate argument passing semantics.

The first two are relatively straightforward, we want to prefer stack allocation where possible, but use smart pointers when we need to allocate, and use an RAII wrapper when we need to acquire / release a resource. Then we want a well-defined ownership and lifetime model. Meaning that we know which objects are long-lived, and which are short, and who owns what. Then, we let these two models dictate how we handle object interaction within our program.

void do_something(std::string s);
void do_something_else(const std::string &s);
void do_something_to(std::string &s);
void do_something_again(std::string *s);
void do_something_pass_ownership(std::string &&s);

If you’re coming from a language like C#, or JavaScript these function declarations might look strange. Let’s be honest, to a rookie C++ developer the difference is subtle, and more often than not, the first pick is the default. Just because in other languages you don’t have to decorate your type when you’re passing a variable. In C++ though, those signatures all behave differently, and all have different meanings, and when you’re authoring an application they serve as self-documentation to allow clients of your class, to understand the functions affect on the ownership and lifetime model of your application.

void do_something(std::string s);

The first signature, says to the caller “you’ll have to pass me a copy of a valid object”, this implicitly means that the object is a) valid, and b) the callee can muck with it because it’s copy, and it has no effect on the original. Unfortunately, this is the go-to object passing method for beginner C++ developers, because it looks just like every other programming language’s method to pass arguments. What’s often misunderstood, is the cost associated with this operation. For small, plain-old-data type objects, it’s often faster to pass a copy rather than a reference, so it makes sense. But when we’re talking about full objects, larger than a couple of bytes, things start to change. With something like a string or vector, you’re paying to copy all the objects contained within. This means a heap allocation, and a copy. So you want to save passing by value for small objects, and when it’s intentional. Such as the case where you want to guarantee you’re receiving an object, you want to muck with it, but you don’t want to mess up the original.

void do_something_else(const std::string &s);

Next up, pass by const-ref. This should be the default argument passing semantic you reach for. This tells your caller “you have to pass me a valid object, and I won’t modify it”. If you start here as the base, you can start to change the signature based on your functions needs. If your need is that you just want to read the object being passed in, then this is great. The only ask from the callee, is that the reference is to a valid object. This is where defining your ownership & lifetime model will allow you to ensure what you’re passing will in-fact be referencing a valid object.

void do_something_to(std::string &s);

You want a valid object, and you want to mutate it. This is the signature for you. That’s exactly what you’re telling the caller, “pass me a valid object, and I’m going to mutate it”. Just like with const-ref, passing by reference says you want a guarantee of an object, but removing the const lets you muck with the object they’ve passed in. Historically, this has been used for out-params, where you basically fill the object being passed in. However, this is modern C++, if you need to get an object out, just return it.

void do_something_again(std::string *s);

Now, the nice thing about passing by reference is that you’ve got a guarantee you’re getting an object, where in some other languages you don’t have a method to guarantee that. So you’ve got to do null checks for defensive programming. Well, in C++ we can explicitly ask for that type of parameter passing. Pass by pointer (or const pointer). This tells your caller something a little different than the “by reference” options of above. This tells them “pass me a pointer to an object, or nothing (nullptr)”. The difference between pass by reference, and pass by pointer, is the ability to pass nullptr to the function. This comes in extremely handy when you want to indicate the beginning or end, or a special case with the nullptr. However, this comes with the expectation that we are able to handle both cases. So always always always do a nullptr check when passing by pointer. Though, it should be an indicator to change your argument passing semantic if you’re not handling this case in the first place.

void do_something_pass_ownership(std::string &&s);

This && is a bit weird, and to other languages that are reference counted such as C# and JavaScript, it really doesn’t have a parallel. But this is the r-value passing semantic, and it’s used to denote the passing of ownership. Arguments should be passed from the caller using std::move, this makes the transfer of ownership explicit, allowing you to maintain your ownership model.

Now, armed with RAII, a solid ownership and lifetime model, and proper passing semantics you can start to craft code that is Leak Free, by Design.

#include <memory>
#include <vector>

int make_handle();
void free_handle(int);

class widget_manager;

struct window_event {};

class widget
{

public:
    virtual ~widget()=default;
    virtual void dispatch(const window_event &e) = 0;

};

class widget_manager
{
public:
    widget_manager()=default;
    widget_manager(widget_manager &)=delete;

    void dispatch(const window_event &e)
    {
        for(auto &wptr : widgets_)
        {
            wptr->dispatch(e);
        }
    }
    void add_widget(std::unique_ptr<widget> ptr)
    {
        widgets_.emplace_back(std::move(ptr));
    }

private:
    std::vector<std::unique_ptr<widget>> widgets_;
};

class main_widget : public widget
{


public:

    main_widget(widget_manager &manager)
    :manager_(manager), handle_(make_handle())
    {
        
    }    
    ~main_widget() { free_handle(handle_); }

    virtual void dispatch(const window_event &e)
    {
        // do something main here

    }

private:
    widget_manager &manager_;
    int handle_; 
};


class widget_factory
{

public:
   std::unique_ptr<widget> make_main_widget(widget_manager &m)
   {
       return std::make_unique<main_widget>(m);
   }

};

class application
{

public:
    application(widget_manager &manager, widget_factory &factory)
    :manager_(manager), factory_(factory)
    {
            auto widget = factory_.make_main_widget(manager_);
            manager_.add_widget(std::move(widget));

    }  

    window_event get_window_event() 
    {
        // get a window event, if end return nullptr
        return window_event{};
    }
    void run()
    {
        while(1)
        {
            auto event = get_window_event();
            manager_.dispatch(event);   
        }
    }

private:
    widget_manager &manager_;
    widget_factory &factory_;

};

int main()
{
    widget_manager manager;
    widget_factory factory;
    application the_app(manager, factory);
}

The problem with contrived examples for complex problems, is that they never quite illustrate the point you’re trying to make. For me, at least. The point this code illustrates, is that you can come up with a model for long, and short lived objects. You can have long lived objects own shorter lived objects. Knowing this set of information can dictate how you want to pass these objects around. You want to use the appropriate smart pointers, i.e. unique_ptr for unique ownership, and shared_ptr for shared ownership, and always use RAII wrapper classes when you have sandwich code, in this example make_handle() and free_handle(int). If you make these rules front of mind when you’re programming in C++, you’ll be able to sleep a little easier knowing you’re not going to leak resources.

Now, if your application isn’t modern, or you’re dealing with legacy code. Well, then you should look to a tool like DeLeaker to help you find those leaks. Once you spot them, you can hopefully refactor your code pulling from some of the above guidelines to guide you into the Leak Free direction.

You can find DeLeaker here. It’s important to note that I’m not endorsing this product, nor was there any financial incentive, only a copy of DeLeaker itself. I just want to help out others in the community.

The other interesting topic that had come to mind when I was writing this post, would be how something like a leak detection software would work. If you’re interested in this, let me know. If you enjoyed reading this, and would like to read more, make sure you subscribe and share!

Until then, stay healthy and Happy Coding!

PL

“Design and programming are human activities; forget that and all is lost.”
― Bjarne Stroustrup

Please rate this post to let me know what I should write more of.

References:
Guideline Standards Library
GSL Passing Parameters
Leak Freedom…. By Default – Herb Sutter
Resource Model – Bjarne Stroustrup, et al.

A Single Responsibility

Over the years I quite often find myself pondering software development patterns and practices. It’s the kind of thing I think about in my downtime, when I’m driving to and from work, or sitting at home… pondering. I always seem to come back to one question, is the common interpretation of the pattern, that is how the majority of the world sees and implements it, what the author had intended? Is that inventor okay with it? It’s not like I’m going to solve this mystery today. One day I might have the opportunity to meet one of these greats and ask them. Is the outcome of their idea what they intended? I often times find myself reading coding, or working on past code where the implementation, doesn’t line up with my current interpretation of the pattern / practice. Though, upon talking about the code, or reading comments, or blind guessing. It can be clear that the intent was to implement towards a given pattern. In my last post, I talked about Separation of Concerns, which in my opinion can be closely related to, and often confused with the “Single Responsibility Principle“.

The intent of my last post, on Separation of Concerns, was to show that it in itself is not a pattern. It’s merely a practice that can be applied to thought, at any level. This can apply to your application at a macro level (application architecture), all the way down to the micro level (lines of code). Where I see things start to get fuzzy for people, is around the application into class level. The Single Responsibility Principle, is an embodiment of Separation of Concerns, but this embodiment is at a specific level. Unlike Separation of Concerns, Single Responsibility Principle applies only at the class level. I mean, that’s in the definition.

Classes should have a single responsibility and thus only a single reason to change.

But it’s like everything in software, open for interpretation. Patterns, Practices, and Principles fall victim to the subjective nature of application development. The real world of development rarely sees foo and bar, outside of whiteboard sessions. This means that you have to deal with real world objects, and real world problems. Then as developers we have to translate the canonical and sometimes naive FooBar examples, into our real world problems. Sometimes, more often than not, especially with less experienced developers, this leads to incorrect or harmful application of these principles.

Sometimes strict adherence to an interpretation of SRP and “Separation of Concerns”, can be deleterious to an application. The unfortunate nature of this, is that it’s a problem that doesn’t manifest until much later, when it’s too late. Now, I’m not trying to sit on my high-horse and say I don’t misapply these things. In fact, it would be foolish to think that anyone is perfect when it comes to this. I would be willing to bet that Martin Fowler himself doesn’t get it right 100% of the time. The difference is that with experience, you’re able to spot the blunder before it’s too late. Before you’ve gone to far, and you’re on the cliff being faced with a re-write. In the real world, this often times ends in a manager wishing he would’ve reviewed the code a little earlier, or a little more often. Hopefully, this post will help to clarify and add some litmus tests to the application of this principle.

First off, Separation of Concerns, isn’t SRP. If you think that, just forget it. Right now.

Separation of Concerns is the organization of thoughts, the ability to separate components, that are not overlapping, or mutually exclusive. Single Responsibility Principle, is an application of this practice, of grouping things that have the same concern, or reason for change into a single class. So it has a real world, level of application. It’s at the class level, that’s where you apply it…. And this is where the problem stems.

Say you have an application, you’ve got a Web Service that deals with incoming client web requests, and you’ve got an Auxiliary Service that is moving data to and from a database, and servicing long running system requests. This is an example of Separation of Concerns. This is not an example of Single Responsibility Principle. It’s too macro, we’re talking at our application level. Not at the class level. The problem that will stem from this form of thinking, is macro level class development. God classes. Sure — you have a class that represents your service that “Fulfills web service requests”. That’s his single responsibility… But is it? Is it really? If we imagine this mock class, he would have to

  1. Receive a message from the Web Server Service
  2. Parse said message
  3. Understand what to do
  4. Fulfill the request
  5. Build the response

Now, that’s definitely more than one responsibility! But from a macro level, it’s easy to see your class as having a single responsibility. You’re Separating your Concerns, remember?

In this case, it would probably make sense to have 1 class for building and parsing messages, 1 class that can switch on those messages to dispatch what to do, and 1 class for each of the actions to fulfill the requests. Woah. Woah. Woah. Wait just a minute. You just said 1 class for building and parsing… Isn’t that violating the SRP? Well, the answer as so many are in Software Development, is ‘it depends’. That statement, was intentional. It was meant to bring light to the fact, that the definition says “a single reason for change”. When you’re dealing with protocols, building and parsing can often be symmetrical. Therefor, if the protocol changes, that could be our single reason for change of this class. So it could be said to have a single responsibility of dealing with the protocol.

As you can see, where you focus the light of Single Responsibility will really play a factor into the organization and structure of your code. Just wait until you start shining that light too close.

When you start focusing the light at a micro level into your code. You’ll start to actually factor out responsibility.

Imagine you have a system, that is used to dispatch sms style messages, but it’s old school, so it takes time. You’ve got a client facing API called a MessageBroker, and a background service called a MessageDispatcher. Clients of your API deal directly with the MessageBroker, they give the MessageBroker in the format of

class Message 
{
public:
   enum RecipientTypes { Specified, Random }; 

public:
   const Address sender_;
   const Address recipient_;
   const RecipientTypes type_;
   const String &message_;
};

The intent, is that we give the MessageBroker the message, and he’ll do something with it for later pick-up by the MessageDispatcher. The MessageDispatcher will ensure delivery of the message to the recipient. Now, the API of the Message class is such that if you set the type, to Specified and set the address, the message will arrive at your intended target. However! If you set the type to Random, it should go to a random target. This randomness, isn’t really random, it could be based on a location heuristic.

You might think it’s best to define an interface for the message broker, and make it look something like this.

interface IMessageBroker 
{
    void Send(const Message &msg);
};

Then you might implement the IMessageBroker, something like this.

class MessageBroker : public IMessageBroker
{
public:
    void Send(const Message &msg)
    {
           // Validate the fields are appropriate for database
           ValidateFields(msg);
           // put it in the db
           Database.Store(msg);
    }

};

There you have it! Our SRP MessageBroker! He has a single responsibility. He accepts a message and stores it in the database. That’s it right? Well, you might be asking “What about sending to a Random recipient?” Yah — that’s not the MessageBroker’s responsibility… His responsibility is to “Accept” a message, and store it in the Database. It’s someone else’s responsibility to determine the recipient. /s

I hope even without the /s, you saw the sarcasm in that. But this is the reality of imposing SRP at a micro level. You’ve just shirked the responsibility of this class. He’s not anything more than a glorified secretary for the database. Worse yet, the real responsibility is now imposed somewhere it doesn’t belong.

Let’s say you require the client of your API to specify it. Well — you’ve just opened up a can of worms… Who’s to say they’ll use the same heuristic? They might have your carrier running all over Hell’s Half acre for the random recipient. Okay — force them to use a Utility class to generate the random. What you’re saying now, is that they have to remember to use your utility class to set the recipient. Or else… That’s not a very good design.

It makes sense, to put the responsibility, where it belongs. If calculation of a random recipient is the behaviour of how this system works. It only makes sense to put that logic into the MessageBroker.

class MessageBroker : public IMessageBroker
{
public:
    void Send(const Message &msg)
    {
        if(msg.type_ == MessageTypes.Random)
           msg.recipient_ = GenerateRandomRecipient(msg.sender_);

        // Validate the fields are appropriate for database
        ValidateFields(msg);
        // put it in the db
        Database.Store(msg);
     }

};

What’s curious about this, is that you can start to see you never needed the IMessageBroker interface in the first place. You see, the point of an interface is to be able to define a boundary of responsibility. Then have any implementation of that interface, provide that contract. Now, in our case, what’s our contract? Well, we get the Message somewhere where it can be dispatched. If it’s specified as a Random type, then we have to know to generate a random recipient, and get that to be dispatched. Would you get this out of the contract the IMessageBroker defines? I wouldn’t. So, for this design, it doesn’t make sense to have an interface. It’s a specific implementation, for a specific Message class. They’re very tightly coupled to each other. The behaviour expectation of your Message client, is very much dependent on the implementation behind that interface, implicitly. As you can see, his responsibility, really came to light once we took that step backwards, and looked at it for what it really was. (If you’re curious how I would do it differently, shoot me an e-mail!)

In summary, when you’re trying to apply the Single Responsibility Principle, it’s really important to focus your view at the right level. Take an objective look, and ask, what is this thing really doing? What would be reasons for me to make edits to this class? If you are honest, and you start to see that your class has many jobs. You can start to refactor some of those into their own classes, and compose that larger class of the smaller classes. Nothing says that Composition cannot occur with SRP. It just means your larger class’ job, becomes orchestration. There’s nothing wrong with that. The trap you don’t want to fall into, is shirking responsibility. You don’t want to start refactoring your code, where you’re pulling out responsibilities, and putting them on other classes. This will lead to a host of skeleton classes that are merely pass-through objects. The refactor in that case, is to look for the responsibility you’ve pushed on your clients. Ask yourself, should the client need to know that? If I was using this, and didn’t write it, would I know to do this? Those are the types of questions that you’ll find start to drive responsibility back into where they belong. That said, it’s a balance, and finding it is tough, it’s just a matter of practice.

I hope you enjoyed the post. As always — Happy Coding!

PL

“The price of greatness is responsibility” — Winston Churchill

 

Separating your Concerns

I spent a lot of time debating what I should title this post. Should it be “Buzz Words”? Or maybe “Separation of Concerns and SRP”… SOLID Concerns? In the end, I settled on this — Separating your Concerns. I also spent a bunch of cycles, asking myself what I really wanted to cover. What ideas do I want to convey? Then I spent some time thinking about how I would convey that message. What literary road would I take? From whom’s style would I borrow. However, none of this is of concern at this moment. The fact that it’s written is all that matters now.

I want you to think about the word, Organization, and what it means to you. Just take a moment to reflect on it.

When I think about Organization, I think about form, and about order. Organization makes me think about neatness, about cleanliness, and about space. Room to breath, and room to work. Organization to me is logical, it’s order — and the opposite of that is chaos, and anarchy. In our world, spaghetti.

Hold that thought.

Now, I want you to consider what “programming” is. What exactly is it for? What is a programming “language” for? Be specific.

You might think to yourself — “programming is telling the computer what to do.” Kind of. “A programming language is the syntax we follow to do that.” Kind of.

One of the definitions of “programming”, is the act of providing a computer (or machine) with with coded instructions for the automatic performance of a task. Now, that’s the definition of programming. But anyone who has worked on any project bigger than a hobby project, with multiple developers, knows it’s so much more than that.

Programming, not only is about telling the machine what to do. It’s doing it in a way that other people can understand it. It’s almost as if our programs are stories, and the compiler is the translator that turns it into instructions. The programming language, therefor is our medium of communication, between developers. Since, realistically the computer can’t understand C++ or C# directly. Consider for a moment, if we all had to “program” in CPU instructions written in binary, something a computer can understand directly. As soon as you have more than one person on the project, you’ve got a nightmare. It would be enough that the person has to communicate with the computer in that way, let alone with other developers. Trust me when I say, programming in higher level languages is for us, not them.

You might say “No. Comments are for communicating with other developers, and code is for the computers.”, to which I would reply simply “You’re wrong.” If you think that, I am sorry for you. (Actually, I’m more sorry for people who work with you.)

So programming, then is really a form of communication. It’s not completely unlike writing a story. This may seem like a bit of a Woo-Woo metaphor, but it helps to illustrate my point. Your tangled rats nest of notes you took in school, might’ve served its purpose for your studying. Though, it’s highly unlikely that it is of any value to anyone else. Not unlike programming, just because something is working when you write it, doesn’t make it of value to anyone else. Unfortunately, that mess of notes you took 3 years ago, is probably of little value now, even to you. The realistic truth, is that you then, is not you now. This is just like bad code. Trust me, I know because I’ve written so much bad code it’s mind boggling.

It’s not like this wasn’t a problem with writing. That’s why people invented literary tools, sentence structure, paragraphs. That’s why we have archetypes, and plot patterns. It’s to better communicate our stories. These things exist in programming, we have numerous languages, different patterns and practices. Hell, we even have smells. All these things try and make our code more easy to understand, for others, and for ourselves.

Let’s go back to Separating of Concerns, and how any of what I just wrote actually applies to programming. If we stick with the metaphor, that coding is a lot like writing, then what in writing is “Separation of Concerns”? Well, in your travels I’m going to assume you’ve read a book. In that book might’ve been a Table of Contents, that Table of Contents laid out the chapters of the book. The ‘Logical Separations” in the book. The book is structured in such a way, that the chapters flow. The author has taken the time to logically bundle pieces of relevant information. Can you imagine reading a book that is teaching you about Botany, and in Chapter 1 they dive directly into the root structure of a Hibiscus, and on the next page the configuration of soil nutrients? That’s not a book I want to read. So the act of bundling relevant information, for consumption of the reader, is in fact “Separation of Concerns”. Now, you can take this further. Do you think that when the author is crafting her book, that she’s worried about what type of paper it’s going to be printed on, or the font size? Probably not. Though — if she’s writing a book that contains needs special paper and tiny font,  likely she will ensure that the printing process will indeed support her special paper and tiny font. She certainly isn’t going to worry about this while she’s writing the book. In this regard, the author is Separating Concerns, regarding her functional requirements i.e. writing the book, and the non-functional requirements that the book needs to be on special paper in tiny font.

If we consult Wikipedia in regards to “Separation of Concerns”, we can look at the statement from Edward Dijkstra, that probably coined the term.

Let me try to explain to you, what to my taste is characteristic for all intelligent thinking. It is, that one is willing to study in depth an aspect of one’s subject matter in isolation for the sake of its own consistency, all the time knowing that one is occupying oneself only with one of the aspects. We know that a program must be correct and we can study it from that viewpoint only; we also know that it should be efficient and we can study its efficiency on another day, so to speak. In another mood we may ask ourselves whether, and if so: why, the program is desirable. But nothing is gained —on the contrary!— by tackling these various aspects simultaneously. It is what I sometimes have called “the separation of concerns”, which, even if not perfectly possible, is yet the only available technique for effective ordering of one’s thoughts, that I know of. This is what I mean by “focusing one’s attention upon some aspect”: it does not mean ignoring the other aspects, it is just doing justice to the fact that from this aspect’s point of view, the other is irrelevant. It is being one- and multiple-track minded simultaneously.

The first time I read this quote, I don’t think I fully groked it. So I read it again. And again. And again. Then I remembered a term that a lot of developers will preach. Make it work. Make it good. Make it fast. Coined by Kent Beck, in the UnixWay we’ll go with sometime ago. But Dijkstra beat him to it. Kind of. The common theme here, is that these pieces are logically separated. You concern yourself with the correctness, the efficiency, and the functionality of your application each in isolation. All the while, keeping in the back of your mind the other concerns. It was eye opening.

Alright — enough philosophy. How does that actually affect my programming?

Well we know now, that Separation of Concerns is essentially grouping logically functions of our program. That allows us to worry about a certain function of our application, without flooding our minds with other pieces. It allows you to focus. I don’t care how smart you think you are, you can’t focus on more than one thing at a time. If you try when you’re programming, you’ll end up with a tangled mess. You’ll start to bring pieces that belong in other areas, into the area you are. Then you’ll take pieces from where you are, and put them in areas they don’t belong. The smartest people, have the innate ability to focus on one thing at a time, while keeping track of all the other things outside.

While authors have chapters. As programmers we have abstractions. In my opinion, the two definitions that most closely apply to programming are:

the process of considering something independently of its associations, attributes, or concrete accompaniments.

and

the quality of dealing with ideas rather than events.

The first part of an abstraction, is that it lets you consider the component devoid of its baggage. You don’t care that it references EntityFramework, Boost 1.61, or the entirety of  GitHub. You don’t care that it has 1.3 million member variables, and 42 private functions. The only thing you care about is that it fulfills its contract to you. That is, you care about it’s public API. You ask for a list of Foo, you better get a list of Foo. That’s why you need to keep your public API clean and concise. Because that’s your first layer of abstraction.

The second definition, and an extremely important part of an abstraction. Is that it allows you do deal with a concept, rather than its details. This lets you think at a higher level, and deal with larger concepts without drowning in all the details. The (not so) modern remote or clicker on a television, had an abstraction that allowed you to press “up”, and that would tune the frequency of the television to the channel. This allowed you to work with the idea of “up” and “down” on your remote, to tune your television. Instead of being concerned with the tuning of the radio frequency that represents the channel.

Obviously given the fact that this entire post is riddled with metaphors, you might already know I’m a sucker for metaphors. The good news is, I’m about ready to unveil the pièce de résistance, of my metaphors. It’s the one I think most clearly buttons this concept up. It’s the car. The car, isn’t just a fantastic example when we’re teaching inheritance. It’s just a great all around metaphor when it comes to programming.

Specifically the steering wheel — this is a fantastic abstraction metaphor. You get into your car, and you look at the wheel. Do you care about the mechanics behind it? No. Do you care about the linkages between the wheels and whatever makes them turn? Nope. How about the power steering pump? The electronics? Nope, and Nope. You care that this thing makes your vehicle go left and right.

Do you know why this is so important when it comes to driving? It’s because driving is complicated, you need to have quick reaction times, and be able to focus on other things, like the rules of the road. At that level, you only have the capacity to concern yourself with “left” and “right” when it comes to steering. Imagine what driving would be like, if you had to push and pull leavers and rotate gears to turn. It would be a nightmare. That wheel in the cockpit of your vehicle, allows you to focus on actually driving, instead of the details of turning the wheels. It moves that concern to a different area. Now, do the mechanics behind that wheel still matter — hell yeah! But as long as they’re functioning when you’re driving, it isn’t your concern. It’s beautiful. The second benefit of this, you can drive a bunch of different cars. You could have a beat up pinto today, and tomorrow be “rolling ‘benz”, all because you know how to use a steering wheel. Steering stays the same, and it has for many years.

Another awesome benefit of the steering wheel, debug-ability. Say you crash your pinto taking a turn. Pretty easy to figure out where the bug is. Is the bug between the seat and the wheel, or the wheel and the head lights? Let’s check, when I turn left, do the wheels turn left? Yes. Is it the correct amount? Check. Okay — problem lies between the wheel and the seat. Easy.  It’s also really easy to check this when the car comes off the lot, or after you’ve had it serviced. Weird — that sounds a lot like unit testing to me.

So in order to sum all of this up. Separation of Concerns affects the entire spectrum of software development, from architectural design, right down to the details of the code. It’s about organization, and only concerning yourself with one topic at a time, all the while keeping in mind those other pieces. You first concern yourself with the design of your program. Capture the like ideas, divide them into chapters. While you’re implementing your chapters, look for steering wheels. Let your chapters flow into one another, but don’t mix Chapter 1 and Chapter 13.  Find spots for steering wheels, don’t force them to use gears and knobs. Mostly — know that this is a process, and it’s hard. You’re likely not going to get it right the first time. It’s just about trying, keeping these concepts in the back of your mind, and looking for opportunities to apply them.

I hope that this post has brought some light to the topic of Separation of Concerns. Maybe next time I’ll try my hand on one of the other concepts of Computing that I got wrong so many times.

“Organizing is what you do, before you do something, so that when you do it, it is not all mixed up” — A.A. Milne

I hope you have a splendid day, and as always — Happy Coding!

PL

 

 

Separation of Concerns

Make it work, Make it Right, Make it Fast

The Zero Cost Abstraction of Iteration

I’ve been hooked on C++ for about 10 years now. Since CMPUT101, I’ve been attracted to the syntax of the language, the simplicity of use, and later the driving ideals behind the language. C++’s author Bjarne Stroustrup, stands alone when it comes to preaching language ideals and pushing the language forward all while respecting these ideals. This is no easy task, especially when the language is designed by a committee. I’ve always been convinced one of the key reasons C++ is such a large success, and has remained so timeless; is the fundamental guiding principles behind the language. The principle that I believe reigns supreme is the ‘Zero Cost Abstraction’.

What is the ‘Zero Cost Abstraction’? Also called a ‘Zero Overhead Abstraction’. Well — it’s an abstraction, that costs nothing. Not like monetary currency; or a favour. Instead resource or runtime cost. Bjarne’s definition is “an abstraction that imposes no space or time overhead in excess of  what would be imposed by careful hand coding of a particular example of the abstraction.” So in other words, an abstraction that doesn’t use any more resources than if you carefully crafted the assembly yourself.

Well then, what is an ‘abstraction’? Well an abstraction is a concept that you can work with, that ignores the details of operation. A good metaphor for this is a steering wheel on a car. You turn the wheel left and right, to turn left and right, but you’re not concerned with the details of actually moving the wheels of the car on the road. In fact, you don’t want to be concerned with those details at the level of driving.  You want to be more focused on the bigger task at hand — driving the car.

So abstractions in computing allow us to work with concepts, craft algorithms and structure code, so that we don’t have to worry about the details. Programming languages themselves are abstractions, they allow us to work with logical operations, classes, English words, and common symbols to create instructions that cause computer hardware to do things. Languages like C and C++, are considered ‘close to the metal’, this means that they only thinly abstract the assembly that is run on the processor, only thinly abstract the management of memory (either directly to the MMU or through the OS), and only thinly abstract the other pieces of hardware. Languages like C# and JAVA (shudder), are higher level languages, meaning they have many layers between the code and the actual instructions that execute on the CPU. These higher level abstractions give way for more flexibility, but often have a cost. In the case of JAVA, the flexibility of portability, at the cost of run-time and space overhead. Garbage collection adds the flexibility of not having to worry about memory management, at the cost of run-time, and space overhead. Not to mention the cost to developers, as the become brainless in the areas of memory lifetime, and ownership rules.

[Coming Soon – a post on Virtual Machines]

So what does any of this have to do with the ‘Zero Overhead Abstraction’ principle? Well, obviously I have a story to go along with it. So some time ago I was working on my library [ASPeKT] and I was soliciting the help of the internet for advice on how to work better with the IL I was crafting. The comments I got, were, well, unexpected to say the least. The majority of the criticism I received was my use of direct for loops for iteration. As opposed to the cooler C# foreach loop or even better LINQ-to-everything!! Now, I can take critiquing of my code, after all that’s how you learn. So I pondered this for quite some time. I reviewed some of the pull requests which had transformed some of my boring for-loops, into beautifully crafted LINQ queries. I wasn’t buying it. I just couldn’t. It hid some of the intent of what I was trying to do, and call me old school, but I found it harder to read.

Enter foreach, this one I liked. C++11 introduced new semantics for it and I liked the clarity that it gave. When you’re iterating a collection using an indexer, the first thing you do is get the item at the index. The foreach, just abstracts this and your boundary checking in a nice syntax package. Color me smitten. Now, I didn’t actually refactor much in my library to use foreach. Honestly, I like it but I wrote the code already and it worked. However I started using foreach, pretty much everywhere I could, just like I did in C++ now. I know that C# probably had this before, and I obviously adopted it backwards, but I do a lot of shit backwards. So sue me. 

Fast forward a couple of months, I’m reading “Writing High-Performance .NET Code” by Ben Watson. He’s got a little section on loops for iteration. The section I think was on comparing C++ to C# for performance. When we’re talking speed of execution, less instructions is more. The less instructions you have to run, the faster your program will be. The fastest program you can write, is one that does nothing.

There was a snip on comparing a loop in C# to a loop in C++, and the generated ASM instructions. He was making the statement that C# doesn’t ALWAYS have much overhead over a language like C++. He showed how old skool for loop iteration, was virtually the same instructions for C++ and C#. But the foreach, it was something else. I was floored, I had never really thought about it, but at that moment I did. What does a foreach in C# actually do?

His example was something like this

[C++]
int sum2()
{
    int range[4] = { 1, 2 , 3 , 4};
    int sum=0;
    for(auto i=range; i<range+4; ++i)
    {
        sum+=*i;
    }
    return sum;
}

[ASM]
//-O2 Disabled so it wouldn't optimize the loop out
sum2(): # @sum2()
  push rbp
  mov rbp, rsp
  lea rax, [rbp - 16]
  mov rcx, qword ptr [.L_ZZ4sumvE5range]
  mov qword ptr [rbp - 16], rcx
  mov rcx, qword ptr [.L_ZZ4sumvE5range+8]
  mov qword ptr [rbp - 8], rcx
  mov dword ptr [rbp - 20], 0
  mov qword ptr [rbp - 32], rax
.LBB1_1: # =>This Inner Loop Header: Depth=1
  lea rax, [rbp - 16]
  mov rcx, qword ptr [rbp - 32]
  add rax, 16
  cmp rcx, rax
  jae .LBB1_4
  mov rax, qword ptr [rbp - 32]
  mov ecx, dword ptr [rax]
  add ecx, dword ptr [rbp - 20]
  mov dword ptr [rbp - 20], ecx
  mov rax, qword ptr [rbp - 32]
  add rax, 4
  mov qword ptr [rbp - 32], rax
  jmp .LBB1_1
.LBB1_4:
  mov eax, dword ptr [rbp - 20]
  pop rbp
  ret
.L_ZZ3sumvE5range:
  .long 1 # 0x1
  .long 2 # 0x2
  .long 3 # 0x3
  .long 4 # 0x4
[C#]
static class Program
{
     static int sum()
    {
          int[] range = new int[]{ 1, 2 , 3 , 4};
          int sum=0;
          for(var i=0; i<4; ++i)
          {
                 sum+=range[i];
           }
          return sum;
   }

}

[JIT ASM]
Program.sum()
    L0000: push ebp
    L0001: mov ebp, esp
    L0003: push edi
    L0004: push esi
    L0005: mov ecx, 0x717168e2
    L000a: mov edx, 0x4
    L000f: call 0x58f3200
    L0014: lea edi, [eax+0x8]
    L0017: mov esi, 0x251c084c
    L001c: movq xmm0, [esi]
    L0020: movq [edi], xmm0
    L0024: movq xmm0, [esi+0x8]
    L0029: movq [edi+0x8], xmm0
    L002e: xor esi, esi
    L0030: xor edx, edx
    L0032: mov ecx, [eax+0x4]
    L0035: cmp edx, ecx
    L0037: jae L0049
    L0039: add esi, [eax+edx*4+0x8]
    L003d: inc edx
    L003e: cmp edx, 0x4
    L0041: jl L0035
    L0043: mov eax, esi
    L0045: pop esi
    L0046: pop edi
    L0047: pop ebp
    L0048: ret
    L0049: call 0x73a52b10
    L004e: int3

As you can see 25 instructions in C++ vs.  30 instructions for C#. So your standard for loop in C++ and C# are running essentially the same instructions.

The foreach was a different story — he wouldn’t even show the instructions. He only showed the generated IL, and let me tell you, it was a lot.

In my own research, the ASM generator that I used, generated 150+ instructions, which didn’t seem like a lot. However, I did notice is that it didn’t generate ASM for the actually calls to MoveNext(), it just used the syntax ‘call’ MoveNext(). Which likely has a lot more instructions under the hood.

Let’s compare that to the pure C++, range foreach.

[C++]
int sum()
{
    int range[4] = { 1, 2 , 3 , 4};
    int sum=0;
    for(auto i : range)
    {
        sum+=i;
    }
    return sum;
}

[ASM]
sum(): # @sum()
  push rbp
  mov rbp, rsp
  mov rax, qword ptr [.L_ZZ3sumvE5range]
  mov qword ptr [rbp - 16], rax
  mov rax, qword ptr [.L_ZZ3sumvE5range+8]
  mov qword ptr [rbp - 8], rax
  mov dword ptr [rbp - 20], 0
  lea rax, [rbp - 16]
  mov qword ptr [rbp - 32], rax
  mov rax, qword ptr [rbp - 32]
  mov qword ptr [rbp - 40], rax
  mov rax, qword ptr [rbp - 32]
  add rax, 16
  mov qword ptr [rbp - 48], rax
.LBB0_1: # =>This Inner Loop Header: Depth=1
  mov rax, qword ptr [rbp - 40]
  cmp rax, qword ptr [rbp - 48]
  je .LBB0_4
  mov rax, qword ptr [rbp - 40]
  mov ecx, dword ptr [rax]
  mov dword ptr [rbp - 52], ecx
  mov ecx, dword ptr [rbp - 52]
  add ecx, dword ptr [rbp - 20]
  mov dword ptr [rbp - 20], ecx
  mov rax, qword ptr [rbp - 40]
  add rax, 4
  mov qword ptr [rbp - 40], rax
  jmp .LBB0_1
.LBB0_4:
  mov eax, dword ptr [rbp - 20]
  pop rbp
  ret

Hmmm…. 30 instructions. So as you can see, this is an illustration of a ‘Zero Cost Abstraction’. The code has been shrunk by quite a few characters. It becomes easier to read and reads with more intent, yet it doesn’t carry any overhead over the original loop.

So, what’s the development cost of writing your own foreach enumerable collection in C#. Implementing the IEnumerable concept.

Well — first you need to implement the IEnumerable interface, which returns an IEnumerator. The IEnumerator class is really the meat and potatoes. It contains your iteration state and a reference to your collection. You need to implement the MoveNext() call to increment the enumerator, which returns true or false based on whether it incremented. Then you need to implement Reset(), which resets the enumerator. You need to implement the ‘Current’ field to return the current object.

Vs.

What’s the development cost of making something enumerable in C++. Implementing the iterator concept.

You need to implement the iterator concept. Iterator concepts are described here, the minimum you need is the ForwardIterator. Which you need to be able to read and increment with multiple passes. The iterator concept models the pointer, so you need to implement operator++() and operator*(), and operator==(). Like the IEnumerator the iterator is the brains of iterator (fancy that), and contains some reference to the collection as well as iteration state.

In order for your collection to work with C++ foreach, you need to implement a begin() and end() method, which return an iterator.

begin() => returns an iterator to the first object
end() => returns an iterator of one past the last object

It’s as easy as that.

The moral of this story, just because an abstraction makes the code cleaner, doesn’t mean you’re not paying for it, someway. Of course, the flip-side is, if there is careful thought put into the abstraction — you can eat your cake and have it too.

“Small leaks sink big ships” – Benjamin Franklin

Happy Coding!

PL