Beforehand, I have discussed the role of the simplicity in creating an efficient software design, and now in this article, I am going to use an example of the simplifying process to remove complexity factors from a real-world problem to reach a maintainable and good enough rich object-oriented design. The problem I want to solve is creating an Engine for controlling a “Snake and Ladder” game.
I think most of the children from all generation have played “Snake and Ladder” game. If you are from those rare people who have not heard about this game I refer you to Wikipedia’s detailed information about the game; briefly, Wikipedia states “Snakes and Ladders is an ancient Indian board game regarded today as a worldwide classic. It is played between two or more players on a game board having numbered, gridded squares. Some “ladders” and “snakes” are pictured on the board, each connecting two specific board squares. The object of the game is to navigate one’s game piece, according to die rolls, from the start (bottom square) to the finish (Top Square), helped or hindered by ladders and snakes respectively. The game is a simple race contest based on sheer luck and is popular with young children. The historical version had root in morality lessons, where a player’s progression up the board represented a life journey complicated by virtues (ladders) and vices (snakes). “
As I mentioned, I am going to represent a step by step object-oriented design for a computer-based version of the game controller. I was talking about phases of object-oriented design in the “Design for simplicity, not for complexity” article, to recall I have stated: An O-O Design process consists of three phases, including “Creating a Conceptual Model,” “Creating a Specification Model” and finally “Creating an Implementation Model.”
Here, in this text, I will pass these stages one by one, and I am using some UML diagrams to depict the models, but the Implementation Model is provided as a project in C# on the GitHub.
The first step is creating a conceptual model or in other words, finding related data items to the elements of the problem space in the real world and omitting irrelevant data from them. Using the “Abstraction” and “Encapsulation” principles -tow principle of the quadruplet divine principle of the object-oriented paradigm- we can create this initialing model. As “Craig Larman” has stated in his seminal book, “Applying UML and patterns,” there are three general techniques to find classes of the Conceptual model. These techniques are “Using an existing model,” ”Finding the phrasal names in the problem statement and requirements” and finally “using a category list of suggested concepts.” The result of applying the second technique is a list of classes and their related attributes, including:
The game, Player, Snake, Ladder, Board, Cells of the game board. A candidate for the UML class diagram for this conceptual model of the problem would be something like the following image:
As it’s obvious, we have focused on the primary attribute of each object in the domain and the relation between them in the real world. As a result, we can tell our story of the snake and ladder game by storyboard technique using this diagram, as it goes on in the real world game. For instance, the story could be such a thing,” Once upon a time, there was a game which some players were playing it, this game had a board with specific size and some cells that some of them have been acquired by some snakes start and end or ladders begin and end, then blah blah blah.”
Nonetheless, what if we convert these classes to the software classes and add some methods to them to manage the game? By doing such crazy thing, not only you have not created software for facilitating the game control process as a computer program, but you have tried to create a miniature size version of the problem in the real world with all details, so it’s not a model, because models are simplified version of reality with unnecessary information, structure or relation among the elements. To clarify, such a decision seems that instead of building an aeroplane as we do these days in the aerospace industry, engineers try to create something exactly like a bird and try to make it fly, even such a strange machine can operate, it is not the most sufficient way to build a flying machine and we have added some complexity to the existing complexity in addition to wasting our resources. So what is the solution?
Since the core idea in the object-oriented paradigm is combining the behaviors and their related data in classes using encapsulation, we need to add required behavior to our classes to empower them as a game controller. A fundamental misconception through this process is adding some methods to the exact domain classes. This belief is entirely wrong because those classes are not software classes, they are just representative for the concepts in the real world which has been depicted by a class diagram notation in the UML, we have used these classes as an input of the software classes construction process. The “Process” means applying a set of principles to make the model simpler, the first principle is“GRASP” or “General Responsibility Assignment Software Principles” and the second one is “S.O.L.I.D” which is an abbreviation of some other abbreviations! including ”SRP,” ”OCP,” ”LSP,” ”ISP” and “DIP.” These principles help to omit the complexity of the real world while the appropriate level of encapsulation and abstractions remain to keep the software safe from the increasing synergistic complexity of its building blocks.
As this article is not about these concepts, I jump over them and apply them to the domain to create a “Specification Design Model,” Specification model is a simplified version of the domain model which its classes have not only data attributes but also methods to implement the required behaviors. The result of such a process will be a class diagram as follows:
If you look at the diagram, you can see some classes are removed in compression with the domain model, including snake and ladder, besides dice and cell, while there are two new classes more than the first model.
It’s evident although some methods are added to the classes in the specification model, this model looks more straightforward than the domain model. However, why?
We know the more elements or relationship among them exist in a model the more complexity appears during the development and maintains phases so as a solution during the behavior assignment we try to break down the relations or merging some classes while in some cases replace them with other ones. For instance, in my example, the cell class is omitted because it does not do anything in the game regardless of showing the current position for a player on the board. As the board has size*size cells, Instead of keeping all cells we keep the size of the board and manage the positions by a simple mathematical formula, in the same way, the coordination of a player can be inferred in a two-dimensional space.
Moreover, the snake and ladder class are merged into the Shortcut class, because both of them do some things, they rout the player from a start point to an end point while the difference between these two is about movement direction which we apply it by setting From and To points in the class based on their values. In addition to that, the Dice class is removed as well from the model, because in our solution it is not more than a random number between 1 and 6 and during the game control process. On the other hand, a PlayerResult class is created to encapsulate all required data about the previous and new position of a player after calling the play method in the game class.
The implementation design is the result of the using the facilities provided by development technology and platform to meet the specification design ideas more easily. So we can say a unique specification design can result in a different form of implementation in different technology and platforms. As such facilities are created to simplifying the development activities, the implementation design model would be smaller than the specification model.
To sum up, A business domain model –a synonym for conceptual design mode- cannot directly convert to the source code, besides if you use a specific technology or framework, for example, .NET, Java,… it’s more appropriate to use their built-in capabilities to gain an implementation design model. It has to be bear in mind that modeling means make the real world concepts simplified to be understood more efficiently, a miniature version of the reality is not a model, it is the reality itself but in a smaller size with exactly same complexity level.