Jump to content


Check out our Community Blogs





- - - - -

OOP is overrated.

Posted by DarkLordoftheMonkeys, 24 January 2010 · 1260 views

Don't get me wrong. I have nothing against OOP. I just don't see what's with all the hype about it. Everyone's like "Yay! OOP! Now I can have things in my program. I can ecapsulate data and do modular programming and $hit." But the reality, at least as I see it, is that "object-oriented" is just a buzzword that is nothing more than a rebranding of something that has been in existence since programmers stopped using machine language. It's an empty shell. Pretty much anything you can do with OOP you can do with procedural programming. Let me explain...

Data abstraction:

Data abstraction provides separation between the interface to an object and its implementation. OOP provides data abstraction by allowing the programmer to group related data and functions into discrete units. What exactly does this do that can not be done with records or structures?

Here is how you create methods and properties in Java:

public class Foo{
	public bar( ){
		/* do something with var */
	}
	private var;
}

Here's how you would do almost the exact same thing in C:

struct Foo{
	int var;
};

void bar( struct Foo foo ){
	/* do something with foo.var */
}

One method knows to use a member of that class because it's included in the class. The C function knows to use a member of the structure because it takes the structure as input. They are practically the same thing.

Both the Java class and the C structure are abstract data types. But the C function does not require the programmer to know that var exists, which actually means that in a way the information hiding scheme is better.


Encapsulation:

Encapsulation is the grouping of related properties and methods into a single unit. Many object-oriented languages force you to group functions and variables together, even if they are completely unrelated. Java is a good example of this in that everything has to be encapsulated in a class. C gives you more flexibility. You get to choose whether you want to encapsulate your data or not. And if you do, just use a header file.

Inheritance:

This is the only area that procedural programming languages are really lacking in. The ability to reuse information is invaluable to a programmer. However, the frequency of having to reuse information in this sort of way is, as far as I can tell, not very great. I have tried to find a way to use inheritance in a useful way, but with no success. All it does in my opinion is make the code look messy, and force whoever is reading the code to search up through the entire hierarchy of parent classes to gain any comprehensive idea of what properties and methods a class uses.


Public and private members:

In my opinion, having members be public and private is just a waste of time. Every variable you create has to have a corresponding set or get function, which adds 3x more lines of code, where x is the number of private variables. If you want to make a variable read-only, just use const.

To add to that, pretty much any language with pointers will allow the programmer unlimited access to private members. This is what C++ does. That sort of takes away the whole point, and all the set and get functions you created just take up space.


Spaghetti code vs. lasagna code:

Both OOP and procedural languages are susceptible to producing spaghetti code, that is, code in which the control flow is hopelessly unclear. OOP languages, however, have an added danger: lasagna code. This is when layers are used to such an extent that they practically lose their meaning and are impossible to make sense of. Procedural languages are in their own way susceptible to the lasagna code effect as well, but it's a lot easier to avoid. One primary cause of lasagna code is the abuse of inheritance.

Widgets:

Apparently, using widgets to create a GUI makes programs easier to write and more compact. Well, let me show you a very simple GUI program in Java that does almost nothing:

import javax.swing.*;
import java.awt.event.*;

public class SimpleGuiB implements ActionListener{
	JButton button;
	
	public static void main(String[] args){
		SimpleGuiB gui = new SimpleGuiB();
		gui.go();
	}
	
	public void go(){
		JFrame frame = new JFrame();
		button = new JButton("Click me");
		button.addActionListener(this);
		frame.getContentPane().add(button);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(300, 300);
		frame.setVisible(true);
		
	}
	public void actionPerformed(ActionEvent event){
		button.setText("I've been clicked");
	}
}

All this does is create a button that says "Click me", and when it is clicked, the button says "I've been clicked". It isn't even scaled or anything.

I hate Java.

In conclusion, I think that OOP capabilities are good for a language to have, as long as they aren't over-emphasized and don't get in the way. Forcing the programmer to use classes for everything is not good practice (one exception to this is Javascript, in which there are predefined classes and objects that actually do something, without you having to write 20 extra lines of code to use them). OOP should be an extra tool that you can use, sort of like the bitwise operators. It should not be the heart and soul of the language.

