Object Oriented Design http://www.objectorienteddesign.org Object Oriented Design Thu, 21 Jun 2018 07:21:18 +0000 en-US hourly 1 https://wordpress.org/?v=4.7.27 115788848 Why People are Successful in Their Jobs When They Failed as Students http://www.objectorienteddesign.org/why-people-are-successful-in-their-jobs-when-they-failed-as-students/ Thu, 10 Aug 2017 06:42:31 +0000 http://www.objectorienteddesign.org/?p=294 We all have tried something before and it did not work out. Like trying to cliff jumping into the ocean.

Once I decided to take the steepest and a long water slide. The moment I reach the top and look down- I was scared. Everybody was looking so small on the ground.

The water was flowing with speed at the edge of the slide.

The air was breezing through and I believe the sun was shining with additional power. I just sit there and think about it and then I aborted.

Months later I tried again and did it– finally. But you know, the experience was thrilling. The ride was worth the pain.

Similarly, I tried learning a course during my undergrad studies and I failed.

It could be possible that the instructor was not good enough. Or the course was boring or that particular subject was not my thing.

For example, I tried learning two courses numerical computing and object oriented design. And let’s say I didn’t grasp the concepts.

But, I successfully learned these two courses after graduation and during my job. Recently I was reflecting why this happens?

There are some courses that we all have tried in our college/university life but we failed there and now we know a lot better about them.

So, in this post, I will analyze why I was failed in university and succeeded afterward in real life and what steps you can take to rejuvenate your desire to learn old subject again.

1) Action is Louder Than Words

There are subjects which we don’t understand because we can’t see them in action. For example, one of my classmates once said to me during undergrad studies:

“I want to go into civil engineering, where we can see things like buildings, bridges and other huge things. Something that you can touch and feel. In software development, you just cannot do that”.

You can see that. A software or code is more of an abstract thing. Like mathematics. But once you are in the field you know how the code is written by you to solve real problems.

It brings in profit. Your code can move some hardware (if you are embedded software developer).

These real life results show the importance of the work that you do. And you like results. Due to this, your mind starts to grasp ideas and gives you an edge in learning. Hence once you see things in action you learn faster.

Therefore, the subject of numerical computing was very helpful when I solved a real world problem which involves curve fitting. It raises the importance of the subject and makes it easier for me to learn the subject.

2) You are not Under Stress, Right now

Ok everybody is under stress, mostly at our jobs. But during studies, you have a lot of things to care about. Like other subjects to cover during the semester. You are worried about assignments, exam, labs and other projects.

Our goal is different during undergrad studies. We want to appease our teachers :). We want to score well in the exams. That’s it. That’s our problem.

During studies, we don’t have to solve a real world problem. We have to get marks in our exam and if you didn’t perform no one is going to be affected except ‘YOU’.

But as a professional, there is no exam date. No multiple courses, no exams, and no teachers. Here your core goal is to solve the problem and until you don’t solve the problem the project will not be completed. So all of your time will be consumed on solving the problem.

Once you solve that problem, you will move to the next problem.

Hence you will be working on one problem a.k.a “the project”(ideally). Therefore you will have time and mental resources(since you are not distracted by 4 other subjects) to learn that subject which you tried before.

3) You had sub-par Resources

In universities, I believe you have subpar resources. I am not talking about you if you are from elite universities.

In colleges/universities, computers were slow. There were shared resources and labs. Schedules and timings that you had to follow.

Whereas as a developer in any organization you get super awesome resources. (this was not true for me– but it is true for the majority)

Second, an awful resource was the BOOKS recommended by our teachers. I am a big fan of books. They are ultimate resources- if you want to grow.

But there are bad books too.

Although there were some great books recommended by my teachers. But 80% of the books were very limited. Those were the books I believed written for academics only. The text was written in a super dull and boring way.

When I tried searching those books on the Amazon. Guess what I found “0” reviews. Bad comments and lower rating.

Hence I know that Amazon book rating system is authentic.

Here is a little tip for finding great books: A simple search “top books on XYZ subject” can yield the names of the best book on that subject and then there is the Amazon best selling category where you can search the books on the subject that you like.

Anyway, when I read great books on the subjects of programming, design or anything else that subject become fun to learn.

I wish that I knew about great books during my undergrad studies.

