Software Design Principles – Lines Per Day https://www.linesperday.com Lines Per Day Sun, 10 Mar 2019 14:45:23 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.5 Proof of Good Quality Code https://www.linesperday.com/proof-of-good-quality-code/ Fri, 20 Oct 2017 16:19:46 +0000 http://www.linesperday.com/?p=399 Whenever I sit with my boss I often hear these lines:

Can you compress this time schedule? Why do you need an extra day? Haven’t you done it before and this time it should be easy to do? Can you compress the schedule by working late hours?

You try to answer these questions and you realize that your boss is getting bored. How do you feel at that moment? Frustrated!

This happens when you give an estimate for a task while thinking that a quality code will take more time. If good design is your priority then it will take extra effort to complete the task.

It does not matter how precise or compressed your estimates are you will always have to bargain with your boss over your estimates.

This will leave you with two option either to write code as fast as you can or fight for quality code. I will always choose the ‘quality’.

Why does this happen? Is your boss skeptical? I believe not.

Being skeptical is a good trait but being fearful is not. It is easy to understand if your boss is not fearful. For example, if you tell your boss that a particular task will take around two weeks. What do you think a fearful person will be thinking?

“What if he fails in completing the task”
“What if the result does not match what I want”

If your boss is fearful then he needs proofs, data, and maths to show him that design patterns help in writing good quality code. But you know that there is no scientific method that can satisfy your boss.
Software design is not science. It is a heuristic.(I guess I am writing these lines too much :)- )

Let your boss be fearful. But I don’t want you to be like that. I don’t want you to be fearful when you select quality over quantity(i.e writing code fast)

All you have to do is just write quality code and wait. No matter how much time it takes to write good quality code. Just don’t be fearful that your efforts are in the danger of being wasted.

You will not get the reward for your good quality code in the next week. You will have to wait and you will reap benefits later. You will see and feel the benefits of your good quality design.

Let the greatest tester of all time test your code and that is the ‘time’. If your code passes this test which means easy to change, re-use and maintain then you don’t need any other mathematical proof to show off.

Afterwards, you can show off your design knowledge to your colleagues but this time with authenticity because you know what it feels like to be a writer of good quality code.

In your opinion what is important to you?
+Showing off in front of your colleagues
+Defeating your boss technically 🙂
+Writing code as much fast as you can

Or anything else. Reply in the comments section.

]]>
3 object oriented programming resources that can fail you–may be they already have https://www.linesperday.com/3-object-oriented-programming-resources-that-can-fail-you/ Wed, 26 Jul 2017 16:01:37 +0000 http://www.linesperday.com/?p=273 I tried to learn good programming skills. I tried learning object oriented programming, design, and principles because I wanted to be a good software engineer.

For a small period of time, I was thinking that I know all about modularity, testability, readability, reliability and other ‘jibberish’ I used to talk about. Until I faced the real world challenges.

Recently, I was thinking about the reasons of my consistent failures. Maybe it is because I am the laziest person. Or maybe this is because I have not focused enough on this subject.

But you know, there were other things which I considered as main resources for learning but they were not good enough.

Here they are: (you may have others and I want you to share them with me:) )

Learning in a classroom

I asked from many of my friends from different institutes and universities and they said that classes are not very much fruitful. In a class, they will teach you stuff like UML, only definitions of design patterns and some other vague concepts.

In class, you will think a design activity is a one-time activity which is done by some high-level souls a.k.a software designers. We all know that never happened.

Another thing is people who are teaching you have not much experience of real-life software development. They studied in the same class and now they are just repeating whatever they listened when they were the student. Instead of experiencing the pain of applying the knowledge they focus on delivering the bookish knowledge to others.

And that became useless when you go in the field.

Learning via boring and complex book

Some books are great. While others are boring as hell. They will demonstrate (and always will) the Animal and dog examples.

There is nothing bad in simple examples when starting out. But these boring books will keep these type of simple example until the end. You know that real-life is very different than a dog and cat example.

Other books are complex. They will jumble upon dry examples and make the simpler concepts very difficult to understand.

Again, I believe these books are written by academics and for academics. This is because when you read any book by a professional(with years of experience) you will experience the ‘AHA’ and ‘right on’ moments on every page of the book.

Learning via diagrams– okay what is this

I was motivated to learn MVC pattern. Every article that I find on the internet was about displaying three large circles where one represents the model, one represents the view and remaining one represents the controller.

Here is an example:

MVC Diagram

Yikes.

Does that give you the big picture–naaaah. Believe me, you will not be able to implement MVC using this diagram.

You may be thinking that this diagram will help us to understand the concept of MVC. Yes a little bit– but mostly this type of diagrams will stray you away from the real concept of MVC(which is largely based on compound patterns- that is you will have to understand at least two patterns to understand MVC flawlessly and easily).

This diagram is just showing you– I don’t know– some sort of flow.

So, I believe the only authentic way to learn about programming is to find someone who has already done it. Someone who has the experience of field and real life. Learn from their books or their classes or courses or a one-to-one coaching.

Okay. So this ends my story. What are your experiences? What difficulties you have felt while learning about design principles and design patterns. Tell me your stories. Reply me or comment here.

-Umair

]]>
Get Serious About Your Programming Skills https://www.linesperday.com/get-serious-about-your-programming-skills/ https://www.linesperday.com/get-serious-about-your-programming-skills/#comments Fri, 21 Jul 2017 07:01:24 +0000 http://www.linesperday.com/?p=263 Have you ever feel the pain of being a beginner? Remember the time when you started your first job as a developer and people treated you like a noobie.

You know you are good but they don’t know. You have done some good project in your undergraduate studies or in your personal time. You know you have to sell yourself in that last interview.

You have earned your place. But nobody treats you like somebody. They even treat you in a way that you started to believe them and consider yourself a less of a developer–”DONT DO THIS”.

Programmig