Perl is a good OO language. So is PHP. They represent the ideal situation, a balance between paradigms.

  • 0



A good example of OOP inheritence: forms in Delphi, Lazarus, gtkmm, wxWidgets, etc. A form is a general object that displays a window. Inheritence allows you to take all the logic of a form, and extend it by adding buttons, text boxes, etc.
    • 0
Well DarkLord, you're jumping on one of my favorite ways to program, you're dissing on one of the few things that make me happy to program. OOP, in my opinion, is rarely used properly, and that leads to it's inevitable underappreciation. Used correctly, it's a wonder to behold. So without further ado, I need to pwn you.

[quote name='DarkLordoftheMonkeys']Don't get me wrong. I have nothing against OOP. I just don't see what's with all the hype about it. Everyone's like "Yay! OOP! Now I can have things in my program. I can ecapsulate data and do modular programming and $hit." But the reality, at least as I see it, is that "object-oriented" is just a buzzword that is nothing more than a rebranding of something that has been in existence since programmers stopped using machine language.[/quote]
No, people aren't saying that. I don't know what rock you recently crawled out from under, but OOP has existed since the 70's, when Smalltalk was developed, later released to a wide audience in August of 1981. So people aren't celebrating, and they certainly aren't saying "now" or anything close to it, OOP has been in use longer than you've been alive.

The only reason anyone could construe Object-Oriented as a buzzword is because it's in so much demand by industry professionals, you know, the guys who actually want to get sh*t done, and aren't afraid to pay for it. It was coined as a method to express how collecting data into manageable units and sending messages back and forth from them was an entirely different way to look at programming than as a set of procedures.

[quote name='DarkLordoftheMonkeys'] It's an empty shell. Pretty much anything you can do with OOP you can do with procedural programming. Let me explain...[/quote]
Yes, well no one will argue that you couldn't do the same stuff without OOP, it's that doing so is fantastically harder. Would this lead you to argue that people should go back to programming with hex editors since you can do so much more with that than one of those silly high-level languages like C?


Data abstraction:
[quote name='DarkLordoftheMonkeys']Data abstraction provides separation between the interface to an object and its implementation. OOP provides data abstraction by allowing the programmer to group related data and functions into discrete units. What exactly does this do that can not be done with records or structures?[/quote]
Wrong, sir! Wrong!

What you describe is much closer to Encapsulation than data abstraction. The most basic form of data abstraction is the data type available nearly everywhere, including C. The point of data abstraction is to ascribe meaning to a particular set of otherwise meaningless data. A series of integers or a series of ones and zeros pretty much mean nothing in and of themselves, but when you give them a name, they suddenly take on purpose. If you collect a series of these smaller abstractions into one larger set, which is supposed to represent something else, that is a bigger abstraction, and so on. Records and structures are data abstractions.

[quote=DarkLordoftheMonkeys]Here is how you create methods and properties in Java:

public class Foo{
	public bar( ){
		/* do something with var */
	}
	private var;
}

Here's how you would do almost the exact same thing in C:

struct Foo{
	int var;
};

void bar( struct Foo foo ){
	/* do something with foo.var */
}

One method knows to use a member of that class because it's included in the class. The C function knows to use a member of the structure because it takes the structure as input. They are practically the same thing.[/quote]
No, no they are not. First off, the Java version will fail to compile since bar isn't declared as void like it should be. Second, if you fix that then the C version will fail to perform as expected because you're sending a copy of struct Foo rather than a reference to it. Finally, after you've fixed those problems you stil have a significant issue in that the Java var is not accessible outside the class, whereas the C version of Foo.var is entirely exposed. Further, Java automatically zero's out any allocated variables, so you can safely assume it's zero, and you can't in C.