4) Experience is the Greatest Teacher

In real life experience teaches you a lot. For example, bit manipulation looked like a simple concept to the newbie Umair.

But when you really dive into the inner workings of understanding signed/unsigned numbers, 32-bit representation of integer, XOR and AND operation, and how the float is represented by IEEE 754 standard. Then you realize that bit-manipulation is an advanced topic and a lot of things can be done with that.

In real life, you commit mistakes. You see your software failing while saying to everybody that last time it worked fine and you don’t know what’s happening to it now. You are introduced to the term ‘intermittent error’.

So, your mistakes are your most valuable experience. You see things differently than your younger self and you know what is important in programming.

If you are experienced, watching your code organized properly will bring you the joy of your life.

If you are experienced, your code is written delicately with comments which are easier to read like a novel. Your code is beautifully divided into separate files and classes.

If you are experienced, it’s a pleasure to watch your web application adopting its layout across all platform and browsers.

These are the perks of having experience in the programming world.

So, if you tried learning before and it didn’t work out then one of the reason is that you didn’t experience an implementation headache, failures and hardship.

So do you really want to learn something go and implement that–now.

5) Now You Have Mentors

Mentors are very important if you want to learn. A mentor is different than a teacher. In my definition mentor is someone who has reached a certain point which is your destination.

You can have many mentors for different areas of your life.

In the programming world, a mentor is someone who has ahead of you in that field. Who has gone through the pain of being a newbie.

Where can you find a mentor? One thing is sure you will hardly find them in your college campus.

But you will find them in your workplace. Someone with experience in your technology. They can solve your problems in hours and can save you weeks.

So, if you want to improve your learning ask senior developers. Ask them via forums and online. Read their books and they will guide you in your journey.

Therefore, if you tried learning something before and failed then this time give your hands in the hands of your mentor and I believe this time you will be successful.

Your Ideas

So, what were your challenges when you tried learning something before and succeeded later in 2nd or 3rd attempt. Share your stories and ideas in the comments.

]]>
294
3 object oriented programming resources that can fail you–may be they already have http://www.objectorienteddesign.org/3-object-oriented-programming-resources-that-can-fail-you/ Wed, 26 Jul 2017 16:01:37 +0000 http://www.objectorienteddesign.org/?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

]]>
273
Get Serious About Your Programming Skills http://www.objectorienteddesign.org/get-serious-about-your-programming-skills/ http://www.objectorienteddesign.org/get-serious-about-your-programming-skills/#comments Fri, 21 Jul 2017 07:01:24 +0000 http://www.objectorienteddesign.org/?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.

]]>
http://www.objectorienteddesign.org/get-serious-about-your-programming-skills/feed/ 1 263
A Process Slightly Greater than the NATURAL Software Development Process Model http://www.objectorienteddesign.org/a-process-slightly-greater-than-the-natural-software-development-process-model/ http://www.objectorienteddesign.org/a-process-slightly-greater-than-the-natural-software-development-process-model/#comments Sun, 18 Jun 2017 08:16:09 +0000 http://www.objectorienteddesign.org/?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.

]]>
http://www.objectorienteddesign.org/a-process-slightly-greater-than-the-natural-software-development-process-model/feed/ 1 250
Object Oriented Design for Life http://www.objectorienteddesign.org/object-oriented-design-for-life/ http://www.objectorienteddesign.org/object-oriented-design-for-life/#comments Sun, 04 Jun 2017 09:48:08 +0000 http://www.objectorienteddesign.org/?p=239 One day I started running with my friend. No prior planning. No management. We just arrived from office and my friend ask “do you want to go for exercise?” I said yes. Then my friend says come on let’s run.

Without any second thought, I changed dress and started running with him. We were desperate and we push our limits on the first day. We were breathing heavily. We ran about 4 miles.

There was severe pain in my legs but we were motivated so we did not care.

Object Oriented Design

Next day the motivation was gone and It’s gone for long. We never went for exercise even after months.

Do you have this kind of experience? You have started something out of desperation and then after some time leave it.

For example:

You started reading books and leave it after 1 or 2 weeks!

Or

You started dieting and didn’t bother to think about it again after one party with friends!

So why we do it- why we start something and then leave it?

