Click here to Skip to main content
15,123,118 members
Articles
Article
Posted 27 Dec 2018

Tagged as

(untagged)

Stats

10.4K views
19 bookmarked

How to Write a Really Object Oriented Program

Rate me:
Please Sign up or sign in to vote.
4.65/5 (17 votes)
27 Dec 2018CPOL11 min read
There's a lot of program code organised into classes, but are they really object oriented?

Introduction

As I started to do interviews with new candidates to our team, I just realised that object oriented programming is a topic which is really not clear for most people. For the question: “Do you know what is object oriented programming?” I usually got the answer: yes. For the follow up question: “Could you briefly tell me what it is?” I never got twice the same answer. I got a lot of good answers and a lot of answers which did not really match with my understanding. And at a point, I started to think about how I would answer this question and I realised that it is not easy at all.

There was another example: I needed to reuse an already existing C++ code for my component. It was basically one class with around 200 functions and 100 variables, all of them were public and it was pretty unclear what they are standing for. After an analysis, I just figured out that I cannot reuse it as it is, because of multiple reasons:

  • It was using a third party logger, which I did not want to include to my project.
  • The program which was using it originally was based on TCP/IP communication. Most of the functions were throwing exceptions if the TCP communication was not set up properly even if they had nothing to do with that.
  • Some of the member variables were used in multiple functions with totally different purposes. So if you wanted to call a member function from outside, first you needed to set up ca. 10 member variables to the correct values to be able to get some results from the function.

All things considered, I just decided to refactor this piece of code before reusing it and it took me a long time to figure out how to do it, because a lot of functions needed to be decoupled to a separate class and it needed to be figured out what effects are made by each variable for the different functions. It was a nightmare. As the customer asked me why this refactoring was needed, I just replied: “Because it was not implemented in an object oriented way.” At this point, he told me: “Why not, it was all implemented inside a class, so it was object oriented.”. OK, from a technical point of view, it was implemented inside a class, so it was object oriented, on the other hand, it was not following anything that means object oriented programming for me.

