Why should we learn Object Oriented Programming?

Algorithms + Data Structures = Programs’

There is a famous book by Niklaus Wirth, which covers fundamental concepts of programming, and Mohan has read it thoroughly.

'I know everything about how to write a program; why do I need to learn OOPS?' Mohan boasted.

*'Because what Niklaus said is theoretically correct, a program is indeed a combination of two things, information(Data) and a set of instructions for manipulating that information (Algorithms). But it turns out that we are not just writing programs, we are writing software.' ~The wise developer replied.*

'Well, what is the difference?' - Mohan asked, still not clear about the difference.

A program is written to perform a particular task, like sorting a linked list or finding a minimum path in a tree, or simply displaying a 'hello world' message on your console. But software is a collection of programs that interoperates to perform one or more tasks.

Modern Softwares usually consists of millions of lines of code and operates on terabytes of data, and is so complex that not a single person understands it all. Hence we need a way to organize these instructions so that it is:

  • Easier to understand and explain.
  • Easier to reuse and extend.
  • Easier to maintain.

'Object-Oriented Programming(OOP) has been one of the most popular paradigms used in the last few decades for this purpose.' ~The wise developer replied.


'So what is OOP and how can it help me?' - Mohan was curious to know more now.

Before that, let's understand what an object is.

'An Object is a logical construct consisting of some user-defined data and a set of operations for manipulating that data.'

‘data + operations = object’

And Object-Oriented Programming is (as the name suggests!) a way to think and structure your program around these objects. The core idea is: Thinking in an object-oriented way is a great way to understand the problem you are trying to solve. It allows you to build software that is more maintainable and easily understandable for other people.

Building System: The 'OOP 'Way

For example, let's say you want to build an inventory management system for a bookstore. And the requirements are :

  1. The system should allow storage of each book's metadata, like name, author, price, etc.
  2. The system should allow the addition and removal of books from inventory.
  3. The system should have the capability to search books by metadata.

To build your system in the 'Object-Oriented way', you will have to

  1. Identify objects in your system.

    💡 The 'Nouns' in your requirements often translate to 'Objects' in your system. Give it a try!

  2. Identify the relationships and responsibilities of these objects.

    💡 Identifying the verbs in your requirements gives you an excellent idea of the roles and responsibilities of each object.

  3. Identify attributes(data) and operations(methods) for each object.

    💡 Similar to the last exercise, look at the remaining nouns, adjectives, and verbs again. The adjectives define the attributes, and verbs define the operations to be performed on the object.

Write down your analysis, repeat the steps, and use some common sense to refine your design further. Ask questions like: Does the author need to be a class or string? How should I store books so that they can be searched easily? Does the order of search results matter? What if the user wants to sort books by price? Asking such questions will help you to

  • Understand which objects you do or don't need.
  • Avoid bugs in your system.
  • Deliver software that does what the user needs.

Here is a simple example of how your classes might look like:

class Book {
    string name;
    string authorName;
    float price;
    string getName() { return this.name; }
    void setName(string name) { this.name = name; }
    string getAuthorName() { return this.authorName; }
    void setAuthorName(string authorName) { this.author = author; }
    float getPrice() { return this.price; }
    void setPrice(float price) { this.price = price; }
}

class Inventory {
    Book [] bookList;
    Book [] searchItem(string name) {}
    void addItem(Book book) {}
    Book removeItem(Book book) {}
}

Let's take another example : 

Let's say you want to build a chess game. To get started, think about what 'things' you need in real life to play a chess game. You will need:

  • A board of 8X8 squares, where the game is played.
  • Chess pieces of different types, i.e Pawn(8), Bishop(2), Knight(2), King(1), Queen(1), and Rook(2) for each player.
  • 2 players to play the game.

I think I got it! I have marked all the nouns in my requirements. So I will need the following objects: player, board, square, pawn, bishop, knight, king, queen, rook, game and …

Wait!

As we are designing a real-world system, it's very common to design our objects according to the things we can see in real life. One way to model the above problem could be to create a separate class for each noun as mentioned. But a wise programmer always thinks twice before writing any code. 

“Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. …[Therefore,] making it easy to read makes it easier to write.”

Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship

Ask yourself, do each piece require a separate class, or are they 'instances' of the same class with different 'types'?

Similarly, Do you need a separate player class? As players can be considered 'external initiators' interacting with our system. 

Remember, there is no single correct answer here. But a simple design with fewer entities is usually a good starting point. One such answer could be :

enum Color { BLACK, WHITE };
class ChessPiece {
    enum Type { PAWN, BISHOP, KNIGHT, KING, QUEEN, ROOK };
    Type type;
    Color color; 
    Square currentPos;
    // moves the piece to target square.
    void move(Square targetSquare);
}

class Square {
    Color color;
    ChessPiece piece;
    String position;
}

class Board {
    Square squares[8][8];
    //initialize game board and setup pieces
    constructor();
}

class Game {
    ChessPiece activePieces[];
    ChessPiece capturedPieces[];
    void startGame();
    void stopGame();
    void pauseGame();
}

'So like in algorithms world, we try to divide the 'problem' into smaller parts so that we can come up with an optimal solution for the computer, here we are dividing our 'program' into smaller parts so that we can come up with an optimal code for the developers.' - Mohan

'Yes, that's correct; there are many more programming paradigms that were created with this purpose in mind. But that's a story for another time, for now, you should focus on improving your OOP skills' - The wise developer replied.

Conclusion

Objects are an inevitable part of every software system that you interact within your daily life—but deciding which objects you need and which you don't require a careful textual analysis of your requirements and a lot of experience. Remember that OOP gives you a 'mental model' of how to structure your software. Once you understand that, you can use these ideas anywhere, irrespective of which programming language you choose. 

💡 Try applying these ideas to software that you use in your daily life.

We welcome your comments

Subscribe Our Newsletter

Get well-designed application and interview centirc content on ds-algorithms, machine learning, system design and oops. Content will be delivered weekly.