This is because somewhere in our conscious mind we are thinking about our health. All of us know that exercise is good for health and we should do this. But we don’t have the time (put any other excuse here).

We learned about these healthy habits from the news or from articles. We thought in our mind that we should try these. But we never do. So these things all add up and one day they outbreak.

Psychologists called that emotional wave. We were on an emotional ride when we started running. One problem with the emotional ride is that they declined after some time. And we fall back to our old routines.

You can feel other emotional waves as well. For example, eating healthy food, wake up early, not waste your time on social media, TV, movies and etc.

As a programmer, you may experience emotional waves. For example, you want to gain experience in another technology and therefore you started a personal learning project and never finish that.

Another emotional wave for programmers is that they want to make good object oriented designs. Often I had these emotional waves but like running I could not keep up.

So in this post, I will discuss what you can do to keep up using object-oriented design(OOD) methodology and not fall victim to emotional wave.

What is stopping you?

OOD is an important skill to learn. Once you are good at it, learning frameworks will be easier. Writing maintainable code will be easy. You will feel proud of yourself.

Learning OOD as a skill will certainly lead you to the club of elite software developers.

You want to recognize yourself as someone who knows about object oriented designs. You want to see yourself in the design role.

Ok. Ok. Ok. We all know the benefits of OOD then what is stopping us? There are two kinds of factors: internal and external.

External Resisting Factors

The first external factor is your boss. Your boss does not understand OOAD. Especially if your boss is non-technical.

Your boss thinks that you are wasting resources. Because applying OOAD process will not produce a single line of code.

Most of the benefits of using OOAD are not immediate. Benefits like reusability, modularity, and testability are visible when there are changes in the code. Changes happen in future. Hence why invest in something that is not important now?

Believe me, your boss is thinking there will be no change in the code — so why extra effort?

Guess what!

You will have to update/upgrade/modify your code. In software development, the only thing that is constant is ‘CHANGE’.

Hence convincing your boss is one huge external factor.

Another external factor — not enough resources. Sometimes we believe that if we have good tools then we will be able to go for OOD.

For example, UML modeling tool. Some developers believe that if they don’t have the perfect UML designing tool they cannot design.

Internal Resisting Factors

Harder than external factors are internal factors. The first one is that nobody will appreciate you when you start applying OOD process. This is because you don’t have any concrete evidence right now to show the benefits of your code design.

External appreciation is critical to get us moving. Hence if nobody supports us during our journey then we can lose the motivation to design our software properly.

Another internal fear is that you will doubt yourself- i.e you may doubt on your design skills. You yourself don’t know if something will be any helpful in the future– as results are not imminent while you are designing.

This is truer if you are a junior developer. You only have studied about design patterns during your studies. Due to this, you are lacking experience and confidence.

Another fear is the fear of failure. I believe this is more common. I am the victim of this fear. Once I design a software where I use generalization when there was only one line of code was common in two classes. Due to this, I have to manage more classes.

I always thought – what if I failed while making this design choice and due to fear of failure – I never did it. Failing once has made me resistive to good design practices.

Too many factors, what should I do?

Yes up to now I only described the factors that resist us. First, I described that sometimes our emotions are on high point and we want to make something happen like getting fit or making good engineering design.

But the reality of the world sets in and we leave the good things for tomorrow. Which never comes.

The first thing to design better is to create self-awareness. Create awareness of the factors that can limit your ability to do things which are good for your future.

Some factors I already have mentioned above but they are not limited to these. There can be many others. Whatever they are following guideline will always help you.

How to handle external fears?

Now, to deal with external factors(your boss and etc) you have to find small opportunities. Opportunities where you can make your design better.

For example, an opportunity is when you are debugging. While debugging your code you have the opportunity to stretch time. Here you can apply design practices and make your code better.

Another opportunity is when your boss asks you about an estimate for implementing a feature. Here you can add additional time for design activities. Make sure that you only add hours or 1 to 2 days at max. Never allocate weeks for design activities.

Another opportunity is when you are set for review. This can be rare and it varies from places to places. When you are reviewing your code for any unseen problem you can refactor your code for a better OO design.

You might be thinking that how can we make a good design after all the code is written?

Well, you can make your design better at any stage of the development. An OO design is not only a one-time activity.

How to Overcome Internal Resisting factors?

