• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Rickert

What's wrong with OOP?

26 posts in this topic

Recently I read many leangthy articles say how bad OO is. Among those are Paul Graham's and he series of articles on this site: [url="http://www.geocities.com/tablizer/oopbad.htm"]http://www.geocities.com/tablizer/oopbad.htm[/url] (I haven't read all, since I don't have much time). Basically, everything about OO is bad. I failed to see. It may not be the perfect solution, but it's not as they claim. I read a more objective article: [url="http://www.petesqbsite.com/sections/express/issue17/modularversusoop.html"]Modular Programming Versus Object Oriented Programming (The Good, The Bad and the Ugly)[/url], and the author made a good point that certain paradigm is more suitable for certain domains. For example, OOP is very suitable for multimedia and entertaiment industries such as "[size=4]Music software designers, Recording studios, game designers, even book publishers, and video production groups[/size]" . He pointed out that people in these industries tend to think in term of objects more.

What's wrong with building abstraction by encapsulate data and behavior into class, and provide the class as a package to be used as it is without worrying about the details? C does this as well. In C, we also specify a set of interfaces to the client in .h file, implement it in .c, and if the source is proprietary, we can always provide the interface only.

What's wrong with classification? How can you program a game in a procedural or functional way, where it's counterintuitive to model objects in real world? Even Lisp supports OOP as well. In C, we can define low level struct, and if we want to transform one struct to another, we have to base on the memory layout of each struct. We would end up writing OOP feature for automatic transformation anyway.

Because we are talking about paradigm, so we should not be specific about one language, so we don't say thing like the object model in Java is dictated by Object, or C++/Java is too verbose.

Finally, object oriented or whatever is just a way to organize source code. Instead of millions lines of code in our main, we divide it into smaller units and store it different locations (files), and the main only uses a nice interface from these modules (which is usually only one line) to invoke certain functions when needed. The act of dividing and organizing code into logical entities (class, functions, struct...) and physical entities (files, directories) is a logical (science) and creative (art) task. I don't think one paradigm is suitable for every situation.

Can anyone, especially from anti-OO camp explain this to me?
1

Share this post


Link to post
Share on other sites
Because objects in oop rarely work well modeling objects in the real world. Real world objects have too many classifications, or too imperfect classifications to model well in code. Inheritance tends to never work properly. And simply, not everything is an object.

Modern use of oop tends to not be pure. Standalone functions mix with objects. C# has some functional programming bits now at its core for all sorts of method implementation.

But frankly these arguments are often put forward by academics who don't put proper weight to how easy it is for less skilled programmers to think in terms of objects. Objects are particularly inelegant from a computational perspective, so have a very bad reputation with people who focus on that as opposed to Getting Stuff Done(tm).
0

Share this post


Link to post
Share on other sites
[quote name='Rickert' timestamp='1331894194' post='4922545']
Recently I read many leangthy articles say how bad OO is.
[/quote]
I'd suggest reading articles from open-minded professionals about pros and cons of OOP and procedural programming instead..
0

Share this post


Link to post
Share on other sites
Nothing wrong with OOP so long as the problem you're modelling is appropriate for being modelled by OOP. Within that constraint there is only one thing about OOP that really bothers me, and even then it would be fair to say that it's more of a people/culture issue than an issue directly arising from use of OOP, and that is that it can lead to overengineered designs and a tendency for implementation of design principles and patterns taking precedence over the problem that those principles and patters are intended to solve.
1

Share this post


Link to post
Share on other sites
Like others said, strict OOP is probably a bad idea since it isn't smart to artificially limit yourself to one way of thinking if you don't have to. The issues with it are well summarized above. Some of the concepts that came from OOP are so so so useful though, and that's what sometimes gets ignored when this comes up.

Normally, would you rather write an abstract (interface) class and multiple implementations, or would you rather write the functions free-standing and then create arrays of function pointers which then have to be maintained much more carefully?

How about RAII? That requires one to at least put a foot in the door of OOP, even if that's as far as you go.
0

Share this post


Link to post
Share on other sites
OO just has a lot of pitfalls that you can become a victim of, because of the way that it makes you think about data in memory.

