Benefits Of Oo Original Discussion

(Topic since superseded by BenefitsOfOo)


Reduces method length

What if what you are comparing does not have methods?

If the alternative does not have methods, then comparison is meaningless. Perhaps we need to define what things we are comparing?


Other (Paradigms? Methodologies? Competitors?): FunctionalProgramming, LogicProgramming, TableOrientedProgramming, StructuredProgramming, LambdaCalculus, TuringMachineProgramming?

Which of these things is not like the others?


Since we are comparing OO versus something here, wouldn't it be better if we group the benefits into groups based on WHAT we are comparing against? Unless you believe that OO is the silver bullet, for each benefit, there will definitely be other paradigms that does it better. Comments?

That may create a huge many-to-many cross-link mess if we tried to compare everything to everything.

That could be interesting. Probably on a different page, that wasn't OO-centric. Some sort of master ProgrammingParadigmChecklist?. Incidentally, your second sentence is busted logic. If you can rank all members of a set for a simple attribute, one member will be ranked highest. Or, to get pedantic about it, if we allow ties, at least one member will have no member ranked higher.

Huh? It may be premature to rank anything.


How does OOP "reduce coupling"? In many cases, it increases coupling. For example, OOP tends to tie behavior to a noun taxonomy (sub-type tree). This *is* a form of coupling. The issue is whether it is "good" coupling or "bad" coupling, not the existence of coupling itself.

No, this is what we call modeling, not coupling.

Sometimes, coupling is good because it means that related things move together. IOW, we can treat concepts as a package. However, sometimes this causes problems when we need feature independence or a finer granularity. Completely ridding coupling may mean too much indirection, which can be very spaghetti-like to manage. Coupling is thus something to balance, not get rid of. -- AnonymousDonor

Encapsulation helps you NarrowTheInterface, reducing coupling between modules. That's the most significant benefit that ObjectOriented programming provides. Of course, other methodologies may also support encapsulation.

Could you be more specific? Perhaps an example?


What are we comparing OO against? I am having a hard time following this page because I don't see what is being discussed.

The most common competitor is probably procedural in combination with relational techniques. I agree that pre-relational procedural was nasty, but relational is a great counter-part. Yin-and-yang. See ProceduralMethodologies.

Okay, starting from the top of the list, how does OO programming compare to procedural programming in terms of reuse?

I think we would have to investigate on a case-by-case basis, as there are no one-to-one translation techniques in many cases. Besides, many question OO's claim to reuse (ReuseHasFailed). Perhaps we should first take a vote on which OO benefits people rank as the most important, and then explore them from high-to-low.

I don't see that ranking has benefit and only delays the analysis. If we cannot compare reuse, let's progress on to "Better models the real world." How does OO match up against relational?

How does one tell if something is better modeling the real world? Perhaps it better models your view of the real world, but your view is probably a simplification, as is any view of the real world. I can look at queues of people, stacks of paper, or bus schedules and see tables and relational formulas. Also, does better modeling the real world necessarily produce better results? Sometimes the real world has limitations that computers don't have, such as multi-category and multi-word indexing of books. RealWorldModel

By trying it. See GeographyExample

I want to make it clear that I don't think OO programming languages are perfect. They are good tools for a particular set of problems. Java and C++, the tools I've used the most, are heavily influenced by procedural ancestors. OO languages make it easier for many of us to communicate our mental models as code.

Well, I find well-designed schemas with decent documentation very good at communicating models also. I would like more specifics on how OO assists you in your communication and mental models.

Is there anything in the list at the top of the page that can be used to compare OO and Relational? Either there is common ground for discussion or relational is not a competitor with OO.

"Real World Modeling" topics: SoftwareHasNoShape, GeographyExample, SoftwarePlatonism


[This below should perhaps be moved to OoLacksMathArgument]

Oo lacks a decent structural math [paraphrased]