Let’s think about why a new developer faces these challenges. It could be that because they are junior and nobody has confidence in them until they prove themselves.

It’s possible that a junior developer does not know about the frameworks and technology they are using.

Every developer has faced these situations. I have faced them too. Once I was given a task to write a write a script for MS Excel.

I was a beginner. I have not done it before. So I was panicking. I thought what if I didn’t do it. I learn how to generate a script. Test it and give it to the seniors. It was an easy task but I was nervous.

So, I completed the task and when they start testing I said (in my heart) please say yes. Please say ‘okay’.

You know as a newbie we are totally on a different emotional level. As a beginner, we consider ourselves always under a test-even after the probation period.

But who wants to live as a junior developer. You want to grow up and get serious about java (or any other programming language that you are using)

But why you need to transition to a senior developer?

There can be many reasons. Simply most of us don’t want to call ourselves noobies. We want to get serious about programming skills.

Or you want to be a senior developer because you wanted a fast promotion. That can bring you all sorts of luxuries like money, free time and a boss of junior developers!

Or you want to learn the technology of your current organization fast and then move to another technology in another organization. In this way, you get an experience of both technologies. Why? Because you need more per hour earning or get more freelance projects.

Or you simply wanted to create an impact. You want your work to be appreciated and you want to serve a huge number of people.

For all of the above reasons, you wanted to transition from a beginner to serious programmer.

Next question: How do you wanna get there? First, we talk about frameworks.

Frameworks VS Principles

Frameworks make our lives easier(or make it a hell if you have used the wrong framework i.e. SubSonic). Hence learning a few framework is often the bare basic requirement in most of the work places.

Most of the time people exaggerate them. They too much focused on learning a new and sexy framework. Or learning frameworks for the sake of ‘learning frameworks’.

While we should be learning about the principles on which these frameworks are built. Well, I am not saying go and develop the next-gen object-relational mapper. But we must know about the underlying principles of any framework.

Let me share a personal story with you:

Discovery of MVC pattern

Once I was assigned a project different than my existing skill set. That’s the beauty of my job. I am not stuck on linear problems. I have to face new challenges very often.

Anyway, the critical problem was that there was a huge amount of images(small ones) that needs be loaded into the memory. Due to memory constraints, I cannot load all images into the memory at once.

Hence I have to load images into memory according to the user action. Consider this like an anticipated load. The application has to anticipate according to the user behavior.

This is because we don’t want the user to stare at the blank screen while a sand clock is appearing on the screen with the message “Loading Images”.This would be death to our project.

So, I thought about if there is any framework that can help me with that work. The application was based on XNA framework. That framework is absolute now. That was never a popular framework and therefore there was no large community hence there was no support available.

Therefore, I was alone. No built in framework to support the kind of functionality we needed. So, I tried on my own.

So, I created a class named ‘Manager’. This class accepts the user input. Update the model and load images for that model. It also loads the adjacent images for the case when user input changes rapidly. Now if the user changes the input then the user will be served with already loaded images hence no delay for the user.

Also, there was a separate class named ‘Renderer’. The responsibility of this class is to render the loaded images.

The distribution of logic made it easier for me to do the work. Then an idea strikes me that if I assign the responsibilities properly- I can implement and MVC(Model View Controller) pattern. Hence the universe witnessed the birth MVC pattern implemented in XNA/C#.

O.K. O.K. I know, it is not sophisticated like Asp.net MVC but it is good enough first version. I can improve my framework like asp.net MVC framework is improved. They have currently version 6 of MVC.

I was able to do this because I understand why MVC pattern is important and what are the internal mechanics to implement.

Can you guess from the above description that which class should be the controller?

The controller class in my little MVC framework was the ‘manager’ class. Hence assigning proper responsibilities to classes I was able to distribute responsibilities in model, view, and controller.

Life was easier after that. Any change in the view was independent of the controller code. The code was clear, readable, elegant, modular and easy to test.

And so on.

Principle first approach

I knew that there is no framework or technology out of the box available to help me out. By learning about MVC design pattern and underlying principles I implemented MVC pattern for my XNA project.

So, most of us wanted to learn frameworks and perfected them and master them. But I believe it is not about learning the framework but what happening behind the framework. On what principle this framework is working?

If you want, can you write a framework for yourself? That will not sophisticated as available in the market but it is yours and you can remake it, enhance it or publish it for other people to use.

You know what you are talking about

There is a lot of difference in talking about frameworks and speaking big words like readability, testability, modularity, and scalability than actually demonstrating these capabilities in your code by yourself.

Once you know the underlying principle and implemented them by yourself then you know what you are talking about. You know what does it mean by “easy to change” and modular. Otherwise, you will be reading the documentation of the framework that you have used blindly.

Hence, if you want to get serious about programming skill you need to focus more on design principle and best practices rather than learning an already available framework.

So, I rest my case and now it is your turn to tell me about what do you think? You can send reply me via email or write comments here.

]]>
https://www.linesperday.com/get-serious-about-your-programming-skills/feed/ 1
A Process Slightly Greater than the NATURAL Software Development Process Model https://www.linesperday.com/a-process-slightly-greater-than-the-natural-software-development-process-model/ https://www.linesperday.com/a-process-slightly-greater-than-the-natural-software-development-process-model/#comments Sun, 18 Jun 2017 08:16:09 +0000 http://www.linesperday.com/?p=250 The goal of this post is to discuss a simple software development process model. Hmmm let’s see. A simple software development process. There are many software development process models.

And

I will be discussing the difference between agile processes and waterfall Process….

Naaaah! Not that old crap. Yeah I know agile/iterative is good and waterfall is baaaaaaad.

We all know that nobody is using waterfall process model anymore. Indeed, no one is using any process model at all. Everyone is using the natural software development process model.

And that is you got the task and you have to write code. This is the natural model. There could be exceptions-maybe large organizations use process model- but they are EXECPTIONS.

