Skip to content

Software Engineering

tsirif edited this page Oct 3, 2014 · 9 revisions

General Topics

###2. Software Engineering

In this chapter, i will try to convince you why Object Oriented Programming (OOP) is great and hence how C++ is suited to be used. After that i will explain some concepts and techniques, giving some examples of software patterns that Pandora has used and a lot more references to classical and modern literature of software engineering and architecture. Finally, i will promote agile developing and coding practices which i believe that maximize productivity in a team and overall enhance the group developing experience. Adopting this style of team-working will automatically show the virtues of OOP and why one should try to learn to code with team-defined standards, testing tools and software patterns.

What is the main advantage of OOP over other programming paradigms?

OOP is known for making a project modular. Modularity is the final goal of OOP style and resides naturally in the concept of object in C++. It begins with the ability to reference object's attributes through its own base class. Base class is an abstraction upon objects that have common attributes and a derived class is an extension of the base prototype. This ability of inheritance, whose usage is the first important thing taught to someone who approaches OOP, makes writing abstract code possible and hence code that is portable, generic, modular and unconstrained (up to a certain point) of the problem's variables. Thus, modularity is a great code feature because it gives your program extensibility to the problem's constraints and also adaptability to changes of already known constraints. It also means that you can work separately and independently each module. You can examine and test it as a system of its own (testability). You can change it and plug it back into the general system to which it belongs without anyone noticing (ideally). This means that a system's development procedure does not require symmetric development of its components. But each component, modular as it is, can be developed in different times, with different speeds, by different people and this will not affect the work in other components (of course delay in the development of one component means delay of the completion of the whole). A fully tested module that can be fit to a system can be used anytime, so it promotes reusability. As a result, making a project modular is the best option for a development team.
For more information you can read a software engineering textbook about the virtues of a good project and program, suggesting Ian Gorton's "Essential Software Architecture" especially chapters 4-7.

How do you achieve modularity with C++?

Right usage of C++ means that you take advantage of its OOP features and so its inherent power to invoke modularity to your work! One should start from the very basics of the problem, trying to find abstractions of its needs, fractals and self-similarities in its behavior. This will the designer a general view of the problem and the ability to describe it with simple rules and states. Then the designer should delegate each distinct rule to a certain component of the design and with that he would succeed in visioning the distinct modules that make the whole system which solves the problem. In order to split the work into modules that are delegated some responsibility, he needs to define very well both the components themselves, while he tries to keep the seperation of concerns, and the interactions between them. These two things make up the system, the components and the interface.

Experience has shown that there are certain virtues which an Object Oriented design must have, which recur in any software problem solving. These virtues are said to make your program SOLID and can be realized with the use of design patterns that have solved once a recurring design problem. Software design patterns are our means to construct an efficient and modular program. Many techniques are described by the "Gang of Four" in the classic bible of software engineering. But as programming languages evolve techniques do so too, with others being implemented differently by the time, others being used rarely and disappearing and with new ones being developed. Below i mention some recognizable patterns which you may have seen and you should definitely know how to use them:

  • Bridge pattern: This is how plugins are made! You can also achieve Inversion of Control through this pattern. Inversion of control is a very crucial concept of programming dynamically (different from dynamic programming) which dictates that program flow in a method should not be controlled by the implementation, but by the user of the method. Thus, this way you take run time decisions on your program's flow. You can study from the originator of this concept at this link or this.
  • Builder pattern and the Factory pattern
  • Decorator pattern: aka run time subclassing, check the example
  • The Wrapper: Also known as the adapter, used when delegating responsibilities.
  • The composite object: When your the basket is treated like an object, but it still holds objects...
  • Strategy Pattern: Changing your plans on run time, does not mean you will use a huge 'switch' statement. Objectify your plan, instead.
  • The Curiously Recurring Template Pattern: When basic implementation uses something that it is not already implemented, but that something cannot be in your derived subclassing repertoire. Solves this problem but throws away run-time choice. It is found regularly in APIs and libraries when one wants to program generically

Obtaining the right techniques for your problem and using them correctly is a tricky issue that needs experience and confidence. But if you know and stick to the principles of OOP and adopt good and solid coding practices, you can continuously make your program better by self-criticizing and redesigning when you think you should do so. Continuous self-criticizing is essential for a software engineer and you need to have some stable coding standards that you can measure yourself upon. Pandora's coding standards are described here. The process of redesigning correctly and enforcing your coding standards is named refactoring and Martin Fowler has written a very good book about finding your code's weaknesses (code smells) and cleaning these before it becomes a mess.

Since accepting continuously criticism is part of writing better software, doing so in a team maximizes the efficiency and promotes productivity. In order for it to work, it must be based in an environment of mutual respect and trust of your companion's knowledge and opinion. Working this scheme further, a team can adopt software development tactics that will make them product much more than the sum of what they would do alone. Thus, maximizing efficiency while working as one in a modular project. To achieve this working pace and style, the team must be agile! Hence the Agile Software Development tactics! This means that the team works continuously on all phases of software production line in a structured way. In order to do that effectively the users must adopt coding styles that permit easy maintenance and changes. So the OOP way is a necessity in this form of co-working!

Last but not least, one must have in mind that a working software is a working software and solves the problem. With this statement i do not want to contradict whatever i have said previously, but i want to say that everything must be done with modesty. Μηδέν Άγαν! This way we will avoid doing anti-patterns and stick to the point clean and nicely. Anti-patterns are complications that show that something is not as effective as it is thought to be! The following links, along with the link in the 'anti-patters' word, are food for thought and parodies of situations we should not be in. Enjoy!
http://sourcemaking.com/antipatterns
http://www.amazon.com/AntiPatterns-Refactoring-Software-Architectures-Projects/dp/0471197130 (this book also presents ways to avoid and tackle occurring anti-patterns!)

The conclusion is one: C++ is a programming language with inherent the graciousness of Object Orientation.
As programmers of C++ we are obligated to do one thing: JOIN THE AGILE FORCES!!!

Next chapter: Software Testing