[quote name='DarkLordoftheMonkeys']Both the Java class and the C structure are abstract data types.[/quote]
Yes, yes they are.
[quote name='DarkLordoftheMonkeys']But the C function does not require the programmer to know that var exists, which actually means that in a way the information hiding scheme is better.[/quote]
On the contrary, actually the C version does require knowledge of var, since you can't declare it statically otherwise and it's public. Further it is the Java one that does not require this knowledge, since the Java version of var is private and always dynamic, and the C version is not. You seem to have this backwards, you have to do quite a bit more work in the C version to get it so var is no longer a public variable, and with that you also then require the use of dynamic memory allocation. In C you cannot replicate what Java is doing in the same number of lines. C++ also opens up the path to RAII tricks, which are very awesome in that it saves you a lot of code.


Encapsulation:
[quote name='DarkLordoftheMonkeys']Encapsulation is the grouping of related properties and methods into a single unit.[/quote]
Weren't we just here before?
[quote name='DarkLordoftheMonkeys']Many object-oriented languages force you to group functions and variables together, even if they are completely unrelated.[/quote]
No they don't. Have you used C++? How about Python? Finally, the "forcing" that these languages are doing seems, at least to a neutral observer, pretty benign. Take a look:
public class Main
{
    static var1;
    public static void main(String[] args)
    {
        var1 = 10;
        System.out.println("" + var1);
    }
}
Yes, there's some real Nazism there.
[quote name='DarkLordoftheMonkeys']Java is a good example of this in that everything has to be encapsulated in a class.[/quote]
Oh, right then.
[quote name='DarkLordoftheMonkeys']C gives you more flexibility. You get to choose whether you want to encapsulate your data or not. And if you do, just use a header file.[/quote]
"Flexibility". Now THAT, my friend, is a buzzword!

Besides, no it doesn't, taking flexibility to mean what it actually does and not what you ascribe it to be. Flexibility means the ability to change or make modifications to something that's already there, not the freedom to make a slightly different choice. Flexibility means you can write half your program, realize you need one panel with dozens of controls in a completely separate window, and code that change in 5 lines. THAT'S flexibility.


Inheritance:
[quote name='DarkLordoftheMonkeys']This is the only area that procedural programming languages are really lacking in.[/quote]
That and generics, polymorphism, lazy evaluation, etc...
[quote name='DarkLordoftheMonkeys']The ability to reuse information is invaluable to a programmer.[/quote]
Remember kids, Don't Repeat Yourself!
[quote name='DarkLordoftheMonkeys']However, the frequency of having to reuse information in this sort of way is, as far as I can tell, not very great. I have tried to find a way to use inheritance in a useful way, but with no success. All it does in my opinion is make the code look messy, and force whoever is reading the code to search up through the entire hierarchy of parent classes to gain any comprehensive idea of what properties and methods a class uses.[/quote]
Then that must be quite a poorly developed class if you'd have to squirm up the inheritance tree just to find out what things are doing what. Further, the frequency of using this ability is so common I very rarely write a class without inheritance. Inheritance allows me to take a prebuilt class, modify it slightly to fit my needs, then plug it in as if nothing had changed at all, and there is NOTHING in C that can perform that ability. Inheritance makes the other very important type of abstraction possible, control abstraction. Now, all that matters is the object in question (possibly even an abstract object, something else very cool) can be passed to a separate method, it's methods operated on, and each of those methods would be doing something else, though the code treats it precisely the same. This is the whole reason interfaces exist in Java. In fact, I'd love to give you an example:
interface InputMe
{
    void run();
}

class First implements InputMe
{
    void run()
    {
        System.out.println("From First");
    }
}

class Second implements InputMe
{
    void run()
    {
        System.out.println("From Second");
    }
}

public class Main
{
    public static void main(String[] args)
    {
        test(new First());
        test(new Second());
    }

    public static void test(InputMe in)
    {
        in.run();
    }
}
In practice, this is amazingly useful, especially when you're working with multiple programmers or you're using a toolkit, both of which are exceedingly common.