The only place I have used software development process is in my university class and that was for completing my assignment. Writing the pros and cons of different software process models was a task during my undergrad studies.

So what is the point of writing this article?

Well, let me admit one thing. There are a few good things that I have adopted from all the process models that I have studied.

I have applied these things personally in my projects and yes they are helpful. They are helpful if you are having a very small team. Or you are developing a software just by yourself.

These things will aid you in programming. Help you understand the benefits of object oriented design.

This will help you when you are sitting in an interview sharing your practical experiences of applying good software development life cycle practices in front of your interviewer.

There you will not sound like a fresh graduate who has studied process model in their class only.

So,

What is a simple process?

I will lay out a process that will focus object oriented design.

Here are the steps:

1)Requirements, 2) Design, 3) code ,4) test ,5) deliver

Pretty much like the BAD WATERFALL process model. Well, pretty much every process model has these steps. What makes them distinct — The Best Practices. Every process model has these steps and a set of best practices.

Rational Unified Process(RUP) model has different best practices. One best practice is that it does not consider above steps as something separate. In each iteration, all things are done in different proportion.

During the initial iterations of RUP, we do a lot of requirement gathering, some designing, a little bit of coding, a little bit of testing and so on.

At the end of RUP, we do a lot of coding and testing and a little bit of requirements gathering and designing.

Similarly, Extreme Programming process methodology offers some unique best practices which are a different than SCRUM.

Haaaah. It looks like I am writing my university assignment. But I believe you got the point.

So I will share 1 or two best practices for each step with respect to object-oriented analysis and design.

Why object-oriented analysis and design. Well, the obvious reason is that top programming languages in use are object-oriented programming languages.

But let me explain one key benefit OOP with respect to process model:

Overlapping of Real World and Engineering World

Object-oriented analysis and design(OOAD) methodology will provide a platform where you can connect the engineering world with the real world.

This is like programming the real world scenarios in a way that anybody would describe them using their own language. For example, consider the following code listing:

aUser = MyGame.RegisterUser()

aUser.Play();

aUser.CheckIfWinOrLose();

MyGame.GiveReward();

MyGame.UregisterUser();

This is the source code of a simple game. This is how anyone would describe how a game would be played in plain English. I have compiled a free report that shows a real life and detail example here.

Using OOAD you can design your code right from the description of real world scenarios.

Now, let’s move to the first step of simple software development process model.

Requirements Gathering

As you know object oriented technology bridge the gap between real life and programming world.

So, when developing a software you will have to start from the real life and then ease into the programming world.

The best way to describe our real world is using stories. There are stories all around us. Hence the best way to gather requirements is to get stories from users about their problems.

There is an advanced form or more detailed form of a story and that is called use cases. Use-case is like a novel. Here you have to define roles and their interaction.

Now, from the text of stories, you have to bring out names of the classes. Mostly nouns will be the name of the classes.

Design

Now from user stories you have got classes. Currently, they are just names. You don’t know what they do. How to they interact and how will you write code for them.

In addition to that, not everything is in the user story. There are things which are implied. Or your user may have used other names for that. For example, your user may have said I want to store the record and have some reports.

You know what the user is talking about. The user is talking about the database. So you will have to include classes related to that functionality.

O.k. Next step in designing is the interaction of classes. You know, in reality, classes don’t exist. Only objects exist. They exist in a secret place called RAM.

So the next step is to define the interaction of these objects. Questions like who will have what information. Who will create this object? How will all of these objects work together to fulfill one user story?

You can design this interaction yourself or you can look up to the good practices of old developers. These good practices are called design patterns.

Do I follow all this?

Hmmm, NOPES. Not all things. Sometimes I just start writing code. Sometimes I just bring out the code from my personal repository or from some other project and start developing from there.

The idea is simple– follow as much as you can. There is no restriction. Software design is mostly heuristic. It all depends upon you and you get better by designing more and more.

Construction

The only part that matters. This should consume the major part of your development effort.

The construction or coding is not a linear activity. It’s not like after the development of design you just have to code it and then run it.

This is the part where you have to think. Think a lot. Solve a lot of problems. Learn a lot. And the outcome is a beautiful software.

One suggestion is design for testability. Write a code module in a way that is easier to test.

I am not going to beat the drum about “TEST FIRST DEVELOPMENT”. But writing you code in this manner will help you in debugging. Which is an integral part of software development 🙂

Testing

This could be a professional level testing. White box and black box and [insert any sophisticated term here].

This could be a functional test with a customer. Or a performance test. Or a UI/UX test. Or a deployment test.

After development, testing and deployment are the two most effort consuming activities.

Deliver and Repeat

Iterative development is one attribute of software development. Each iteration main focus point should be a user story. Each iteration should complete one user story. And test that with the end user and then move onto the next story.

That is the whole point for which the waterfall model is frowned upon. In waterfall, there was no way that one can find out if they are on the right track. There was no customer integration within the development process.

Each iteration also gives you the opportunity to refine and improve your object oriented design. In initial iterations, you can focus on providing the functionality(or use GRASP). In later iterations, you can refine your object oriented design by refactoring and utilizing design patterns.

So what process do you follow in your organization? Is there any critical step that you think should be part of this simple process[please don’t tell me to include documentation– I hate it ].

Write them in comments or email me.

]]>
https://www.linesperday.com/a-process-slightly-greater-than-the-natural-software-development-process-model/feed/ 1
You hate comments? Kill Them (Period) https://www.linesperday.com/you-hate-comments-kill-them-period/ Fri, 24 Mar 2017 15:08:27 +0000 http://www.linesperday.com/?p=155 A while ago, I was searching about comments. Specifically, strategies to comment better. I found the following example:

//
// Dear maintainer:
// Once you are done trying to 'optimize' this routine,
// and have realized what a terrible mistake that was,
// please increment the following counter as a warning
// to the next guy:
//
// total_hours_wasted_here = 42
//

 

