Recently I was assigned a task of creating a calculator with functions addition, subtraction, multiplication, division and power using Object Oriented Programming. I successfully completed this task. However afterwards I reprogrammed the whole program without using Object Oriented technique/method.
The thing I noticed that my code length was reduced quite significantly and it was quite understandable. So my question here is when should I use Object Oriented Programming? Is it okay to create programs without Object Orientation in Object Oriented Language? Kindly help me out on this one.
PS: I am not asking here to tell me merits of Object Oriented Programming over procedural programming.
17
C++ is not “just” an OO language, it is a multi-paradigm language. So it allows you to decide for or against OO programming, or to mix them both. Using OO techniques adds more structure to your program – from which you will benefit when your program reaches a certain size or complexity. This additional structure, however, comes for the price of additional lines of code. So for “small” programs the best way to go is often to implement them in a non-OO style first, and add more and more OO techniques later when the program starts to grow over the years (which will probably not happen to “exercise” programs, but is the typical life cycle for lots of business programs).
The tricky part is not to miss the point in time when the complexity of your program reaches the size which demands more structure. Otherwise you will end up with a huge pile of spaghetti code.
2
How do professional programmers make judgement call on whether to go
for OOP or not? It would be really helpful for me.
For me, there are two decision points. First, sometimes it will be obvious at the beginning. There will be lots of similar types that all share common methods that differ widely in their implementation details. For example, I was building a workflow system, and I needed the ability to implement arbitrary tasks. To run the task, I implemented a base class that each task inherited from, with an Execute()
abstract method. The inheriting classes supplied the implementation, but the workflow system could begin the execution without knowing anything about what kind of task was being run.
Most projects aren’t that clear-cut though. The second decision point is when a subset of the project has grown into a huge tangle of if-then statements or switch-case statements, and especially when those if-then statements require a lot of setup code to run correctly. I feel myself starting to lose the logic of what I’m trying to accomplish, and the code starts to feel fragile. At that point, it is usually a sign that it is time to refactor the code into base classes with specific implementations.
A big part of switching to an object-oriented style as opposed to a functional style is converting if-then statements into “run this action” statements. Instead of a huge set of if-then statements, you just tell the code to run its action. Which action is actually run depends on the implementation you supplied.
For example, here’s the functional style in C#-style pseudocode:
if ( action == "email" ) {
callEmailFunction(userInfo);
}
else if ( action == "sms" ) {
callSmsFunction(userInfo);
}
else if ( action == "web" ) {
endpoint = "http://127.0.0.1/confirm";
confirmWeb(endpoint, userinfo);
}
...
But maybe you could rewrite that to something like this:
interface IConfirmable {
void Confirm(UserInfo userinfo);
}
public class ConfirmEmail : IConfirmable {
public void Confirm(UserInfo userinfo) {
// do the appropriate thing to confirm via email
}
}
public class ConfirmSms : IConfirmable {
public void Confirm(UserInfo userinfo) {
// do the appropriate thing to confirm via email
}
}
public class ConfirmWeb : IConfirmable {
// this is a constructor
public ConfirmWeb(string endpoint) {
...
}
public void Confirm(UserInfo userinfo) {
// do the appropriate thing to confirm via web
}
}
And then the code itself:
// An implementation that decides which implementation of the base class to use
// This replaces the if-then statements in the functional programmming.
IConfirmable confirmer = ConfirmerFactory.GetConfirmer();
// get the userinfo however you get it,
// which would be the same way you get it in the functional example.
UserInfo userinfo = ...;
// perform the action.
confirmer.Confirm(userinfo);
Now, when there is very little code inside the if-then, this looks like a lot of work to get no benefit. And when there is very little code in the if-then, that is correct: that’s a lot of work for code that is harder to understand.
But the object-oriented style really shines when you have more than one action than just the Confirm()
method that needs to be performed. Maybe you have an initialization routine, three or more action methods that can be run, and a Cleanup()
method. The base algorithm is identical, except it makes its calls into the appropriate objects that implement a common base class. Now you start to see a real benefit to the object oriented style: the base algorithm is much easier to read than if it was checking if-then statements at every step of the way.
5
Yes, it is perfectly normal to use old style code, provided the scope of your project is well known or is limited. If you plan on extending your program or project OOP is one way to go, because you can maintain and extend your code seamlessly, on the other hand if you planned it and have come to a conclusion that you are never going to plan extensibility of the project you make then writing code without OOP would suffice. It doesn’t mean if you use non OOP approach you can never upgrade your project but then it would be a tedious thing to do. OOP is to help us visualize our concept as though it were a real life organism because we understand those better than anything else.
3