Classes: Possible to overdo it?

Started by
25 comments, last by caseyd 15 years, 9 months ago
Quote:Original post by Alastair Gould
You should not mix OO and procedural methods of programming.


I respectfully disagree.
Advertisement
This is my University education speaking, We've always been taught this.

You also have to remember that you can do OO without classes i.e c. It the way its designed is OO.
Quote:Original post by Telastyn
Quote:Original post by Alastair Gould
You should not mix OO and procedural methods of programming.


I respectfully disagree.

Seconded.

In a multi-paradigm language, like C++ for example, you have the freedom to select the appropriate tools and mindset from a variety paradigms (procedural, OO, generic, functional, aspect, ...) to most cleanly solve the problem at hand.
Trying to design a program formally on paper you will realise designing procedurally has completely different steps and methods than OO.

I used to think that OO and procedural methods can mixed, but now being taught formally has taught me why this can be a bad method.

The diagramming and layout of programs is completely different for a start.

Functional programming can be mixed in well. I've always written most functions/methods like that.


But oo and procedural completely change the big picture of the program.
How do you represent, say, sorting with 'pure OO'. That is, without procedural methods?

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

I came out of school about two years ago and have been working a computer game programmer during that time. In this time I have changed my way of looking at OOP a lot. Let me take and example of something that seems to be a common example of OOP programming

// C++ that is not tested in a compiler

class Animal
{
public:
virtual ~Animal() {}
virtual void cry() = 0;
};

class Dog : public Animal
{
public:
void cry() { std::cout << "Bark!"; }
};

class Cat : public Animal
{
public:
void cry() { std::cout << "Mjao!"; } // Swedish cat sound
};

After I gained some experience i realized how bad this really is! Virtual functions are the very core of OOP programming. At least in C++. Still there is a much better solution:

class Animal
{
public:
Animal(const std::string& cry) : m_cry(cry) {}
void cry() { std::cout << m_cry; }

private:
std::string m_cry;
};

The code has now become data driven instead of hard coded in a class hierarchy. There is no inheritance, only information. You can imagine how easy it is to make the Dog and Cat and other animals using a text file without touching the code.

It is often said that OOP is about hiding information but I think this is wrong. The point is to hide the way that information is stored. An std::vector is not hiding the information that you put inside it but it makes the handling of the data easier and safer. When you are going to save information to a file, or send over a network, transmit to another thread, or even display in a GUI, then you need to handle data. Preferably through some interfaces to hide implementation details.

There are many problems that just don't make sense as objects. For example the sin() function or a function that splits a string at the spaces. Even Java has static functions. The static functions are procedures and the class keyword is only used as a namesapce. Procedures are necessary.

I think my point is that you should use OOP to make plugins or frameworks or keep invariants (like std::vector). Use OOP when it is useful. Don't care what OOP programmes says that have just learned what design patterns are and think that they are smarter than others. I call them OOP snobs. Use both OOP and procedural code. If that makes you _not_ getting a job at a company I think you deserve better places to work at anyway! A company where programmers likes to get real work done.

I can write more because I am actually quite upset about that OOP has been so hyped and taught in the wrong way. At least in my school. Not that it is bad... But this is enough for tonight.
@jonathanjansson: Whilst you're largely right, just some comments...

Quote:Original post by jonathanjansson
Virtual functions are the very core of OOP programming. At least in C++.
Virtual functions are the core of polymorphism in C++. Polymorphism is just one aspect of OOP, others include encapsulation, modularity, inheritance, abstraction, SRP, LSP OCP and ISP.

Quote:It is often said that OOP is about hiding information but I think this is wrong. The point is to hide the way that information is stored.
This is encapsulation.

Quote:An std::vector is not hiding the information that you put inside it but it makes the handling of the data easier and safer.
Of course a std::vector is really a better example of generic programming rather than object oriented programming. Also, a std::vector does hide the implementation details of a dynamic array and associated memory management.
Quote:
Trying to design a program formally on paper you will realise designing procedurally has completely different steps and methods than OO.


So I can write an actual, real program that mixes different paradigms and solves every problem using the optimal solution, but I can't design it on paper? If that's the case, then what's wrong is the way you design it on paper, not the other way around.

Quote:
I used to think that OO and procedural methods can mixed, but now being taught formally has taught me why this can be a bad method.


Why?
Quote:Original post by dmatter
@jonathanjansson: Whilst you're largely right, just some comments...

Quote:Original post by jonathanjansson
Virtual functions are the very core of OOP programming. At least in C++.
Virtual functions are the core of polymorphism in C++. Polymorphism is just one aspect of OOP, others include encapsulation, modularity, inheritance, abstraction, SRP, LSP OCP and ISP.

Quote:It is often said that OOP is about hiding information but I think this is wrong. The point is to hide the way that information is stored.
This is encapsulation.

Quote:An std::vector is not hiding the information that you put inside it but it makes the handling of the data easier and safer.
Of course a std::vector is really a better example of generic programming rather than object oriented programming. Also, a std::vector does hide the implementation details of a dynamic array and associated memory management.


Thanks for the reply. I am not familiar with those abbrevations, maybe if you spell them out i will know them?

I think a problem is that OOP is not very well defined. OOP means different things for different people and programming languages, which makes the discussion more difficult. I agree that inheritance and abstractions are typical OOP features which in C++ are implemented using virtual function.

I think that OOP takes too much credit for what really is sane programming practice. For example encapsulation. Any good C API uses opaque structures and a few functions. An opaque struct is in my opinion even safer than a private section in C++. The reason is that a pointer is always safe to keep on the stack but keeping object itself is not if the members would change.

Another iteresting thought it that if you would replace all private: and protected: declarations with public:, would the code not be object oriented anymore? If restricting access to variables is not an OOP feature, then I think that C++ does not bring much more than virtual functions (which enables polymorhism, inheritance etc.) to the laguage from an OOP perspective. Templates and RAII, better type safety are not that related to OOP I think.

I think that std::vector is an example of both encapsulation and generic programming which proves the point that most people here tries to make. OOP is only one technique among many. It is a good way but not the only way. Generic programming is another good way. So is procedural and functional and relational etc.
Quote:Original post by jonathanjansson
I am not familiar with those abbrevations, maybe if you spell them out i will know them?

Sure can [smile]

Single Responsiblity Principle - SRP
Open Closed Principle - OCP
Liskov Substitution Principle - LSP
Dependancy Inversion Principle - DIP (missed this one last time)
Interface Segregation Principle - ISP

I'm sure some of these can be reinterpreted for other paradigms too, but you will find these principles are frequently associated with Object Oriented Programming (*sneakily borrows links from ToohrVyk*).

Quote:Another iteresting thought it that if you would replace all private: and protected: declarations with public:, would the code not be object oriented anymore?

I'd say it would be less (not!) encapsulated and so less object oriented.

This topic is closed to new replies.

Advertisement