LOL.

Who writes comments like that?

Here is another one:

// somedev1 - 6/7/02 Adding temporary tracking of Login screen

// somedev2 - 5/22/07 Temporary my a**

And so on.

You will find funny comments when you try to search for how to write effective code comments.

The reason I was searching about writing comments better is that I hate comments. Initially, I believed that everybody loves writing comments in their code. In my research, I found that many developers hated comments. Hence, I am not alone.

Why We hate comments?

We hate comments because comments are boring. I know one time our team was given a task to add comments to an existing project. Each team members have to read the comments written by another teammate and give suggestions.

It was so boring that nobody read comments written by their teammates.You can argue that it’s the laziness of the team. But developers in the team understand the importance of code comments.

So why our team hated this commenting task?

The culprit was the dedicated task of writing comments to an existing code. Writing comments on the fly is easy. Compare writing comments for a completed project vs writing comments as you code.

Writing comments to an existing project is like documentation and developers hate any kind of documentation.

On the other hand, writing comments on the fly is easy and sometimes addiction. For example, one developer even commented the following line of code:

// Saving customer to database

aCustomer.Save();

Therefore, we like to write comments when we are writing code.Some people talk when they are writing comments- I know this because I sometimes talk when I code.

Another reason we hate comments is that we have to manage them. For example, you have written comments for some lines of code and the next day you change the code. But you forgot to change the related comments.

Keep doing this for 2 months and one day you will find that there are so many unrelated words written by aliens.

So we have to manage comments in addition to code. Therefore we hate writing comments.

Benefits of comments

We all know comments are good. Our bosses are kept telling us to write comments. So that they can fire us someday and hire someone else to do the job. Comments will make that transition easy!

Because the new hire would read the code — and understands the code magically with the help of comments and they will live happily after.

This reminds me of another funny comment:

//When I wrote this, only God and I understood what I was doing

//Now, God only knows

Jokes apart, commenting code is beneficial for the reader of your code. This reader can be you — in distant future.

You can use comments to warn others. While reading code, it looks like that you can follow a straight and obvious approach. So there is a temptation to change the code from complex to simple. This is often wrong.

Another benefit of using comments is: It helps you while refactoring. Refactoring is a process to improve the quality of your code. When you see too many comments around a code listing. It’s good hint for you to refactor that piece of code.

So you wanted to write comments that are helpful. You want to write good comments because you wanted to understand the piece of code that you have written 5 years ago.

Or, you want to give your code to someone else and don’t want that guy to bother you every 10 minutes.

I found the following guidelines helpful. This will helped you write minimum and effective comments for code even if you hate comments.

How I write comments?

The key idea here is to write minimum and effective comments.

I divide comments into two categories. Head comments and inline comments. Head comments that you write before creating a class or creating a function. Head comment define the reason for the creation of that class or function. Head comments can be described as big picture comments.

I use head comments frequently. Because head comments are helpful for getting the overall picture of the code.

I also write head comments to warn the other guy (or yourselves in future). In future, somebody will try to optimize your code because he or she think that there is a simpler way to write your code.

effective comments

You know that obvious way. You have tested it and you have gone through the pain. You just know that the obvious way does not work. Hence you give the warning to the smarty-pants.

You can also use head comments to explain your reasons. Why you choose that particular strategy and not the other.

Inline comments are those you write to elaborate the code listing. This is the place where you can write spaghetti comments.

What can you do to minimize inline comments? Answer: Write good code.

Quote:

”Dont comment bad code – rewrite it” —Brian W. Kernighan and P. J. Plaugher

It means re-structure your code by assigning a proper and sensible name to code modules: variables, functions, and classes.

How can you assign a sensible to name to a function or variable?

One approach that I used is object oriented analysis and design (OOAD).If you are using an object oriented programming like java or C# you can use object oriented analysis approach to assigning good names to code modules.

Object oriented analysis and design help you to model the real world. This is also called the domain for which you are writing the software. For example, in a banking software, you can have classes like Account, Ledger and etc. Using this concept you can assign names that are close to real world names.

When you assign real names to variables, functions, and classes then it is easier to work with the code. The code will be like reading a standard operating procedure(SOP).

For example, consider the following code

Record rcd = new Record();

rec.Verify();

rec.store();

Vs

Customer aCustomer = new Customer();

aCustomer.VerifyPersonalData();

aCustomer.Save();

Moreover, using OOAD you can work at a higher level of abstraction. Working at a higher level of abstraction makes it easier for a developer to understand the general flow of the code. Consider the following code:

NetworkDevice: IDevice
USBDevice:IDevice
Interface IDevice{
Public byte[] read();
}

In my main code, I have this line

device.Read();

Here, I am working at a higher layer of abstraction and I don’t care about the specifics. In the example above, I don’t know which device will be called ultimately. Hence, I move on to next line of code. If I want to drill down I can go the implementation of the device I am interested in.

Hence, OOAD enables you to write at the higher level of abstraction and this will lower the complexity of reading the code.

The idea of OOAD is that you write code in such a way that comments become redundant. Hence using the real world naming convention and writing code at the higher level of abstraction minimize the number of comments.

These strategies helped me write minimum and effective comments. What strategies have you used to write better comments?

]]>
S.O.L.I.D, GRASP And Other Basic Principles of Object Oriented Design https://www.linesperday.com/s-o-l-i-d-grasp-and-other-basic-principles-of-object-oriented-design/ https://www.linesperday.com/s-o-l-i-d-grasp-and-other-basic-principles-of-object-oriented-design/#comments Tue, 17 Jan 2017 14:35:29 +0000 http://www.linesperday.com/?p=16 I will start with a cliché

A software code should depict following qualities:

  1. Maintainability
  2. Extensibility
  3. Modularity
  4. etc

You may find yourself in a difficult situation when you ask a question about whether any particular code depicts above quality features or not.