Public and private members:
[quote name='DarkLordoftheMonkeys']In my opinion, having members be public and private is just a waste of time. Every variable you create has to have a corresponding set or get function, which adds 3x more lines of code, where x is the number of private variables.[/quote]
Uhh... no they don't? In no way are you required to write get/set functions for properties if interface users won't be accessing that property, so right off the bat your assertion is fallacious. The only reason get/set functions were found to be of any use at all is that if the property was public there's no method to control if that property suddenly changes and other methods in your object rely on it remaining the same. If you funnel set commands through a function, you can make according changes, and the get function is mostly there just to accommodate the set. In C, you have no such mechanism of control like this, and if you do invent one by forcing dynamic allocation, you have to write those get/set function anyway.

Also, Python has made get/set functions effectively worthless.

[quote name='DarkLordoftheMonkeys'] If you want to make a variable read-only, just use const.[/quote]
Like this?
public class MyClass
{
    public final int number;

    public MyClass(int anum)
    {
        number = anum; // After this, number is const.
    }
}

[quote name='DarkLordoftheMonkeys']To add to that, pretty much any language with pointers will allow the programmer unlimited access to private members.[/quote]
Uhh... I'm not exactly sure where you got this silly idea from... let's take a look at C++:
class MyClass
{
    int somenum;
public:
    MyClass(int anum) : somenum(anum) {}

    const int* getSomeNum() { return &somenum; }
};
Since the pointer is a pointer to a const int, the client can't modify it. You can do the same with a const reference as well. What you said was out and out absurd.
[quote name='DarkLordoftheMonkeys']This is what C++ does.[/quote]
Oh, right then.
[quote name='DarkLordoftheMonkeys']That sort of takes away the whole point, and all the set and get functions you created just take up space.[/quote]
Only to a n00b.


Spaghetti code vs. lasagna code:
[quote name='DarkLordoftheMonkeys']Both OOP and procedural languages are susceptible to producing spaghetti code, that is, code in which the control flow is hopelessly unclear.[/quote]
See above.
[quote name='DarkLordoftheMonkeys']OOP languages, however, have an added danger: lasagna code.[/quote]
Any system that has well defined interfaces between two separately operating systems is vulnerable to this, but Lasagna code is more likely to occur with web development or database architectures, so I don't see the relevance with OOP.
[quote name='DarkLordoftheMonkeys']This is when layers are used to such an extent that they practically lose their meaning and are impossible to make sense of.[/quote]
No... the term defines the fact that there are well defined interfaces between systems, but those individual systems that make up the layers are spaghetti-like in nature, there's no organization. This results in easy to use interfaces, but impossible to maintain internal code (See: Open Source Software).
[quote name='DarkLordoftheMonkeys']Procedural languages are in their own way susceptible to the lasagna code effect as well, but it's a lot easier to avoid.[/quote]
No it isn't, because with procedural languages it's considerably more difficult to establish the necessary structure within each layer you wrote to keep them maintainable.
[quote name='DarkLordoftheMonkeys']One primary cause of lasagna code is the abuse of inheritance.[/quote]
No. It's. Not. You. Fail. F. Minus.


Widgets:
[quote=DarkLordoftheMonkeys]Apparently, using widgets to create a GUI makes programs easier to write and more compact. Well, let me show you a very simple GUI program in Java that does almost nothing:

import javax.swing.*;
import java.awt.event.*;

public class SimpleGuiB implements ActionListener{
	JButton button;
	
	public static void main(String[] args){
		SimpleGuiB gui = new SimpleGuiB();
		gui.go();
	}
	
	public void go(){
		JFrame frame = new JFrame();
		button = new JButton("Click me");
		button.addActionListener(this);
		frame.getContentPane().add(button);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(300, 300);
		frame.setVisible(true);
		
	}
	public void actionPerformed(ActionEvent event){
		button.setText("I've been clicked");
	}
}

All this does is create a button that says "Click me", and when it is clicked, the button says "I've been clicked". It isn't even scaled or anything.

I hate Java.[/quote]
Well if you don't take advantage of Java's features, or use any sort of OOP practices while programming in Java, or worse, try and treat Java code like it's C with classes, then yeah, it's gonna suck.
import javax.swing.*;
import java.awt.event.*;