To overcome internal factors the key is confidence. Believe in that whatever you are doing will be helpful. Once you have this firm believe, you will observe the benefits of OOAD over time.

This is extremely necessary if you are a junior developer. Lack of experience will make you doubt the benefits of OOD methodology. Once you have confidence and willing to give in the effort, you will reap benefits.

Once you are confident then don’t worry about what other people are thinking. You will not need external motivation to carry out your work.

Next is fear of failure.

I used to think more about failures than success. What if all the design effort that I am doing will not be helpful. What if all the additional number of classes created due to the design process will be a headache to manage!

And most scary feeling:

My boss and my colleagues will make fun of me!

Yes, I have these fears and how do I tackle them. It’s simple. Just do it. If you failed (which happens rarely) then you know that you have learned something- But if you don’t give it a shot what will you lose?

For example, you will lose:

  • An experience which can get you to higher places.
  • Using object-oriented programming languages in an object oriented way (Not the procedural way).
  • Most importantly trying out new things in your life 🙂

Look, what I am saying is “start small”. Find the small opportunities to apply OOAD skills. Take small risks. These small tests will bring you the wealth of experience and you will be far ahead of your peers in the coming years.

So, what are the obstacles that you face? Are they internal or external.? Reply me via email or write them in the comments.

]]>
http://www.objectorienteddesign.org/object-oriented-design-for-life/feed/ 4 239
Put a Dinosaur in Zoo http://www.objectorienteddesign.org/put-a-dinosaur-in-zoo/ http://www.objectorienteddesign.org/put-a-dinosaur-in-zoo/#comments Mon, 01 May 2017 14:07:28 +0000 http://www.objectorienteddesign.org/?p=178 If you have ever been to a zoo you will definitely want to see one animal and that is Lion. Why? It’s because a lion is the king of the jungle. It’s at the top of the food chain.

I asked questions from my parents like: “can a lion kill an elephant or crocodile or cheetah”.

Then I watch Jurassic park movie. A dinosaur can kill the lion. They were huge. They can destroy buildings as shown in movies.

What if dinosaurs are still alive! We are able to keep the ferocious animal in the zoo, like lions and tigers. We can keep the dinosaur in our control and put them in a zoo. But definitely, if alive, dinosaurs will be at the top of the food chain.

Still, there are dinosaurs in our life. We want to keep them in a zoo. They are at the top. They are our bosses. How can you keep them in your control?

I believe managing and controlling boss is part of your job. Those who knows the pleasure in controlling their boss knows what I am talking about.

It creates benefits like extra vacations. Flexible timings. Fast promotions. Learning new things on the job. And most importantly free time to explore new opportunities.

Everyone hate their bosses. Especially programmers. Your boss telling you do a lot of things in the shortest possible time. Comparing you with others.

Bosses are hard. I realise this during my first interview after graduation. The boss told me in the interview that “We are hiring you but you are a liability for first three months- since it will take three months for you to adjust in the environment learned things that we do here and the way we do things here ”.

In short, he was telling me that you will consume electricity, one PC and internet bandwidth while he was not making any money from me.

This remind me a quote from Bill Gates

“If you think your teacher is tough, wait until you get a boss. He does not have tenure”

Well, this is not brutal. The brutal thing is that your boss telling you things that are not technically possible. For example suppose your boss ask this: ”Why would a particular task takes so much time in C++ whereas the same task can be done quickly in Matlab”. What would you say?

Convincing your boss that Matlab is not equivalent to C++. Explaining that there is a huge difference between a lab work and production work. How Matlab has built-in features and etc etc. It could be a nightmare to explain.

It does not matter if your boss is technical or not

Well, so many times your boss is right if he is a tech savvy person. Or if your boss has programming experience. But it is rare that your boss knows all about your field.

Whether your boss knows about technicalities of your job or not. In all cases, it’s a nightmare to convince your boss to your way of doing things.

You are not alone

If you are thinking that you are the only person in the world who has this maniac boss. Then you are wrong. We all have such bosses. Consider yourself luckiest if your boss likes you from the start.

Now, How can you handle your boss? There are three options.

Option 1

You can confront your boss. Go direct. Deny orders and do the things your way.

In many cases, this will not work. Especially if you are a new hire, e.g less than 2 years, you can get fired.