A technique that helps is by looking at the development timeline of any software. If the software code remains easier to maintain, extend and modular over its lifetime then it means that the code has above quality features.

I have written difficult to read, hard to extend and rotten software code. I only knew this after six months into the development when a change happens. Hence development timeline is important in understanding quality factors.

But this technique (looking at the timeline of development) can only be applied by looking into the past but we want a quality software somewhere in future.

Senior developers, who know about quality, don’t have this problem. They feel proud when they see their code has the quality factors which junior developers only dream about.

Hence senior developers and experts have distilled down a set of principles which junior developers can apply to write a good quality code and to show off in front of other developers :). If you want to write your principles then here is a guide to extract principles from your own experience.

In this post, I will cover SOLID principles. These principles are given by uncle bob(Robert C. Martin). I will also cover GRASP (General Responsibility Assignment software Principles) published by Craig Larman and other basic object oriented design principles. I have included examples from my personal experience, therefore you will not find any ‘Animal’ or  ‘Duck’ examples.

The code examples shown are closer to java and C# but they are helpful to any developer who knows the basics of object oriented programming.

Here is the complete list of principles covered in this post:

  1. Single Responsibility Principle (SOLID)
  2. High Cohesion (GRASP)
  3. Low Coupling (GRASP)
  4. Open Closed Principle (SOLID)
  5. Liskov Substitution principle (SOLID)
  6. Interface Segregation Principle (SOLID)
  7. Dependency Inversion Principle (SOLID)
  8. Program to an Interface, not to an Implementation
  9. Hollywood Principle
  10. Polymorphism (GRASP)
  11. Information Expert (GRASP)
  12. Creator (GRASP)
  13. Pure Fabrication (GRASP)
  14. Controller (GRASP)
  15. Favor composition over inheritance
  16. Indirection (GRASP)

This looks like a huge list of principles(I will add more in the coming days!). You know, one mistake that I made during my early career is that I tried to apply all the principles at one time. That was a big mistake.

I don’t want you to do that. I have designed a process (a very simple) where you can apply basic design skills and then build upon from there. I compile that process in a free report which you can get by subscribing to our email list. Just put in your name and email address and I will send you the report.

Here is the link to report.

 

Single Responsibility principle

SRP says:

A class should have only one responsibility.

A class fulfills its responsibilities using its functions or contracts( and data members help functions).

Take the following example class:

Class Simulation{
	Public LoadSimulationFile()
	Public Simulate()
	Public ConvertParams()
}

This class handles two responsibilities. First, this class is loading simulation data and second, it is performing the simulation algorithm(using Simulate and ConvertParams functions).

A class fulfills a responsibility using one or more than one function. In the example above loading simulation data is one responsibility and performing simulation is another responsibility. One function is needed to load simulation data (i.e LoadSimulationFile). Remaining two functions are needed to perform the simulation.

How do we know how many responsibilities my class has? Consider the phrase “reason to change”  analogous to responsibility. Hence look for all the reasons a class has to change. If there is more than one reason to change a class then it means this class does not follow the single responsibility principle.

In our example class above this class should not contain LoadSimulationFile function( or loading simulation data responsibility). If we create a separate class for loading simulation data then this class will not violate SRP.

A class can only have a single responsibility. How would you design a software with such a hard rule?

Let’s consider another principle which is closely related to SRP and it is called High Cohesion. High cohesion gives you a subjective scale and not an objective one as in the case of SRP.

Very low cohesion means a class is fulfilling many responsibilities. For example, there are more than 10 responsibilities for which a class is responsible.

Low Cohesion means a class is fulfilling around 5 responsibilities and moderate cohesion means a class fulfilling 3 responsibilities. High Cohesion means a class is fulfilling a single responsibility.

Hence the rule of thumb is while designing strive for high cohesion.

Another principle which should be discussed here is Low Coupling. This principle states that one should assign a responsibility so that the dependency between the classes remains low.

Again consider the above example class. After applying SRP and high cohesion principle we have decided to make a separate class which will handle simulation files. In this way, we have created two classes which are dependent on each other.

It looks like that applying high cohesion causing us to violate another principle which is low coupling. This level of coupling is allowed as the goal is to minimize the coupling not zeroing the coupling. Some degree of coupling is normal to create an object-oriented design in which tasks are completed by a collaboration of objects.

On the other hand, consider a GUI class which connects to a database, handles remote clients over HTTP and handles screen layout. This GUI class is dependent upon too many classes. This GUI class clearly violates the low-coupling principle. This class cannot be re-used without involving all the related classes. Any change to database component cause changes to GUI class.

Open-Closed Principle

Open-Closed principles says:

A software module (it can be a class or method ) should be open for extension but closed for modification.

In simple words, you cannot update the code that you have already written for a project but you can add new code to the project.

There are two methods through which you can apply the open-closed principle. You can apply this principle either through inheritance or through composition.

Here is the example of applying open-close principle using inheritance:

Class DataStream{
	Public byte[] Read()
}	

Class NetworkDataStream:DataStream{
	Public byte[] Read(){
	//Read from the network
 }
}

Class Client {
	Public void ReadData(DataStream ds){
		ds.Read();
 }
}

In this example, the client read data (ds.Read()) from the network stream. If I want to extend the functionality of client class to read data from another stream, e.g PCI data stream, then I will add another subclass of DataStream class as shown in the listing below:

Class PCIDataStream:DataStream{

	Publc byte[] Read(){
	//Read data from PCI
 }
}

In this scenario, the client code will function without any error. Client class knows about the base class and I can pass an object of any of the two subclasses of DataStream. In this way, the client can read data without knowing the underlying subclass. This is achieved without modifying any existing code.

We can apply this principle using composition and there are other methods and design patterns to apply this principle. Some of these methods will be discussed in this post.

Do we have to apply this principle to every piece of code that you write? The answer is no. This is because most of that code will not change. You will have to apply this principle strategically in those conditions where you suspect a piece of code will change in the future.