For example -- Often, different member functions require different sub-sets of the member variables, and often certain members variables are only used by a small number of member functions. However, if these is all bundled together into a class, then you end up with sub-optimal memory layouts, leading to bad cache usage, leading to bad performance.

Another example is that packaging up all related data into an object forces a particular memory layout upon your users. Often, if someone is uses multiple instances of a class, there is a more efficient memory layout possible for the "[i]more than one object[/i]" case, than OO's "[i]design the layout for a single object[/i]" method provides.[code]//holds a value, which can be marked as 'invalid'
template<class T> struct Maybe
{
T value;
bool isValid;
}
//example usage
class Foo
{
Maybe<int> i;
Maybe<float> f;
}
//which results in the layout
struct Foo { int i; bool iValid; /*char pad[3];*/ float f; bool fValid; /*char pad[3];*/ };

// ideally, we would be using the following layout, but OO makes this difficult
struct Foo { int i; float f; bool iValid; bool fValid; /*char pad[2];*/ };[/code]
2

Share this post


Link to post
Share on other sites
[quote name='achild' timestamp='1331907098' post='4922578']
Normally, would you rather write an abstract (interface) class and multiple implementations, or would you rather write the functions free-standing and then create arrays of function pointers which then have to be maintained much more carefully?
[/quote]

Depends on the problem being solved. Sometimes (a lot of the time) the "arrays of function pointers which then have to be maintained..." consideration just does not even exist. In that case I'd much rather write a freestanding function and call it as required than have to implement all of the standard OOP baggage around it. On the other hand, where that OOP "baggage" makes my job and life easier, then bring it on! :)
0

Share this post


Link to post
Share on other sites
The backlash against OOP is justified in some ways but misguided in other ways. Applying OOP to some problem which doesn't have a natural object structure is a mistake, so it is also a mistake to design languages that more-or-less force you to do this, such as Java. However, when it's a good fit it can be extremely elegant.

I think what happened is that when OOP was born, it grew up hand-in-hand with a large software problem for which it was a particularly good fit and this led to a view that object-oriented design was the solution to all large software problems. The "large software problem" that I am talking about is the implementation of graphical user interfaces. OOP makes sense for this problem because it is easy to view GUI widgets as a hierarchy of objects that inherit from base classes that are composed together. You have a base widget class that supports abstract methods for the ways a user might interact with a widget then a button is a kind of widget, a check box could be a kind of button, and so forth. Then users of the widget framework can do "smalltalk-style" OOP in which to make a button to do something application-specific they inherit from an abstract button class and provide a button click handler that does something application-specific. This kind of object-oriented design, which I'm calling smalltalk-style, is not in current vogue, but I think it was the original idea about the way this sort of thing was to be done.

All of that kind of stuff came out of Xerox PARC in the 70's where I think Alan Kay was at the time and Alan Kay is considered one of the fathers of OOP so go figure.

off-topic: I'm looking at the links provided in the original post ... Geocities sites still exist? I thought they were all shut down years ago?
0

Share this post


Link to post
Share on other sites
@Hodgman: Thanks for provide the low level point of view. It's nice to know such disadvantage for coupling between functions and data, which I never think of before. However, I don't understand the 3 empty bytes for padding? Shouldn't all variable be contiguous?

One of the complain about OO is that it does not reflect the real world because not everything in the eral world is object. However, I think people play with word on this one rather focus on the idea. Let's not call it object, but call it concept. An object in OOP reflects a real world concepts, not an object as in noun. For instance, kicking is an action which can be modeled by a class named Kick along with its attributes to present it as a concept:

[CODE]
class Kick{
private:
int velocity_;
int force_;
public:
Kick(int velocity, int force):velocity_(velocity),force_(force){}
virtual ~Kick(){}

void high(Fighter target){ /*implement high kick */ }
void mid(Fighter target){ /*implement mid kick */ }
void low(Fighter target){ /* implement low kick */ }

int get_velocity() const { return velocity_; }
int get_force() const { return force_; }
};

class Fighter{
private:
int health_;
int ki_;
Kick kicking_stance_;
public:
enum AttackPosition {
high,
mid,
low,
};

FIghter(int health, int ki, int kick_stance):health_(health), ki_(ki), kicking_stance_(kick_stance){}
virtual ~Fighter(){}

void kick(Fighter target, AttackPosition pos){
if (pos == high) kicking_stance_.high(target);
else if (pos == mid) kicking_stance_.mid(target);
else kicking_stance_.low(target);
}
};
[/CODE]

