This page addresses the question
-
- Why change well written Procedural code to be ObjectOriented?
Q1: My C program is essentially working along the following lines: if .. do this; else .. else if.. And a few databases. It is extremely quick. What would it gain from being programmed in C++ instead of C?
A1.1: IfItAintBrokeDontFixIt.
A1.2: If you have budget to change the code, perhaps also consider using another language if performance is not the key factor. The C/C++ family is not the most human-friendly language around in my opinion. They are subject to "mad pointer bugs" that will make you rip your hair out.
A1.3: If your program grows and changes over time, OO will allegedly help make it easier to change and extend while being less error prone. If it doesn't need this, then you'd gain nothing. If your program is already finished, then you'd gain nothing. C and C++ are also very low level; you'd benefit from using a higher level language, if you're going to do a rewrite. SmallTalk, Python, Ruby, C#, or Java would all allow much quicker progress in a rewrite, as they are far more modern languages than C and C++. Depends on the program's domain, though. {Not everybody agrees with OO making software more change-friendly. If you personally feel OO is better, then C++ might look more inviting over C.}
My guess of the intention of Q1:
Q2: I have written a C program which essentially working along the lines as in Q1, I have a new project and it seems I am going to do in a similar style again. What would I gain from doing the new project in OO style (in C++ or other OO language) instead of C? How would the answer depends on the scale of the project?
A2.1.1: What would I gain . . . instead of C? One thing you might gain is performance. Using OO in this situation implies you'll be using a polymorphic interface, which under the hood, means pointers to functions. Ask yourself what your giant if/else if/else construct does. Let's assign that name to a method on the object (one class per control flow direction). Then, for each class, implement the body of the relevant consequent of the if statement. When you invoke the method, it just invokes directly the relevant and correct code -- no need to spend time searching through what amounts to be an array of conditions that get repeated every single loop iteration. Assuming you're using a loop, of course.
However, it turns out that you can use this in procedural code too. In fact, in LeoBrodie's ThinkingForth, one of the Forth coding patterns commonly used is documented: don't set a flag, set the function (vector). (Page 256, #8.24 in my printed copy.) To quote: "If the only purpose to setting a flag is so that later some code can decide between one function and another, you're better off saving the address of the function itself."
What OO provides, however, is a convenient syntactic notation for this, at least in a static context. If you need this kind of behavior at run-time, then the StatePattern is for you. Either way, switching to OO is a net-win if, and only if, it would result in fewer keystrokes typed OR facilitate greater program maintenance.
- OO's benefits are about syntax? Please explain. And remember, CeeIsNotThePinnacleOfProcedural.
- Since anything you can do in an OO language you can do in procedural and just as fast (it's not just a Turing-completeness game; remember, raw assembly language is the final output of both!), it follows that any OOPL isn't worth its weight in horse dung if it doesn't allow you to conveniently exploit OO-style programming. That means you need a system of notation, a syntax, which caters just for that purpose. That's why p -> _vtbl -> aMethod((MyT *)p, arg1, arg2); in C is better expressed using syntax designed for the job of dynamic dispatch: p->aMethod(arg1, arg2); (using C++ syntax here, but there are better syntaxes still, such as ObjectiveCee or, dare I say it, JavaLanguage).
- It is, of course, true that OOPLs tend to offer a more convenient syntax for OO programming than do traditional procedural languages. However, that leaves unjustified the choice of OO approaches to solving problems. As a user of OO I find the advantages of OO relative to Procedural tend to be in its runtime ConfigurableModularity (the ability to construct programs based on some inputs then run them over other inputs), and its ObjectCapabilityModel (if you go fully OO you can encapsulate system tests and simulations as well as run multiple instances of a subprogram (sometimes tweaked to different purposes)). That said, with all the CrossCuttingConcerns that OO does not handle well (especially regarding reentrancy and asynchronous behavior and call cycles), I cannot call myself a fan. Traditional OO is not the pinnacle of OO... not with options like JoinCalculus (CeeOmega), FutureObjects, ActorsModel (and TransactionalActorModel on the horizon) offering all the same benefits as OO plus many more, and certainly not with even higher layers offering DataflowProgramming and service mashups.
- {Keep in mind that you are still comparing C to C++ in your example. The syntax "size" difference would be almost zero with a decent (more powerful) procedural language}
- Such as? OberonLanguage (specifically, Oberon-2) is the one, and the only, language whose dynamic dispatch is nearly as natural as most other OO languages (save Smalltalk). However, the addition of type-bound procedures in Oberon-2 automatically renders it a proper OO language. Oberon-1 wasn't true OO, and used explicit message typing to implement dynamic dispatch. The user had to explicitly declare one unique record type for each method signature, which means to call a method, you had to NEW(msg); msg^.f1 := value1; msg^.f2 := value2; ... etc before actually making the call. I'm sorry, but I'd rather C's approach over Oberon-1's in that event.
- Also, top (and I know it's you because of the RecentChanges IP address ;) ), in case you haven't noticed, I'm also largely agreeing with you. If you already know how to do something procedurally, and the economics of the project are such that you're looking for excuses to switch to OO (e.g., "just because I want to learn OO" or whatever), odds are in your favor that you're better off sticking with procedural/relational analysis. Use a toy project to learn OO fundamentals -- that way, the risk of failure won't be as great on a real-world project.
- OOP works fairly well when the quantity of object instances is fairly small and there is a *natural* one-to-one relationship between most of the behavior (operations) and the objects. Computational space seems to have this more often than domain space for yet unidentified reason(s). -t
- [How is 'the quantity of object instances' significant, especially compared to using procedural programming?]
- True, and I agree with everything you've said; but, I interpreted the OP's question as, "Why should I switch to OO if I already know how to achieve my goals in a procedural language?" Things like object capabilities and dependency inversion become irrelevant under those circumstances, which pretty much leaves only syntactical convenience. Adopting ObjectOrientedAnalysis? only gives benefits for new projects which haven't already been analyzed through other means.
- You seem to be saying that if you start a project with OO thinking then it's best to stick with OO thinking and vise versa. I don't have much of a disagreement with that; unless of course something is just a poor fit from the start, such as using OOP as a big database or using existing RDBMS as a real-time game engine.
A2.1.2: How would the answer depend on the scale of the project? Without specific source code examples, this question cannot be answered.
A1.4: There's a place in this world for well written procedural code. Implementing the ObjectMentorBowlingGame, for example, showed me that some problems have better procedural than ObjectOriented solutions. So it doesn't bother me to find and leave sections of well written procedural code in place, without changing them, as whole programs or parts of ObjectOriented programs.
However, my experience has also been that most procedural code would benefit from being refactored into being more ObjectOriented.
Examine the CodeSmells.
I've found the ObjectOriented style to offer useful tools to EliminateDuplication in the code.
Given the original description of the problem above as code containing "if .. do this; else .. else if..", I'd look for duplication among the if statements:
A common procedural code smell is to have the same codes and states tested in a number of different places because they have effects in multiple different places.
ObjectOriented PolyMorphism is often helpful in addressing duplicated conditional logic. See ReplaceConditionalWithPolymorphism.
-- JeffGrigg
SwitchStatementsSmell contains a similar claim, but there's a dispute about how "duplication" is being measured. The code "volume" difference is highly dependent on the language being used so much so that paradigm differences cannot be isolated out from specific language difference "noise". --top
EditHint: We need to find a way to clean up OO-related "improvement" topics. See OopDebateMetaDiscussion.
FebruaryZeroNine