OO programming languages can express any math. You know that, it's been demonstrated on other pages. There's nothing willy or nilly about "OO theory". You're just being rude.

"Expressing" a math and being a math are two different things. You never seemed to grasp the difference. You only demonstrated the first, and in a rather, let's say, code-intensive way. I was not being "rude". Perhaps we should start up ExpressingVersusBeing? to resolve this recurring sticking point.

They aren't two different things. That was Turing's revelation. Any math that can be described in the syntax of a Turing machine can be used by that Turing machine. OOP languages allow every usable math.

Okay, lets then compare relational designs with a heavy OO wrapper versus relational without a heavy OO wrapper versus OO without relational. I find the first rather bloated WRT code size and the third lacks relational math. Thus, the logical choice is the second.

What an absurd statement, lacking relational math is not automatically a bad thing. What if my model is based on lambda calculus? There's nothing logical about assuming all models are inferior to the relational model, it simply isn't true.

{But we are not comparing lambda calculus to relational here. Relational provides a benefit over OO in that (at least) relationship management is better disciplined. OO does not offer standard relationship-management techniques, and that is its biggest problem IMO. See OoLacksConsistencyDiscussion for more. If lambdas do a better job than even relational, that is great, but off-topic. -- top}

TuringComplete only talks about emulation possibilities, not the convenience of doing such. Someone can write SmallTalk in a TuringTarpit for example.

Of course, there is the possibility of relational designs with a light weight OO wrapper, allowing you to pass around controlled access to the relational design with out giving them the keys to the whole shebang... PrincipleOfLeastPrivilege. -- cwillu

This seems to be about security, not relational versus OO from a paradigm standpoint. Note that wrapping something does not necessarily protect it. You have to force everything to use the wrappers if you want to use wrappers as a security feature. See GateKeeper.

Capability based security is a benefit of OO, and therefore applies to the situation. See GateKeeper :) Remembering of course, that you have to force everything to use whatever security mechanism you have in mind (e.g, lowest common denominator determines the level of security). If you're not concerned with unlimited access to the whole db if one happens to know the right door to try, then I guess this isn't an issue... but how often is that the case? I'm starting to come to the opinion that OO and Relational are orthogonal... one is a powerful security paradigm, the other is a powerful data-manipulation paradigm. -- WilliamUnderwood

I did not see any convincing arguments that OO does security or gate-keeping better in those links. There are some key unanswered questions in those links, such as example scenarios demonstrating alleged failures or weaknesses of relational-centric approaches.


Provides better source code structure than procedural programming

Having seen quite a bit of both procedural (mostly C) and OO (mostly C++) code, I have noticed that OO raises the bar in source code structure. Average OO code tends to have better structure than average procedural code, although I am convinced that the best procedural code writers could produce code as well structured as the best OO code writers. For the majority of developers, however, OO structure constrains them to better practices.

I would contend that the best procedural programs are effectively object oriented in structure, and could be easily translated to an OOP language. -- ChrisHandley

[I will concur with the observation above. My feeling is that OO was an evolutionary advance from procedural, with OO codify some of the best practices occurring in procedural code. I tend to fault many of the early "evangelists" of OO who tried to present OO as a revolutionary change. I feel much of the backlash is against the "revolutionary" portrayal rather than a reasoned review of the advancements solidified in OO specific languages. -- WayneMack]

Encapsulation and Cohesion (see CouplingAndCohesion) - From my view point, these are largely synonymous concepts. Encapsulation is not about "data hiding" per se, but provides a rule for operation cohesion. [Note: I am using the term "operation" to mean a unique action performed. A method may contain many operations and an operation may contain many lines of source code. I hope I am not confusing the issue.] In OO coding, operations are bound together in a class based on access to a common data element. Methods usually contain few operations, often only one. In procedural coding, operations are bound together based on an end use function. Methods usually contain many operations and often a single method provides almost all of an end use function.