Confronting strategy works if you are so senior that you makes yourself a requirement for your boss. You have dozens of good projects under your belt. You are invincible. Then you can confront and tell your boss to shut off.

Option 2

You can fire your boss. You can quit. Many people can say you are escaping the bad situation. Well changing the bad situation and not making a compromise is one solution to your problems.

Keep in mind your ultimate goals. Like learning, earning according to the market and free time to live your life.

If you can fulfil all of your goals through another job then there is no shame in firing a bad boss. This will even leave some bad reputation for your ex-boss. Someone who is leaving a job is also a sign of bad management.

Will you find the best boss next door? Not guaranteed. But your next boss could be little better than the previous one. If that does not work then change again-shamelessly.

Option 3

What if you can’t follow the above two options? This is a situation when you are not experienced enough to dictate your own terms or if you are easily replaceable ( it’s easy in programming world). That is your boss can fill your position in no time.

Another reason is you don’t want to get in the hassle of finding a new job. Then in order to put your boss under control, you will have to make few changes in daily routine.

Understand your boss’ needs and wants

First, you will have to understand from your boss’ perspective. Your boss may be stressed out because of his superiors. Your boss may have challenging goals to accomplish. Or your boss wanted the next promotion.

Find out your boss’ goals and priorities and then align your goals accordingly.

Address Your Boss’ Fears

If your boss does not have information about the programming language and frameworks/tools that you use. This could make your boss uncomfortable. Or more accurately fearful. Your boss maybe thinks that you are making a fool out of him or her. What you need to do is address this fear.

What you can do to address this fear: educate your boss about technologies. For example, tell him about the benefits of python over other languages. What you can accomplish with node.js or any other tool or platform that you use.

Secondly, educate him about the way you do things. Like why you choose one strategy that your boss is sceptical about. Share any research paper on that or a book reference on that strategy with your boss.

One important point to note here is that: don’t educate to ridicule your boss. Don’t educate like you are confronting him -especially in front of your colleagues. This can backfire.

Don’t hurt your boss ego because everybody wants to protect their ego in front of others. And someone at a higher level then you (like your boss) is supposed to know everything that you do.

If you highlight that your boss does not know anything about what you do. This will hurt your boss’ ego. Hence you have to educate your boss politely.

Illusion of control

Another thing that you can do to appease your boss is by giving your boss the illusion that they are in control and they are guiding the whole process.

For example, a year ago I was working on a challenging project. There were a few things in my mind that I was thinking of experimenting. One day my boss called me up for the discussion on the problem. In that meeting, he was discussing a technique that was already in my mind. I kept a note of it.

Next, I ran an experiment to test that technique. That was successful and bring me near to my objective. I reported my boss that the technique that he mentioned does help me out. Explaining in detail how that specific technique helped me in solving the problem.

In this way, I make my boss the part of the process and someone who has full control over the project. Afterwards, when I completed the project my boss appreciated me than ever before.

The flipside of the story: In that meeting, my boss also mentioned dozens of other techniques that a sane programmer would laugh to death. But I kept myself in control.

So by making your boss the part of the solution and giving the illusion of control, you can win your boss trust.

In addition to that, giving your boss the education and giving them the illusion of control can work together. When you keep your boss educating, it is possible that your boss gives you ideas in future from the same knowledge that you taught your boss earlier.

What can be wonderful then your boss telling you the things that you told earlier and guiding you the way you want to be. That is the state where you know that you have put your dinosaur in your little zoo.

No doubt that this strategy will take some time. You will have to give it time initially and reap the benefits in future.

So what is your experience? Have you faced a stressful situation with your boss on programming projects? If you are new in the professional programming you will face them.

If you have faced these challenges then tell me in the comments and what you do to get out of that situation.

I read every comment.

]]>
http://www.objectorienteddesign.org/put-a-dinosaur-in-zoo/feed/ 1 178
S.O.L.I.D, GRASP And Other Basic Principles of Object Oriented Design http://www.objectorienteddesign.org/s-o-l-i-d-grasp-and-other-basic-principles-of-object-oriented-design/ Tue, 17 Jan 2017 14:35:29 +0000 http://www.objectorienteddesign.org/?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.

 

* indicates required


 

 

 

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.

]]>
16