So, what's the problem here? I think one of the reason people complain that is, Kick is not an object in real world itself. Only live entity like human, horses can kick. Another example is, if I got an Invoice class, should object of invocie, invokes actions like invoice.save(), invoice.send()? For this reason, we have patterns, design and design principles because pretty much people can invent different ways to present a concept. As a consequence, OO is accused for low reusability, despite the abstraction is for concept reusability. In the example above, other people might put Kick concept inside an abstract class Fighter, while other might define the MartialArtStyle abstract class, and put kick action inside it as a abstract method. For this reason, it's more difficult to reuse, since if there's a more complicated object system, a member function of an object may operate on the abstract data type of that object, and inside the abstract data type, it operates on other abstract data types as well.

This is what I got from the articles. Correct me if I'm wrong.

However, I still don't think it's the fault of the paradigm, but rather, the language. Let's consider another scenario:[list]
[*]An ancient wizard has a powerful spell which can turn objects (such as tea cup) into living entity like human being.
[*]There's a tea cup in front of him
[*]The old wizard casts the spell on the tea cup to make it live.
[/list]
In language like Java, the problem is that I have to plan ahead for TeaCup object. If I want to have a tea cup to behave like human, I have to:[list]
[*]Write an interface for shared human behaviors, such as talk(), walk(), and let TeaCup implement it.
[*]Since not all TeaCup can talk, and I want to model the real work closely so other can understand, the TeaCup must not always talk.
[*]So, I define a TeaCup hierarchy, which (for simplicity, I will create one) has TalkingTeaCup inherits from TeaCup (which is the normal one), and implements the shared human behaviors interface.
[/list]
Look at this way of constructing concept, we can see that it creates overhead. In this case, instead of a tea cup with has varied behaviors, we got different versions of TeaCup which varies a little in behaviors. This is just another simple case. Imagine if it applies for a large and complicated system.

There's no way for me to keep the TeaCup object as simple as it is, because TeaCup is a TeaCup, it can't operate on it own until the wizard gives it a life. Thus, TeaCup must not contain any related behaviors to make it "lively" (to prevent issue like whether invoice should save() / send() or not). Dynamic behaviors will be added later after the wizard casts life spell on TeaCup.

I don't think we can add methods to TeaCup if we don't write it in class or implement via interface. Although, Java can dynamically add more class with varied parameter at runtime with Dynamic Object Mode (which we have to do more work)l: [url="http://dirkriehle.com/computer-science/research/2005/plopd-5.pdf"]http://dirkriehle.co...005/plopd-5.pdf[/url] . In C, we can have an array of function pointers, however, this approach is not convenient, since it operates on low level, so it's error-prone and it is strong typing, which make it less flexible.

With function as first class object, it creates a more elegant way to solve the above problem. Consider this piece of Lisp code (I'm learning, so pardon me if it's not elegant) written for this scenario:

[CODE]
//I have to use C comment because our forum does not support Lisp comment style.

//collection of wizard spells. In Lisp, a variable is just a list, which might be a single value, or a list of symbols/values/[b]functions[/b]
(defparameter *wizard-spells* nil)

//class object with its attributes consists of name and action
(defstruct object name action)