In the previous example, I know from experience of my domain that there will be more than one stream. Therefore, I apply open-closed principle so that it can handle future changes without modification.

Liskov substitution principle

LSP says:

Derived classes must be substitutable for their base classes.

Another way to look at this definition is that abstraction(interface or abstract class) should be enough for a client.

To elaborate let’s consider an example, here is an interface whose listing is given below:

Public Interface IDevice{
	Void Open();
	Void Read();
	Void Close();
}

This code represents data acquisition device abstraction. A data acquisition device differentiates based upon its interface type. A data acquisition device can use USB interface, Network Interface(TCP or UDP), PCI express interface or any other computer interface.

Clients of IDevice does not need to know what kind of device they are working with. This gives programmer enormous flexibility to adapt to new devices without changing the code which depends upon the IDevice interface.

Let’s go into a little history when there were only two concrete classes that implemented IDevice interface shown below:

public class PCIDevice:IDevice {
   public void Open(){
   // Device specific opening logic
   }
   public void Read(){
   // Reading logic specific to this device
   }
   public void Close(){
   // Device specific closing logic.
   }


}

public class NetWorkDevice:IDevice{

 public void Open(){
 // Device specific opening logic
 }
 public void Read(){
 // Reading logic specific to this device
 }
 public void Close(){
 // Device specific closing logic.
 }


}

These three methods(open, read and close) are sufficient to handle data from these devices. Later, there was a requirement to add another data acquisition device which was based upon USB Interface.

The problem with USB Device was that when you open the connection, data from the previous connection remains in the buffer. Therefore upon the first read call to the USB device data from the previous session returned. That behavior corrupted data for that particular acquisition session.

Fortunately, USB based device driver provides a refresh function which clears the buffers in the USB based acquisition device. How can I implement this feature into my code so that code change remains minimal?

One naive solution is to update the code by identifying if you are calling the USB object:

public class USBDevice:IDevice{
 public void Open(){
    // Device specific opening logic
 }
 public void Read(){
    // Reading logic specific to this device<br> 
 }
public void Close(){
   // Device specific closing logic.
 }
 public void Refresh(){
   // specific only to USB interface Device
 }
}

//Client code..

Public void Acquire(IDevice aDevice){
        aDevice.Open();
        // Identify if the object passed here is USBDevice class Object.    
	if(aDevice.GetType() == typeof(USBDevice)){
	USBDevice aUsbDevice = (USBDevice) aDevice;
	aUsbDevice.Refresh();
	}

        // remaining code….
}

In this solution, client code is directly using the concrete class as well as the interface (or abstraction). It means abstraction is not enough for the client to fulfill its responsibilities.

Another way to state the same thing, the base class cannot fulfill the required behavior (refresh behavior) but the derived class has this behavior. Hence derived class is not compatible with the base class and therefore derived class cannot be substituted. Hence this solution violates Liskov Substitution Principle.

In the example above, the client is dependent upon more entities (IDevice and USBDevice) and any change in one entity will cause a change in other entities.  Therefore violation of LSP causes dependency between the classes.

A Solution to this problem that follows LSP? I updated the Interface in this way:

Public Interface IDevice{
	Void Open();
	Void Refresh();
	Void Read();
	Void Close();

}

Now the client of IDevice is:

Public void Acquire(IDevice aDevice)
	{
	aDevice.open();
	aDevice.refresh();
	aDevice.acquire()
	//Remaining code..

}

Now client does not depend upon the concrete implementation of IDevice. Hence in this solution, our interface(IDevice) is enough for the client.

There is another angle to look at the LSP principle within the context of object oriented analysis. To get an introduction of object oriented Analysis get this free report. In summary, during OOA we think about the classes and their hierarchies that could be part of our software.

When we are thinking about the classes and hierarchies we can come up with classes which violate LSP.

Let’s consider the classic example of rectangle and square which is misquoted many times. When looking from the outset it looks like that square is a specialized version of the rectangle and a happy designer would draw the following inheritance hierarchy.

Public class Rectangle{
	Public void SetWidth(int width){}
	Public void SetHeight(int height){}
}

Public Class Square:Rectangle{
//
	
}

What happens next is you cannot substitute square object in place of rectangle object. Since Square inherits from Rectangle, therefore, it inherits its method setWidth() and setHeight(). A client of Square object can change its width and height to different dimensions. But width and height of a square are always identical hence failing the normal behavior of the software.

This can only be avoided by looking at classes according to different usage scenarios and conditions. Therefore when you are designing classes in isolation there is a probability that your assumptions may fail. As in the case of Square and Rectangle, is-a relationship looks good enough during initial analysis but as we look at different conditions this is-a relationship failed the correct behavior of the software.

Interface Segregation Principle

Interface Segregation Principle (ISP) says:

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

Again consider the previous example:

Public Interface IDevice{
	Void Open();
	Void Read();
	Void Close();
}

There are three classes that implement this interface. USBDevice, NetworkDevice, and PCIDevice. This interface is good enough to work with network and PCI devices. But USB device needs another function(Refresh()) to work properly.

Similar to USB device, in future, there can another device which may require refresh function to work properly. Due to this IDevice is updated as shown below:

 Public Interface IDevice{
	Void Open();
        Void Refresh();
	Void Read();
	Void Close();
}

The problem is now each class that implement IDevice has to provide the definition for the refresh function.

For example, I have to add the following lines of code to NetworkDevice class and PCIDevice class to work with this design:

public  void Refresh()
{
// Yes nothing here… just a useless blank function
}

Hence IDevice represents a fat interface(too many functions). This design violates the Interface Segregation Principle because the fat interface is causing unnecessary clients to depend upon it.

There are numerous ways to solve this problem but I will tackle this problem using my domain specific knowledge.