public class SimpleButton extends JFrame
{
    public SimpleButton()
    {
        final JButton but = new JButton("Click me!");
        but.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event)
            {
                but.setText("I've been clicked!");
            }
        });
        add(but);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(300, 300);
        setVisible(true);
    }

    public static void main(String[] args)
    {
        new SimpleButton();
    }
}
See there? I used a "constructor", a thing that would require a separate function call in C, and I'm taking advantage of the garbage collector, another thing C is noticeably lacking. Oh, and there's that d*mned inheritance thing you despise so much! How dare it make my code shorter and easier to maintain?!

[quote name='DarkLordoftheMonkeys']In conclusion, I think that OOP capabilities are good for a language to have, as long as they aren't over-emphasized and don't get in the way.[/quote]
OOP is a paradigm, an entire thought process, not something you just sprinkle onto code you have and figure you've done your part! That's Spaghetti with Meatballs.
[quote name='DarkLordoftheMonkeys']Forcing the programmer to use classes for everything is not good practice (one exception to this is Javascript, in which there are predefined classes and objects that actually do something, without you having to write 20 extra lines of code to use them).[/quote]
That's what a framework is. Y'know, that ** Java you were just criticizing, yeah, it comes with a ** ton of predefined classes for you to take advantage of, try reading the docs some time.
[quote name='DarkLordoftheMonkeys']OOP should be an extra tool that you can use, sort of like the bitwise operators. It should not be the heart and soul of the language.[/quote]
Oh but it should, it so very should. Bitwise operators are nothing compared to OOP. In fact, Bitwise operations are kind of... not really that cool anyway. You can't expect to build an entire software product on the structure of Bitwise operations, you have to have control structures to guide them, and you have to have ways to express these operations quickly and modularly so that they may be both modified and retrofitted to perform new tasks. This is what OOP provides, and Bitwise operations... well they mangle bits.

[quote name='DarkLordoftheMonkeys']Perl is a good OO language. So is PHP. They represent the ideal situation, a balance between paradigms.[/quote]
Did you know you can code OOP in C? Did you also know you can ignore OOP in C++? Did you also know that Python and Ruby allow you to do pretty much any of those, but are both OOP languages?

There are plenty of very good reasons to levy criticism towards Java or C++. One of those reasons is not, however, the choice on the language designers part to emphasize OOP. Simply because you haven't gotten experienced enough to realize why it's so vital to maintaining large interconnected systems (which shows that you've never actually had to maintain such a program), doesn't mean that OOP isn't doing it's job to make writing software easier, more maintainable, and modular. Sorry, DLM, but you've left me unconvinced.
    • 0
I'm sorry, it's just that I've had bad experience with languages like C++ and Java. They seem overly complicated and hard to use. I prefer languages like Perl. I don't mean to upset any fans. Like I said, I have nothing against OOP, I just think it's easy to abuse.
    • 0
Using OOP effectively and well generally involves working with projects that are much larger than the sample programs and exercises that you find in language books. OOP becomes useful when your code reaches significant size/complexity. Unfortunately, you generally need a book devoted to the subject for anything useful to happen.
    • 0
I suggest you use NetBeans to make programs in Java. I'm glad your learning all the basic theory stuff, but really, NetBeans could really help you.
I hate writing GUI's.

Note: Don't get angry if the menu isn't positioned in the upper bar, there is a way to fix it.
    • 0
In my Java class last summer, one of my teammates created the GUI for our project with Netbeans, and it created literally hundreds of class files the first time he compiled it. Fu¬Ęk Netbeans! I'd rather code in machine language.
    • 0
Davide, I agree that writing GUI's can be a pain, but looking at the crappy code generated by a RAD is ten times worse.
    • 0
I think I may have used the term "lasagna code" incorrectly. I believe the generally accepted name is "spaghetti inheritance".
    • 0
**** dark you possibly got pwned. honestly i have no idea. all of this is way over my head.
was a good read though!
    • 0
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download