/* This is the wizard spell for giving an object a life. Here you can see, upon calling this function, it will add function talk and walk into the variable action of the class object */
(defmethod giving-life ((o object))
(princ ( type-of o))
(princ " is now as lively as human!")
(push #'talk (object-action o))
(push #'walk (object-action o)))

//wizard spell for making an object become poisonous, so if someone contacts with the object, they will die a moment later
(defmethod poison ((o object))
(princ ( type-of o))
(princ " is covered with poison."))

//talk action, which is a human behavior
(defun talk ()
(princ "Hello I can talk now"))

//walk action, which is a human behavior
(defun walk ()
(princ "Hello I can walk now"))

//add spells to spell collection of the wizard
(push #'giving-life *wizard-spells*)
(push #'poison *wizard-spells*)

//create a teacup
(defparameter *tea-cup* (make-object :name "TeaCup" :action nil))

//funcall will execute the functions inside the variables.
(funcall (nth 1 *wizard-spells*) *tea-cup*)
(funcall (nth 0 (object-action *tea-cup*)))
(funcall (nth 1 (object-action *tea-cup*)))
[/CODE]

In sum, OOP creates or more flexible way for "creativity" (in which we call design, where people can create different abstractions for the same concepts. This might be a good or bad thing). Those are the ideas I "suddenly" got it after practicing with Lisp for a while. Not sure if it's to the point or not, so If you guys can verify it, I am really thankful.
1

Share this post


Link to post
Share on other sites
Part of it comes down to this: OOP applied to the correct problem in the correct way is pretty great -- OOP applied to the incorrect problem in the correct way, or the correct problem in the incorrect way is hell, and OOP applied to the incorrect problem in the incorrect way will make you want to shoot yourself in the face (or at least throw away all the code and start over [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img]).

OOP languages tend to be much more unfriendly to re-factoring (especially if the original factoring violated OOP principles like SRP) -- bad OOP tends to be made up of unruly hierarchies, tightly-coupled classes, and metaphors that have been stretched to the point of breaking -- It's a mess to clean up. Other paradigms tend to either be more flexible (by focussing less on rigid structure) such as procedural languages like C, or to strongly discourage poor design from the first line of code (either by force or by accepted idioms) such as functional languages like Haskell.

There's also a correlation between approach-ability in a language, and the quality of its practice. That is, the type of people who are capable of thinking about anything non-trivial in a functional language are rather few, hence elite, and so the community around, say Haskell, is rather strongly made of very intelligent people -- even relative idiots who stick with Haskell long enough will pick up good practices. On the other hand, the type of people who can think about problems using an "object" metaphor are common (in part due to industry/accadamia focus on OOP) and so they are not necessarily the cream of the crop to begin with, hence the number of elite member of that community relative to the total size of the community is not high enough to provide the sort of "herd immunity" that languages with a higher ratio of elites exhibit. In short, more elite communities discourage poor practice, while broader communities tolerate (or even promote, in the new/less-educated factions) poor practices.
0

Share this post


Link to post
Share on other sites
[quote name='Rickert' timestamp='1331924006' post='4922645']
@Hodgman: Thanks for provide the low level point of view. It's nice to know such disadvantage for coupling between functions and data, which I never think of before. However, I don't understand the 3 empty bytes for padding? Shouldn't all variable be contiguous?
[/quote]

It has to do with memory alignment, in c++ (on x86 atleast) objects will be aligned to the nearest 4 bytes, This is because the CPU has a 4 byte word size and always fetch memory in chunks that start at an even 4 byte offset, (if the memory isn't aligned then performance will be worse)
[url="http://en.wikipedia.org/wiki/Data_structure_alignment"]http://en.wikipedia....cture_alignment[/url]

This is all well and good when you work on single objects, However, the general case tend to be to have multiple objects of the same type that you work with and then the extra padding results in less efficient use of the cache. (bigger objects means you'll fit less objects in the cache), also, if you are going to update 300 enemies it is likely that you will run the update method for all of them and change the position of all of them, Thus it is better for the cache to have enemy positions stored close to eachother.

Data oriented design attempts to solve this by having you structure your data based on how it is used rather than what it represents.(Enemies class with a vector of positions and a single method to update all enemies) rather than an Enemy class that you store in a vector for example)
This is in my opinion alot harder to do intuitively (simply replacing a vector of objects with an object with vectors isn't always optimal either (if you have both a velocity and a position then you probably want to store it something like x,vx,y,vy,z,vz using a single vector (as the velocity is usually added to the position it helps to keep it close) while for example the health value is better stored on its own or maybe close to the armor value.).

It really is all about tradeoffs, OOP is a way to keep large projects from collapsing under their own complexity and it is very good at it when done right, Sometimes other paradigms can make code clearer(Not everything can be cleanly modelled as a set of objects) and sometimes you have to sacrifice clarity for performance but OOP is a reasonably decent default choice.
1

Share this post


Link to post
Share on other sites
[quote name='SimonForsman' timestamp='1331940672' post='4922698']
(if you have both a velocity and a position then you probably want to store it something like x,vx,y,vy,z,vz using a single vector (as the velocity is usually added to the position it helps to keep it close)
[/quote]
No you wouldn't. You might have them adjacent, but even then that's doubtful. You will be more likely to have two separate arrays, one for position and one for velocity. Having them interleaved the way you showed would be the worst case option, as it eliminates almost any possibility to use SIMD or any other vector instructions (on your choice platform) to perform the operation.
1

Share this post


Link to post
Share on other sites
Even ignoring SIMD, interleaving like that makes no sense. In your typical game, you might update the position once per frame per object from velocity, whereas there's a ton of use cases that can end up at higher use counts where you simply don't care about velocity and it's merely wasting cachelines and memory bandwidth at best:

Rendering (both for culling and for setting up transforms)
AI (pathfinding, LOS / sight distance checks, target prioritization)
Gameplay (distance based damage calculations like AoE falloff, fog of war calculations)

With seperate arrays, you're potentially halving your required cache/bandwidth from getting positions if you only care about the position.

Interleaving can speed things up by reducing bandwidth during random access when you're using all the fields, but even then you're going to gain less than nothing by interleaving on a per-component basis.
1

Share this post


Link to post
Share on other sites
I think the reason why OOP gets dumped on a lot is because of the examples people use when explaining how OOP should work. These examples are ridiculously contrived and if you coded them in a non OOP language it would take half the code or less and be easier to read.

Things like classifying animals like cats and dogs to show inheritance, or representing a car as a vehicle with a certain number of wheels. ARGH!

I think if you can grok the idea behind OOP and get past trying to model real world objects as classes, OOP can make coding (and maintenance) of complex systems MUCH easier. That said, OOP is no silver bullet. It's like saying "Concrete is the best construction material". There's plenty of situations where that is a colossally bad idea, like say when you're making a car or a rowboat. The same applies to OOP.
0

Share this post


Link to post
Share on other sites
[quote name='Washu' timestamp='1331950198' post='4922730']
[quote name='SimonForsman' timestamp='1331940672' post='4922698']
(if you have both a velocity and a position then you probably want to store it something like x,vx,y,vy,z,vz using a single vector (as the velocity is usually added to the position it helps to keep it close)
[/quote]
No you wouldn't. You might have them adjacent, but even then that's doubtful. You will be more likely to have two separate arrays, one for position and one for velocity. Having them interleaved the way you showed would be the worst case option, as it eliminates almost any possibility to use SIMD or any other vector instructions (on your choice platform) to perform the operation.
[/quote]

Good point, i didn't think of simd at all and as mauling monkey correctly notes, the normal usecase for games is different aswell.
0

Share this post


Link to post
Share on other sites
[quote name='Promit' timestamp='1331962593' post='4922756']
A lot of problems with OOP stem from the way it is badly mis-taught to programmers. The recent push for data oriented design is related, but it isn't quite the same. The trouble is that object oriented programming [i]as presented in most educational material[/i] is badly flawed. It does not reflect real world usage of objects, it does not reflect real world problem solving, and it certainly isn't a good way to think about code.[/quote]
Can you please give an example between simple which "does not reflect real world usage of objects" (such as Animal, Shape, Car examples) and real world examples how OOP is applied.

[quote]We learn in school and in books that object oriented programming is invariably applied to logical, human based objects. I've heard this referred to as "noun-based" design, and frequently imposes constraints that have everything to do with a human abstraction and nothing to do with the technical problem we're dealing with. The problem is further exacerbated by is-a and has-a relationships, UML diagrams, design patterns (GoF), and all that other crap that passes for "object oriented software engineering". Then you wind up with projects like Java, blindly applying the OO principles in the most pointlessly abstract terms imaginable.[/quote]
Underlying of human abstraction is still the technical problems we have to deal. What's wrong with creating a high level point of view which is close to human, and solve its technical underneath?

[quote]And to top it off, most of this code never turns out to be "reusable". The biggest promise of OOP simply does not deliver. And the tight coupling headache leads us down a whole new rabbit hole of design patterns, IOC, and stuff that lands us so far in abstracted land that we've lost sight of what it was we were trying to do. I understand why the guys who think we should have stuck to C feel that way, though they are misguided.[/quote]
Can you give an example how OOP is not reusable? I think if something which can be packaged into libraries and is independent of any application code, it is already resuable? With this definition, resuable is presented in any language and programming paradigm? Or is OOP [i]less[/i] [i]resuable?[/i]

Finally, I wonder, if OOP is so bad, why is it so widely used, especially in game industry (this is what I read and heard of)?
0

Share this post


Link to post
Share on other sites
[quote name='Rickert' timestamp='1332144540' post='4923222']
Underlying of human abstraction is still the technical problems we have to deal. What's wrong with creating a high level point of view which is close to human, and solve its technical underneath?
[/quote]
For me the GameEntity is a good example. From the "human high level point of view" it sounds fine to say "See, a tree is a GameEntity, the player is a GameEntity, NPCs are GameEntities". But then you end up putting this insanely bloated interface on the GameEntity and somehow trees end up with interfaces for conversations etc.


[quote]
Finally, I wonder, if OOP is so bad, why is it so widely used, especially in game industry (this is what I read and heard of)?
[/quote]
It's not so much that OOP in general is bad, but it often gets blindly applied even when it is not a good fit for the problem at hand.
1

Share this post


Link to post
Share on other sites
I see OOP as a collection of capabilities I can take advantage of in the language i'm using. If it makes sense to use iheritance, use it. If it make sense that a framework should use overloaded/overriden methods, do it, if it doesnt, dont do it. OOP is just another tool in your toolbox, treat it as such. Know how that tool works, and what its best used for and you'll never use it wrong. Same can be said about Declaritive, Functional, Reactive, etc methodologies. Use them when it makes sense for the problem at hand, otherwise use something more appropriate.
1

Share this post


Link to post
Share on other sites
There is nothing wrong with OOP per se. It is simply a design methodology suited to a certain problem domain.
The problem I see however is the "OOP or die" mentality shown by various (often inexperienced) programmers.
As the saying goes "[i]If the only tool you have is a hammer, every problems looks like a nail[/i]" or something like that...

[b]I think the biggest flaws of OOP (or rather, how it is generally misused) are:[/b]

* The tight coupling of data and functionality. It makes sense in some cases but many algorithms are not dependant on type. This is where templates, generics, operator overloading or function overloading in general come in handy. Generally I try to put as little advanced functionality in the class as possible. If a method does not access private state or takes class instances as parameters it is a candidate for extraction.

* The strict taxonomy created by inheritance. Subclasses are disjunct sets. You can overcome this problem by either stuffing more functionality in the base class (bloat), using multiple inheritance (hard to manage, not supported in many languages) or separating orthogonal class concerns. By doing the latter you end up with smaller, more manageable pieces that don't usually resemble "your typical" OOP design.

[b]However, there are alsosome nice things about OOP:[/b]

* Encapsulation. By defining explicit entry points into the maintained data, producing stable code should be easier.
* Interfaces. Separating algorithms from representation. Unfortunately a little expensive at least in C++.
1

Share this post


Link to post
Share on other sites
OOP moves knowledge into code. Yet code is worthless and transient, the knowledge is what matters. That is why we have file systems and databases. They outlive any language.

[quote]Interfaces[/quote]
OOP does not require strong typing or typing at all. Original definition of OOP talked about opaque messages being sent and messages not being understood were a part of definition.


The cache issues are caused by today's language's interpretation of OOP. There is precisely nothing preventing anyone from encapsulating such knowledge in OO manner. Bigger scalability issues come from incorrect abstractions, not OOP itself. Just like words aren't good or bad, it's how they are composed that determines that. Encapsulation as part of OOP only gives excellent opportunity for optimization by being explicit about dependencies - limitations are caused by mainstream languages in use today. IOC and DI solve the same problem as applicable to maintenance of software by making code transient and putting emphasis on interaction between data.


One of bigger harms which cemented fate of OOP was Java. By going over the list of 10 fallacies of network programming, they made sure Java standard library (not the language) commits every single one of them. C# is now trying to patch things a bit through async/LINQ and while decent, it's evolutionary change. If those fallacies applied to network programming, they apply to all layers today, cache, disk, network and any other hardware resource due to von Neumann bottleneck.
1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0