As the size of programming projects increases we need more structure to help us manage the complexity of the project. StructuredProgramming gave us well defined control structures that made it easier to manage short pieces of code. ProceduralCode gave us well defined subroutine scoping and easy recursion to help us break up larger pieces of code. ObjectOrientedProgramming gave us well defined sets of procedures operating on well defined data structures to help us manage large numbers of procedures.

So what's next, what paradigm will help us manage large numbers of classes?

Hierarchy manages the quantity of classes. This provides a scope to view classes as necessary. Remember, the underlying problem is managing a large number of lines of source code. The proposition is that it is easier to manage a hierarchical set of many smaller files than a flat set of fewer large files.

[Also using PackageDesign to group closely related "clusters" of classes to packages, to help manage the hierarchy]

{Please clarify}

Most production OO languages have some sort of "package" or "module" system that lets you group related classes together. In Java, for example, the first statement in every class file might be something like "package com.c2.wiki;", and then all classes with that designator belong to that package. This gives them certain access rights, lets you import them together, etc.

But more importantly, it provides a means of navigation. Java forces you to mirror the package structure with the directory structure. (This, IMHO, is a misfeature; it's usually good to mimic the package structure, but it can be really inflexible and bloated in certain cases, and won't work well at all with a TaggedDatabaseFileSystem. But anyway...) This means that you can find any class just by navigating the directory structure: com.c2.wiki.EditText would translate into com/c2/wiki/EditText.java. And any given directory, assuming a sane package structure, would contain related classes so you can easily find everything within a given subsystem.

In many IDEs, this is even presented in a nice tree structure that you can expand and collapse as necessary. To browse, you merely have to expand the package you're interested in and take a look at its subsystems.

I know that you're going to immediately point me to LimitsOfHierarchies. And in this case, you're completely... wrong. Hierarchies are a good way to model systems and subsystems, because they let you zoom in on progressively more detailed areas. The amount of detail at any given level remains about the same, preventing things from getting overwhelming.

I agree trees would allow that if the actual information fits well into a tree shape, but my observation is that it does not over the longer run. A shoehorned tree is worse than no tree when things grow complex. It is like the old joke about looking for your missing watch where the lighting is good instead of where you actually lost it. Also note that many OO proponents agree with my about the problems with trees. They like OO for reasons other than tree-ness.

Relational, by contrast, is singularly bad for browsing. It's good at formulating fast ad-hoc queries, but that requires that you know what it is you're querying for. If you don't, you're stuck with the raw tables, which can be huge.

If you don't know what you are looking for, why are you looking?

If you have a couple tens of thousands of functions, as many large apps do, there is no way that you're going to select them all from the database and read over them. -- JonathanTang

Usually there is a module grouping. If you want a higher-level view for initiation purposes, then start off with a list of the modules, which generally correspond to "tasks" or "events" in procedural. Ideally, one can query that list to narrow it down. I will agree that it is harder to group such by entity because procedural tends to view entities as implementation details, in contrast to OO which often has a PrimaryNoun philosophy. One can include meta data with module records that describe the most common entity associations if need be (and if there is such a thing for a given module). Thus, I will agree that most OO generally makes for easier noun-based views because it's the flip-side of the verb-based code org of procedural. That is the trade-off. But IMO relational makes it easier to make up for the deficiencies than the reverse.

The HierarchicalVsRelational? debate may be fun, but let's get back on topic. What will be the next paradigm? The addition of packages or modules on top of OO isn't really a paradigm so much as an idiom or a good practice. While OO probably started as a collection of idioms and good practices that helped organize large procedural projects, once it was formalized it actually produced a new way of thinking about problems. That is what makes it a ParadigmShift. So, are packages the precursor of new paradigm, or are they just a way to name a bunch of classes.