I know that refresh is directly called after the open function. Hence I moved the logic of refresh from the client of IDevice to the specific concrete class. In our case I moved the call to refresh logic to USBDevice class as shown here:

Public Interface IDevice{
		Void Open();
		Void Read();
		Void Close();
}	


Public class USBDevice:IDevice{
	Public void Open{
	// open the device here…

	// refresh the device
	this.Refresh();
	
 }
Private void Refresh(){
	// make the USb Device Refresh
 }

}

In this way, I have reduced the number of functions in the IDevice class and make it less fat.

Dependency Inversion Principle

This principle is a generalization of other principles. Principles discussed above, LSP and OCP, substitutes dependency inversion principle.

Before jumping to the textbook definition of DIP let me introduce a closely related principle which will help understand DIP.

The principle is:

“Program to an interface, not to an implementation”

This is quite a simple one. Consider the following example:

Class PCIDevice{
	Void open(){}
	Void close(){}
}
Static void Main(){
	PCIDevice aDevice = new PCIDevice();
	aDevice.open();
	//do some work
	aDevice.close();
	
}

Above example violates the “Program to an interface principle” because we are working with the reference of concrete class PCIDevice. Following listing follows this principle:

Interface IDevice{
	Void open();
	Void close();	
}
Class PCIDevice implements IDevice{
	Void open(){ // PCI device opening code }
	Void close(){ // PCI Device closing code }
}
Static void Main(){
	IDevice aDevice = new PCIDevice();
	aDevice.open();
	//do some work
	aDevice.close();	
}

Hence it’s very easy to follow this principle. Dependency inversion principle is similar to this principle but DIP asks us to do one more step.

DIP says:

High-level modules should not depend upon low-level modules. Both should Depend upon abstractions.

You can easily understand the line “Both should depend upon abstractions” as it is saying each module should program to an interface. But what are high-level modules and low-level modules?

To understand the first part we have to learn what are high-level modules and low-level modules?

See the following code:

Class TransferManager{
	public void TransferData(USBExternalDevice usbExternalDeviceObj,SSDDrive  ssdDriveObj){
            Byte[] dataBytes = usbExternalDeviceObj.readData();

           // work on dataBytes e.g compress, encrypt etc..

            ssdDriveObj.WrtieData(dataBytes);		
        }
}

Class USBExternalDevice{
	Public byte[] readData(){
        }
}

Class SSDDrive{
	Public void WriteData(byte[] data){
	}
}

In this code,  there are three classes. TransferManager class represent a high-level module. This is because it is using two classes in its one function. Hence other two classes are low-level modules.

High-level module function(TransferData) defines logic how data transferred from one device to another device. Any module which is controlling the logic, and uses the low-level modules in doing so, is called the high-level module.

In the code above high-level module is directly(without any abstraction) using the lower level modules hence violating dependency inversion principle.

Violation of this principle causes the software difficult to change. For example, if you want to add other external devices you will have to change the higher level module. Hence your higher level module will be dependent upon the lower level module and that dependency will make the code difficult to change.

The solution is easy if you understand the principle above “program to an interface”. Here is the listing:

Class USBExternalDevice implements IExternalDevice{
	Public byte[] readData(){
	}
}

Class SSDDrive implements IInternalDevice{
	Public void WriteData(byte[] data){
	}
}

Class TransferManager implements ITransferManager{
	public void Transfer(IExternalDevice externalDeviceObj, IInternalDevice internalDeviceObj){
           Byte[] dataBytes = externalDeviceObj.readData();

           // work on dataBytes e.g compress, encrypt etc..

           internalDeviceObj.WrtieData(dataBytes);		
        }
}

Interface IExternalDevice{
        Public byte[] readData();
}

Interfce IInternalDevice{
	Public void WriteData(byte[] data);
}

Interface ITransferManager {
	public void Transfer(IExternalDevice usbExternalDeviceObj,SSDDrive  IInternalDevice);
}

In the code above high-level module and low-level modules, both depend upon abstractions. This code follows Dependency Inversion Principle.

Hollywood Principle

This principle is similar to the dependency inversion principle. This principle says

Don’t call us, we will call you

This means a high-level component can dictate low-level components(or call them) in a manner that they are not dependent on each other.

This principle defends against dependency rot. Dependency rot happens when each component depends upon every other component.In other words, dependency rot is when dependency happens in each direction(Up, sideways, downward). Hollywood Principle restricts us to make dependency in only one direction.

The difference with dependency inversion principle is that DIP gives us a general guideline “Both higher level and lower component should depend upon abstractions and not on concrete classes”. On the other hand, Hollywood Principle specifies how higher level component and lower level component interact without creating dependencies.

If you want to learn more about object oriented programming then visit here.

Polymorphism

What–Polymorphism is a design principle? But we have learned that polymorphism is a basic feature of an object oriented programming.

Yes, it’s the basic requirement for any oop language to provide polymorphism feature where derived classes can be referenced through parent classes.

It’s also a design principle in GRASP. This principle provides guidelines about how to use this oop language feature in your object oriented design.

This principle restricts the use of run-time type identification(RTTI). We implement RTTI in C# in the following manner:

if(aDevice.GetType() == typeof(USBDevice)){

	//This type is of USBDEvice
}

In java, RTTI is accomplished using the function getClass() or instanceOf() .

if(aDevice.getClass() == USBDevice.class){
    // Implement USBDevice
     Byte[] data = USBDeviceObj.ReadUART32();
}

If you have written this type code in your project then now is the time to refactor that code and improve it using the polymorphism principle.

Look at the following diagram:

polymorphism diagram

Here I have generalized the read method in the interface and delegate the device specific implementation to their classes(e.g ReadUART32() in USBDevice).

Now I just use the method read.

//RefactoreCode
IDevice aDevice = dm.getDeviceObject();
aDevice.Read();

Where will be the implementation of getDeviceObject() come from? This we will discuss in the Creator principle and Information Expert principle where you will learn about assigning the responsibilities to classes.

Information Expert

This is a simple GRASP principle and gives guidelines about giving responsibilities to classes.

It says assign a responsibility to the class which has the information necessary to fulfill that responsibility.

Consider the following classes:

Information Expert

In our scenario simulation is performed at full speed(600 loops per second) whereas user display is updated at reduced speed. Here I have to assign a responsibility to whether to display the next frame or not.

Which class should handle this responsibility? I have two option either the simulation class or SpeedControl class.

Now SpeedControl class has the information about which frames has been displayed in the current sequence therefore according to the information expert SpeedControl should have this responsibility.

Creator

Creator is a GRASP principle and helps in deciding which class should be responsible for creating a new instance of a class.

Object creation is an important process and it is useful to have a principle in deciding who should create an instance of a class.

According to Larman, a class “B” should be given the responsibility to create another class “A” if any of the following conditions are true.

a) B contains A
b) B aggregates A
c) B has the initializing data for A
d) B records A
e) B closely uses A