In this article, I’d like to show you that object oriented programming is not just about using the related programming language elements, it is something much more than that. In my view, you can also do object oriented programming in languages which are not supporting that officially (like C) and you can also work in a non object oriented way in pure OOP languages (like Java or C#). Let me show you my understanding about OOP.

Principles of Object Oriented Programming

First of all, let’s see the official definition of OOP. I found a clear definition here.

It says:

“Object-oriented programming (OOP) is a software programming model constructed around objects. This model compartmentalizes data into objects (data fields) and describes object contents and behavior through the declaration of classes (methods).

OOP features include the following:

  • Encapsulation: This makes the program structure easier to manage because each object’s implementation and state are hidden behind well-defined boundaries.
  • Polymorphism: This means abstract entities are implemented in multiple ways.
  • Inheritance: This refers to the hierarchical arrangement of implementation fragments.

Object-oriented programming allows for simplified programming. Its benefits include reusability, refactoring, extensibility, maintenance and efficiency.”

Let’s stuck first at the features:

  • Encapsulation: I think this is the most important one. Each of the objects has a state which is hidden for other objects. And on the other hand, there is an “implementation” for each object. I understand under that the member functions of the objects. And the state and the implementation together is one unit or with OOP terminology one object. So if your object is a rectangle, it will have a state with elements like width, high, position, colour, etc. And it will have an implementation, implemented member functions, like: move, resize, paint, etc. And this is one object, not less, not more.
  • Inheritance: I would mention it before the polymorphism, because otherwise, it is difficult to understand it. Inheritance stands for the connection between parent/child classes alias base/inherited classes. So for each class, you can define so called child classes which can do everything that the base class can to (has the same public methods and member variables), but it can overdefine the implementation of the methods and it can extend the functionality (introduce new member functions and member variables). For example, you have a class for animals. Each animal can move itself. But how they can move themselves if different for each animal. So the different animals will be inherited from the Animal base class and will override the implementation of move method. Plus some animals have some extra skills, like a dog can bark. So you can define a bark method for the Dog class.
  • Polymorphism: This is exactly what I told about the move method of the animals. You can have, for example, a collection of animals and you can call the move method for each of them and you shouldn’t mind how it is implemented for the animal.

That’s the official theory. Let’s go further with some practical theory.

Objects and Classes and the Connections Between Them

From the name of object oriented programming, we can see that objects are the basic units behind this paradigm. The next important feature is the class. But what is the relationship between objects and classes: class is in fact a collection, a template for similar objects, for objects with the same methods and member variables. So if you are having a rectangle, then you will have a rectangle object which is an instance of Rectangle class. The rectangle class defines that it needs to have a size and a position and the object holds its exact size and position. There are programming languages (like JavaScript) where it is not needed to define the class of an object. In this case, objects are created based on so called prototypes.

So when you are planning an object oriented program, first you always need to think about what kind of classes you will need in your program.

The other important question is: what are the connections between these classes.

There are 4 types of connections between classes:

  • Composition

    That means that the connected class is belonging to our class. They have the same lifetime (they are created and deleted at the same time). Our class cannot work without the connected class. Like if we have a class called House and a class called Wall, then most likely, there will be composition between them.

  • Aggregation

    Aggregation between class A and B means that class A has an instance of class B. Like Car has an Owner. But the owner can exist also without the car, and the car can exist without the owner, the owner can change any time.

  • Association

    Association between class A and B means class A is using an instance of class B. Usually, this relation between the objects is just a short term relationship, only during the run of the specific function. For example, you have a class and it has a Log function. But this Log function needs an instance of the Logger class as a parameter. This is a typical example for association.

  • Inheritance/Generalisation

    This is the relation type already mentioned earlier. It means class A is a special case of class B. It’s also called as child/parent class as well.

So the next to do is to decide what kind of relations are there between your classes. It’s good to do some graphical modelling for your classes to have a better overview. For that, the class diagram of UML is a good tool. I would propose to always do a plan of your classes at least on a paper before starting to program.

There are two additional definitions I wanted to clarify:

State of the object: In fact, this built up based on the current value of all member variables. So if you are changing at least one member variable, the state of your object is also changing.

Public interface of the class: This is all the methods and variables which are public, which are visible from outside of the class.

Based on that, you can do a plan of your needed classes, but there are still some so called “best practices” in OOP programming.

SOLID

These best practices are called SOLID. This stands for the following:

  • SIngle Responsibility Principle

    Each of your classes should have a simple clear responsibility. You should be able to describe the purpose of the class with one sentence without using the words “and” and “or”. So yes: huge classes are most of the cases against this principle.

  • Open/Closed Principle

    Your code should be open for extensions, but closed for modifications.

  • LIskov Substitution Principle

    This is maybe a bit more complicated. But it means that each of your parent classes can be replaced with any of its child classes without breaking the functionality. This is coming from something called “Design by contract”. I plan to write a separate article about this topic.

  • Interface Segregation Principle

    Your interfaces shall be small and clear and having one well-specified purpose. So you should avoid having interfaces which are returning a lot of data. So the public interface of your class needs to be well designed and easy to use. Make everything public is not a good practise.

  • Dependency Inversion Principle

    You should design your classes in a way that the classes which are dependencies of your class can be set through some setter functions or constructor parameters. So that you can change them to any subtype later on. So for example, if you have a Logger class which is used to create log files and you can change it though a setter function, you can change your Logger between an XMLLogger, a JSONLogger or a SimpleLogger if all these classes are derived from the same Logger base class. It is also helpful if at unit testing, you need to mock your dependencies.

Let me extend it with my own suggestions:

  • Always try to keep all member variables (so the state of your class) private and use setter and getter functions for more control.
  • Always try to design a user friendly public interface for your class.
  • Avoid the long parameter lists at your member functions, in that case, always think about transforming some parameters to member variables if it really makes sense.
  • Read about object oriented design patterns and try to use them always when it is possible.

Object Oriented Programming in Practise

Now after getting familiar with all theory, I wanted to include a short practical example. This is about implementing a Canvas which can visualise different shapes, like rectangle, circle, triangle and star.

A not really object oriented solution would be to create one Canvas class with member methods like: drawRectangle, drawCircle, etc. But this solution is not nice, it is not using the features of object oriented programming and it makes it difficult to extend your code (it is against open/closed principle).

Based on that, my proposal would be the following:

Create a Canvas class. It should have a collection of shapes (aggregation with Shape class). It should also have member methods like addShape for adding new shapes or deleteShape for deleting already added shapes. It should have a drawAll function which draws all added shapes. Shape is a base class which has a draw method. Each shape has a (composition) size and a position. Position is a class with attributes for x and y coordinates. Size has a width and a height attribute. Each specific shape (Rectangle, Triangle, Circle and Star) are child classes of shape. So that each of them has a Position, a Size and all of them should implement the draw function. With this solution, it is pretty to easy to extend the program with new shapes (just implement new child classes) to change the representation of position to other coordinate system.

This modelled and visualised in a UML class diagram should be something similar:

Image 1

Summary

If you are an experienced software developer, maybe I did not tell you anything new, but based on my experience, a lot of programmers have a non-clear understanding about this topic, so I really hope I could help a lot of them. Based on my experience with this understanding, you can ensure a much better quality for your work.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Marcell Lipp
Software Developer
Germany Germany
I'm a software developer with around 5 years experience. Actually my main focuses are the following: software architecture, technical project leading, coaching, quality assurance and C++ development.
Next to that I'm blogging under: http://howtosurviveasaprogrammer.blogspot.com

Comments and Discussions

 
Generalvery good read Pin
Southmountain28-Dec-19 8:15
MemberSouthmountain28-Dec-19 8:15 
QuestionPre-OOP habits Pin
Bernhard Hiller4-Jan-19 4:33
MemberBernhard Hiller4-Jan-19 4:33 
QuestionDesign by Contract Pin
obermd28-Dec-18 10:33
Memberobermd28-Dec-18 10:33 
AnswerRe: Design by Contract Pin
Marcell Lipp28-Dec-18 10:44
MemberMarcell Lipp28-Dec-18 10:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.