Probably the next paradigm is the formalization of communications between executable modules (as opposed to within a single executable). There have been several attempts in this direction, including pipes, MQ, COM, CORBA, and now XML + Web Services. There comes a point where there is simply too much to be done to put it into a single compiled unit. We need a rational way to decompose the functionality into different modules. At this scale, I believe method calls and inheritance break down and we need some type of peer to peer data sharing.

[Don't forget AspectOrientedProgramming when looking to see where OO will evolve next]

I don't think so, AspectOrientedProgramming is but a subset of Meta programming, something Smalltalk/Lisp/etc... have been able to do for a long time. Smalltalkers don't even consider this new, it's standard OO Metaclass programming. CLOS could do things far more advanced I imagine. Frankly I think it's part of OO and doesn't deserve it's own "Oriented" adjective.

It needs language support (you can't do it directly in C, for instance), and doesn't follow from any of the definitions of OO, so even if it is related, it certainly is not just a part of OO. An extension, you could argue.

And you also can't dismiss it because you've been able to do it in older systems; the question is, have people actually been doing it, and regarding some of the AOP techniques, I think the answer is largely "no".

You may be right, but from my readings, it seems smalltalkers/lispers have been doing this for years. Maybe I have a misunderstanding, but it seems to me AspectOrientedProgramming is but a small part of the MetaObjectProtocol style of programming, if not, what makes it special?

I suppose it would be interesting to list the AOP sub-techniques and see which are commonly in use in Lisp, Smalltalk, etc.

AspectsAndMetaObjects are related, but aspects give you one big advantage over CLOS: the ability to specify where advice applies along with the advice, instead of at the point of application. You have to specify the metaclass to use along with each class, preventing you from non-invasively adding functionality. In an aspect, however, you specify which classes are affected by the pointcut, and the classes themselves remain pure and unmodified.

This is not a free lunch: it makes it impossible to know exactly what code path will be followed at any given point in the program. But OOP already gives up much of this static knowledge, because PolyMorphism makes it impossible to tell what method a given function call will execute, and UncheckedExceptions mean that any given function call might or might not return. Up till the 60s, the trend in CS was towards greater comprehensibility in programs (hence GoToConsideredHarmful?). From the mid-70s onwards, the trend has been to deal with incomprehensibility, because the systems software engineers build are fundamentally too large for any one person to understand. -- JonathanTang


I would like to hear more about how managing "large procedural projects" naturally leads to OO. As I have stated under ProceduralMethodologies

[I've copied the following from my WikiHomePage] Eventually, I discovered that the best way to keep large C programs manageable was to impose rules on myself to keep the code organized. I built structures to hold data and wrote a set of functions that all took a pointer to said structure as their first argument, and I only allowed myself to access the structure via those functions. The structure and its functions all went in a common header file by themselves, with a single .c file for the function implementations. Later, I learned that this technique was called ObjectOrientedProgramming. Actually, to be precise it's encapsulation (EncapsulationDefinition), but that was when I started ToGrok ObjectOrientedProgramming.

I began ToGrok ObjectOrientedProgramming while working on the final project of SoftwareEngineering during college (1991 in case anyone was curious). I'd had a little exposure to C++, but had not yet understood what all the fuss was about. I was quite comfortable writing procedural code in C, however. The project was to write a college course registration system. We were a team of three. During early design meetings we quickly realized that the system would have to manage many different lists. The system needed lists of professors, lists of classes, lists of classrooms, and lists of students. Professors had lists of the classes they were teaching. Classrooms had lists of classes held in them. Students had lists of classes they were registered for, etc. Using a database to maintain all of these lists and relationships would have been a good solution, but we didn't have access to a database that I am aware of, and we probably weren't that familiar with using them at the time anyway.

What we knew we didn't want to do was write a bunch of functions to manage each of the different kinds of lists. I proposed that we write a set of generic list functions that could be used to manage a list of anything, and since I proposed it, I also got the task of writing the code. First I decided to use a DoubleLinkedList. Next I defined a generic list node structure as follows:

    struct node
    {
        node* prev;
        node* next;
        void* data;
    };

Once this structure was defined, I started writing functions to manipulate lists. I ended up with a pretty rich set of operations for linked lists. What jumped out at me after a while was that nearly every single linked list function took a node* as its first argument. That's when it finally hit me. Had I been using C++, the node* would have been eliminated and replaced by the this pointer, and all the functions would have been members of the node class.

I hope that this anecdote demonstrates how in my effort to encapsulate and reuse a concept in a procedural environment I ended up replicating some basic OO functionality. Hopefully, others can provide examples that touch on inheritance and polymorphism.

-- ChrisHines

It sounds like you are claiming that OO is good if you don't have access to a database. I would also probably prefer OO over pure procedural if I could not use a database or at least a decent "table engine". In that sense, you imply that OO is the consolation prize when the database is not obtainable. BTW, see CampusExample. -- top

[You should re-read that a few times, that was not his point at all.]

I read it again, and interpret it the same way the second time. Perhaps what you mean is that it is the first time that the concepts of OO were grokked, but not necessarily the benefits. If so, then it does not answer the topic name. -- top

[The paragraph ...Once this structure was defined, I started writing functions to manipulate lists. I ended up with a pretty rich set of operations for linked lists. What jumped out at me after a while was that nearly every single linked list function took a node* as its first argument. That's when it finally hit me. Had I been using C++, the node* would have been eliminated and replaced by the this pointer, and all the functions would have been members of the node class. This is the behavior thing we talk about... he suddenly realized that he had all these functions (the behavior) that worked with that datastructure, and every one of them took it as the first argument. He was doing OO programming in C, when he suddenly realized his data structure was the object's this pointer. Objects allow attaching behavior to data, when it is necessary, rather than passing the data around to the behavior. One doesn't always need to attach behavior to data, but when you do.. objects are simply a godsend.]

Actually, I just thought of an example for polymorphism. Several years ago, a colleague and I were asked to write a program to migrate data from a legacy database schema to a new schema. In the process of migration, the program was also to perform close to 200 validity checks on the data. The program was only supposed to write records that passed all of the validity checks to the database and write any records that failed to another location for human inspection. The programming language was C.

We categorized each validity check based on the scope of information it required. There were three categories, checks that depended only on a single field, checks that depended on only a single record, and checks that depended on multiple records. Although we had nearly 200 checks in total to perform, there were far fewer different check algorithms involved. For example, the data contained many date fields, and we needed to validate that each of them was a valid date.

So, here is where the polymorphism comes in. We performed the checks in increasing order of complexity. First we performed all of the single field checks. The program read a single record. It then iterated over the fields in the record performing the single field check (if any) for each field. This process was performed by indexing into an array of function pointers, one for each field in order. Each entry of the array pointed to a function that performed the correct check for the corresponding field. Obviously every single-field-check function had to have the same signature, but they each did what was appropriate for that field whether it was a date field, a numeric field, a string field, or what have you. This change of behavior based on the true type of an object is polymorphism, and it simplifies the higher levels of applications by allowing them to treat a group of diverse objects in a common fashion via a common interface.

Like my first example, this example isn't really true OO. I believe these examples are valuable because they describe software designs that live in that grey area between procedural and OO. In both cases, my colleagues were initially sceptical of the ideas, but quickly jumped on the bandwagon once they saw the power of the techniques. In both cases I began to realize the power of true OO because of a need to manage the complexity of a non-trivial application.

-- ChrisHines

That's a great example of how learning advanced procedural techniques and code organization naturally lead to object oriented programming. As many have said before, object oriented programming is the natural next step to procedural programming. Good story.

As the resident OO skeptic, I have a few comments and questions. Why wouldn't case/switch statements or ControlTables be appropriate? I have done similar conversion tasks using ControlTables. I was even complimented for finishing the task ahead of other recently-purchased divisions that had to do similar stuff to their own data. Further, being dependent on dividing things into "types" will bring up topics such as ThereAreNoTypes, and LimitsOfHierarchies. Maybe subtypes will work for a one-time conversion, but over time things tend to drift away from clean tree-shaped subtypes. OO proponents claim that a key benefit of subtyping over case/switch lists is that it is easier to add new types. But if this is a one-shot conversion, one does not keep adding new subtypes.

[He added over 200 new types, I'd say that ability came in pretty handy.]

Although this is an oversimplified version of my actual conversion ControlTable(s) for stated project, it gives an feel of the converting of a text file into a RDBMS.

  Table: Convert
  ----
  startPosition       // character position in ASCII dump
  endPosition
  destinationColumn   // name of destination RDBMS column
  validationType      // code such as int, date, money, etc.
  otherValidation     // code snippet and/or function name 

The majority of fields did not require "otherValidation" I would note. In practice, I had to do math and other parsing, and thus had stored conversion formulas such as "field('foo') + field('bar') - field('taxes')". Well, actually it was more like "field(sourceFileCode,fieldName)" because I was combining two tables into one (or was it the other way around?). I could print out all 150 or so field conversion records in nice, compact report form to take to conversion meetings. Even the accountants could understand some of it (although that was not my original goal) because it sort of resembled a spreadsheet with the "formula inspection" turned on. It was real handy. I received a lot of kudos for that project. It was a case where TableOrientedProgramming shined brightly in the real world. (It was written in FoxPro, BTW.)

...

If being maintenance-friendly was not an issue, what criteria did you use to evaluate "better"? -- top

[Umm.... better == easier to build.]

You're missing the point, he used PolyMorphism because he had a limited set of known field types, the database column types, and the code was simpler to write by treating each rule as its own separate method. He has well over 200 rules at the end, but by dividing them into 3 kinds of rules, he came up with only 3 possible function signatures, i.e. validation types. Once that was known, it's easy to build the validation system generically without any rules, then add then rules one by one until the job was complete. The types made adding the rules easier, while keeping them separated from each other and from the validation engine. The switch couldn't do that, it would mix them all together in one big massive function, which he was trying to avoid doing.

I need to look at some details. How about a pseudocode mock-up? BTW, LongFunctions are not by themselves necessarily evil.

You don't need samples to grasp that it's easier to write a complex system, by building it with lot's of simple parts, than by building it with one big massive complex function. No need to revisit that long function argument, the author already said he broke it up to simplify it, obviously it was necessary.

Case lists are not "complex". They are like a bunch of small anonymous functions (blocks) neatly placed list-wise within a larger module-like function. As stated at the bottom of LongFunctionsDiscussion, Blocks is Blocks. (Sure, C has the ugly "break" command, but that is a language flaw, not a paradigm flaw.) However, I will grant that code that bothers me may not bother him and visa versa. If whatever you saw bothered you, I respect that. However, please don't over-extrapolate your personal preferences to everybody else.


Subtle or Obvious?

I am curious. Does anyone here think that OO has any obvious, clear-cut "slam-dunk" benefits? In other words, something that is easy to demonstrate and measure, such as being noticeably less code? All of the benefit claims/demonstrations seem to eventually rely on subtle or psychological issues or claims, not blatant improvements (well, outside of the infamous device driver patterns perhaps). I just want to clarify that we are dealing with subtle differences here. If not, let's nail down the obvious ones because they would in theory be easier to present. In other words, lets compare the power of different canons before we compare their paint jobs. Note that some believe that multitudes of subtle differences add up to a big difference, but that still makes it hard to pin down from an observational viewpoint. -- top


Some material about change impact benefits moved to PerceptionOfChange.


See OoIsPragmatic, OoEmpiricalEvidence, OoBestFeaturePoll, ArgumentsAgainstOop


EditText of this page (last edited July 23, 2013) or FindPage with title or text search