In our example of polymorphism I have used Information Expert and Creator principles to give DeviceManager class the responsibility to create a Device object(dm.getDeviceObject()). This is because DeviceManger has the information to create a Device object.

Pure Fabrication

In order to understand Pure Fabrication, a pre-requisite is that you understand object oriented analysis(OOA).

In summary, object oriented analysis is a process through which you can identify the classes in your problem domain. For example, domain model for a banking system contains classes like Account, Branch, Cash, Check, Transaction and etc. To learn more about object oriented analysis please visit here.

In the banking example, domain classes need to store information about the customers. In order to do that one option is to delegate data storage responsibility to domain classes. This option will reduce the cohesiveness of the domain classes(more than one responsibility). Ultimately, this option violates the SRP principle.

Another option is to introduce another class which does not represent any domain concept. In the banking example, we can introduce a class “PersistenceProvider”. This class does not represent any domain entity. The purpose of this class is to handle data storage functions. Therefore “PersistenceProvider” is a pure fabrication.

Controller

When I started development I write most of the program using Java’s swing components and I write most of my logic behind listeners.

Then I learned about domain model. Hence I moved my logic from listeners to Domain model. But I directly called the domain objects from listeners. This creates a dependency between the GUI components (listeners) domain model. Controller design principle helped in minimizing the dependency between GUI components and Domain Model classes.

There are two purposes of Controller. The first purpose of Controller is to encapsulate a system operation. A system operation is something that your user want to achieve e.g buying a product or entering an item into the cart. This system operation is then accomplished by calling one or more method calls between the software objects.The second purpose of Controller is to provide a layer between UI and Domain Model.

A UI enables users to perform system operations. A controller is the first object after the UI layer that handles the system operations request and then delegates the responsibility to the underlying domain objects.

For example, here is MAP Class which represent a Controller in one of our software code.

controller

From the UI we delegate the responsibility of “moving cursor” to this controller and then this calls the underlying domain objects to move the cursor.

By using the Controller principle you will have the flexibility to plug in another user interface like command line interface or web interface.

Favor composition over inheritance

Primarily there are two tools in object oriented programming to extend the functionality of existing code. The first one is inheritance.

The second method is composition. In programming words, by having a reference to another object you can extend that object’s functionality. If using composition, add a new class create its object and then use that object using its reference where you want to extend the code.

A very helpful feature of the composition is that behavior can be set at run-time. On the other hand, using inheritance you can only set the behavior at compile time. This will be shown in the example below.

When I was a newbie and used inheritance to extend the behavior, these are the classes that I designed:

composition vs inheritance

 

Initially, I only know about the processing an incoming stream of data and there were two kinds(Stream A and Stream B) of data. After a few weeks, I came to know that endianness of the data should be handled. Hence I come up with a class design shown below:

composition vs inheritance

Later on, another variable was added to the requirements. This time I have to handle the polarity of the data. Imagine how many classes I have to add? Two types of polarity for stream A, streamB, Stream with endianness and so on. A class explosion! Now I will have to maintain a large number of classes.

Now, If I handle the same problem using composition following will be the class design:

composition vs inheritance

I add new classes and then use them in my code using their references, see the listing below:

clientData.setPolarity(new PolarityOfTypeA); // or clientData.setPolarity(new PolarityOfTypeB)
clientData.FormatPolarity;

clientData.setEndianness(new LittleEndiannes());// setting the behavior at run-time
clientData.FormatStream();

Hence I can provide the instances of the classes according to the behavior that I want. This feature reduced the total number of classes and ultimately maintainability issues. Hence favoring composition over inheritance will reduce maintainability problems and flexibility to set behavior at run-time.

Indirection

This principle answer one question:

How to let objects interact in a manner that the bond among them remain weak?

The solution is:

Give the responsibility of interaction to an intermediate object so that the coupling among different components remain low.

For example:

A software application works with different configuration and options. To decouple the domain code from the configuration a specific class is added shown in the following listing:

Public Configuration{
  public int GetFrameLength(){
    // implementation
  }
  public string GetNextFileName(){

  }
 // Remaining configuration methods
}

In this way, if any domain object wants to read a certain configuration setting it will ask the Configuration class object. Therefore, main code is decoupled from the configuration code.

If you have read the Pure Fabrication Principle this Configuration class is an example of pure fabrication. But the purpose of indirection is to create de-coupling. On the other hand, the purpose of pure fabrication is to keep the domain model clean and represent only domain concept and responsibilities.

Many software design patterns like Adapter, Facade and observer are specializations of Indirection principle.

This is it up to now. I will add more principles soon.

Over to you

Tell me in the comments, what you like in this post and what are your biggest challenges while learning and applying object oriented design principles. If you want to learn more about object oriented programming then visit here.

]]>
https://www.linesperday.com/s-o-l-i-d-grasp-and-other-basic-principles-of-object-oriented-design/feed/ 7