Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In Martin Fowler's book Refactoring, Fowler speaks of how when developers learn something new, they don't consider when it's inappropriate for the job:

Ten years ago it was like that with objects. If someone asked me when not to use objects, it was hard to answer. [...] It was just that I didn't know what those limitations were, although I knew what the benefits were.

Reading this, it occurred to me I don't know what the limitations or potential disadvantages of Object-Oriented Programming are.

What are the limitations of Object Oriented Programming? When should one look at a project and think "OOP is not best suited for this"?


migration rejected from Sep 24 '15 at 0:50

This question came from our site for professional and enthusiast programmers. Votes, comments, and answers are locked due to the question being closed here, but it may be eligible for editing and reopening on the site where it originated.

closed as too broad by MichaelT, Pieter B, jwenting, Snowman, durron597 Sep 24 '15 at 0:50

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.If this question can be reworded to fit the rules in the help center, please edit the question.

The closest potential duplicate I found was Pitfalls of Object oriented programming whose answers are more about hardships when using OOP - not about when not to use it outright. – LeguRi Feb 27 '11 at 13:48

It is easier to list domains for which OOP fits well. There are not that many. All the other domains can't be properly expressed in terms of OOP.

To name a few exceptionally unfit areas:

  1. Compilers - representing ASTs and graphs; Pattern matching does not go well with OOP.
  2. Most of the numeric and symbolic mathematics - functional approach fits better.
  3. Business rules - logic/constraint programming is a much better fit here
  4. Anything that can be expressed as a state machine
  5. Graphics. Yes, yes, all the OOP textbooks contains mandatory examples. Square is a subclass of a rectangle, and all that bullshit. The best graphical DSLs are not OOP at all.
  6. Concurrency. In fact, messages in OOP were supposed to be asynchronous. But they are not. So, scrap the OOP, it can't be properly used in a highly parallel setting.
  7. Anything that can be expressed in a dataflow semantics. OOP does not fit it at all.
  8. Anything that is better expressed using the term rewriting systems.
SK-logic: (1) Smalltalk's compiler is written in Smalltalk. (2) Function and OO are not opposites. Go read William Cook's work. (6) Erlang, as OO as they come. (Just ask Joe Armstrong.) I can't be bothered to list counters to the rest. – Frank Shearar Feb 27 '11 at 22:03
@Frank Shearar, most of the Smalltalk implementations I've seen are trivial (and needless to mention that Smalltalk syntax is almost as minimalistic as S-expressions). Think of a more complex compiler. And, as I said, if messages were asynchronous, OO will be a perfect fit. Unfortunately, they aren't, and Erlang is not a classic OO at all. For numeric, you simply don't need OO. And it certainly will harm if you start expressing your problem domain in useless and alien terms. – SK-logic Feb 27 '11 at 22:46
@SK-logic it sounds that you're saying that OOP's bad for writing compilers because it's hard to add operations to the tree walkers. Yes, and it's easy to add new nodes. (The classic trade-off between ADTs and objects.) So since one (probably) adds operations - new ways of walking the AST - more often than extending the language - adding new types of nodes - you're probably right. – Frank Shearar Feb 28 '11 at 10:02
@SK-logic by which you mean "you can implement a non-OO language within an OO language", in which case my point still stands: OMeta, a parser/compiler generator/tree transformer, is written in Smalltalk, an OO language. – Frank Shearar Feb 28 '11 at 14:54
@Frank Shearar, probably we're using different definitions of what "ill-suited" is, but something that is "ugly and annoying" perfectly fits into my definition. And being "easy" does not help. – SK-logic Feb 28 '11 at 20:16

Very small programs

When ever a program does something extremely simple and doesn't last long (think quick command line programs), the overhead of OOP and the OOP spaghetti you must use becomes too much of an overhead. Half your code shouldn't be OOP baggage.

+1 This is why I started using Python. For small scripts a language which enforces OO just sucks (see – Oliver Weiler Feb 27 '11 at 23:25
@Helper - but Python supports OOP! Of course the principle holds, but Python is a bit of a misleading example. A big advantage in Python compared with non-OOP C is that you have all these prepackaged libraries at your fingertips - you get more value from less code because you're standing on giants shoulders. C has libraries for anything you can think of, of course, but you get all these packaging-things-to-work-together issues before you can start coding. – Steve314 Feb 28 '11 at 4:52
@Steve314 Python supports OOP, but it can be used with other programming styles. I bet TheLQ meant those other styles in his answer. – Andres F. Oct 29 '12 at 13:24
@OliverWeiler Just FYI, the link no longer exists. Didn't seem worthy of flagging, but still just saying. – Arc676 Sep 14 '15 at 10:51

From experience, I haven't found a situation where OOP wasn't appropriate, but have found places where OOP was overused or misdesigned. Roughly put, deep down, OOP is syntactic sugar and a code organization schema. Overusing it may, in some cases, trigger an unnecessary sense of frustration and complexity. Most over-designed pieces of code I find tend to overuse OOP concepts.

Another trouble of OOP is when developers don't know about it, something that is way common in some development environments. The approach can sometimes be mocked, frowned upon, angrily rejected or perceived as without sense. Again, personal experience here at work.

Apart from these instances, there are places where other approaches may be better suited to describe your problem. For example, declarative languages aren't OO-based, but are incredibly efficient and idiomatic in their expression of some problems.


Rather than trying to find what OOP is ill-suited to, perhaps it would be more productive to look at some alternatives like functional programming, generic programming and aspect-oriented programming, and considering what they do particularly well and areas where they provide advantages over OOP.

Compared to generic programming, OOP requires that you define a relationship between types, even if there is none. In reality, "debt" and "rainbow" don't have much in common -- but if we're going to use them in Java (for example), they're going to have some common traits that most normal people would never associate with either one (e.g., hashCode, wait, and notify).

In theory the classes at the bottom of the hierarchy are concrete and those at the top abstract. In reality, as you get close to the top of the hierarchy, classes rarely represent a meaningful, coherent abstraction -- rather, they represent the the union of the requirements of a miscellaneous set of lower-level classes that somebody decided needed to be able to apply to all the other classes (e.g., the aforementioned hashCode, so you can store any object in a hash-based collection). I don't mean to pick on Java in particular here either -- .NET is similar in this regard, and Smalltalk is (if anything) considerably worse -- when you get to the base of its hierarchy, you have a "knot" that almost nobody even attempts to understand; a pretzel is hardly twisted all compared to what your mind has to do to fool itself into believing that mess represents anything even similar to a coherent abstraction of anything!

Generic programming does away with specifying a common base class to represent the set of operations required by a particular collection or algorithm or whatever. Instead, you define a set of requirements, and work with anything that meets those requirements. This, of course, can have consequences of its own -- e.g., mistakes with C++ templates are notorious for producing error messages that contain reams of meaningless garbage.

Aspect-oriented programming deals with a somewhat similar problem, but in a considerably different way. AOP is generally concerned (at least primarily) with cross-cutting concerns. A classic example is security. In a typical program, you end up with security-oriented code scattered throughout the program, "tangled up" with implementations of everything else. This means when/if you want to modify the security aspects of the program, you typically end up having to look at nearly everything else. AOP attempts to address that so you can move all the security code into its own, independent module, and specify points in the main stream of the code where the security code will be injected (so to speak) to do its job.

Functional programming can address a couple of completely different areas in which OOP is (or can be) weak. One is the ability to formally prove correctness -- lack of side effects makes formal proofs (and reasoning in general) easier. Note, that this is frequently misstated as "possible" rather than "easier" -- but this is incorrect. Formal proofs are possible in the presence of side-effects, but they are substantially more difficult.

Functional programming also limits communications between different parts of the code (for the most part, the only incoming communication is a function's parameters, and its own outgoing communication is the return value). This can be extremely useful for things like distributed systems. It's relatively easy to detect exactly where communications will be needed, and what parts of the system can run in parallel.

I'll just say the reams-of-error-messages issue isn't a generic programming issue so much as a C++ issue. Concepts would be nice, but we won't be getting them for a while yet. Based on a superficial understanding, Haskell has a generic-programming type system similar to templates-with-concepts, but already working. There's plenty I don't like about Haskell, but the generic programming model isn't in that set. On AOP, when I looked at it I saw a good idea, but I also saw that one hammer being used to bang in every screw IYSWIM. – Steve314 Feb 28 '11 at 5:00
@Steve314: Quite true -- the lousy error messages aren't necessarily endemic to generic programming, but they do point toward the difficulty in implementing it well. Yes, I've seen a bit the same with AOP, but its being misused doesn't invalidate the concept or make OOP handle those situations any better. – Jerry Coffin Feb 28 '11 at 5:35
In C++, debt and rainbow classes would not normally have any connection. We like shallow inheritance diagrams and independent classes. – David Thornley Feb 28 '11 at 15:38
@glenviewjeff: How exactly would you create these classes so they didn't inherit (at least indirectly) from java.lang.Object? I was rather under the impression that all classes in Java inherited from Object. The point here isn't whether it's better to model the commonality via inheritance or interfaces, but to realize that there is no commonality at all, but Java forces an inheritance relationship (tight coupling) even though in reality there's no relationship between the types at all. – Jerry Coffin Jun 20 '11 at 3:32
"Perhaps it would be more productive to look at some alternatives... and consider... where they provide advantages over OOP". That's an insightful approach. +1 for this alone. However... – Kramii Oct 29 '12 at 13:31

In a comment to an answer to another question, Frank Shearar pointed me to On Understanding Data Abstraction, Revisited by William Cook. This line seems particularly relevant:

Reynolds noticed that abstract data types facilitate adding new operations, while “procedural data values” (objects) facilitate adding new representations. Since then, this duality has been independently discovered at least three times [18, 14, 33].

We always like to use abstraction to allow for extensibility, but there's a fundamental distinction between abstracting to allow new implementations of a message receiver (objects), and abstracting to allow new operations to apply to the same data representation (ADTs). OOP is good for the former; functional (and maybe procedural?) languages tend to be better at the latter.

I read about this, and found it to be a poor expression. I interpret it like this (perhaps wrongly?): "Procedural code allows you to extend functionality by adding one function which supports behavior for all the required data structures. OO code, on the other hand, requires you to add the new function to all the different data structures. Procedural code makes you adjust all functions to support a new data structure. OO code makes you implement a new function in all data structures.". I discussed it on my blog. – Steven Jeuris Feb 27 '11 at 20:36
Key here is OO enforces a correct implementation while procedural doesn't. Also, an OO approach provides more cohesion. Anyhow, thanks for the link to the paper, It'll be an interesting read! – Steven Jeuris Feb 27 '11 at 20:49
@Steven - look into type classes. These provide type-level rigor to ADTs, enforcing correctness and improving cohesion just as effectively as object-types can, IMO. – Aidan Cully Feb 27 '11 at 22:06
OO absolutely does not enforce a correct implementation! – Frank Shearar Feb 27 '11 at 22:09
Another of Cook's papers might shed more light on the topic, which is more explicit in the tradeoff between ADTs and objects: – Frank Shearar Feb 27 '11 at 22:10

Object oriented programming is poorly suited to tasks where individual items or collections of data are not the most useful level of abstraction.

For example, when defining a mathematics library, one notices that there are a lot of binary operations: x dot y and M*x and so on. The level of abstraction isn't the data (matrices and vectors) so much as it is the operations of inner and outer product, tensor multiplication, and so on. So you will see, for example, Java matrix libraries where the operations are classes (?!). Functional programming provides a more comfortable fit, but even plain function calls provide a more sensible framework than hierarchies of classes that don't correspond to any data.

Object oriented programming is also poorly suited to tasks where the Liskov substitution principle fails to hold. In particular, subtracting functionality is not something that OOP techniques handle well. Birds fly--except for flightless birds!

And OOP is poorly matched to situations where giving commands is the most natural thing to do. cp my_file.txt that_file.txt is a more natural fit conceptually than "my_file.txt".copySelf("that_file.txt"). The file isn't doing the copying. The file is sitting there. It's the OS and file subsystem handling it. But you don't want to have to filesystem.cp("my_file.txt","that_file.txt") either; the object is a distraction to what you're trying to accomplish.

In any of these cases, you can come up with workable solutions using OOP, but they're not IMO the most powerful way to conceive of the problem.

Could you make the words "Liskov principle" link to something, like the wikipedia article about it? I for one didn't know (or didn't remember?) what it was until I read this. – Richard JP Le Guen Feb 27 '11 at 22:58
filesystem.cp is an interesting example. Would shell.cp or OS.cp be better or is making the function belong to an object the problem? The function to perform the copy is in code that can be described by a name: device driver, filesystem, virtual filesystem, operating system, service, command line interface. Because the function can be described as residing in a named place I don't think that using an object to contain the function is wrong, but it might not be helpful. – this.josh Sep 10 '11 at 7:58
@this.josh - As you pointed out, a filesystem object is the appropriate place for copy, and there is also rarely a good reason to make that an object rather than just a package/module/namespace/whatever. If you deal with a number of different filesystems at once (especially if some are derivatives of others with added features), sure, make it an object. Otherwise it's just getting in your way. – Rex Kerr Sep 12 '11 at 3:13

OOP is not suitable for applications, where the task is converting some kind of input to output, functional or procedural approach is much better for that. As others noted: command line programs, compilers, numeric calculations, engines of antivirus programs, web server side scripts (PHP!) etc. The common in them, that they get some kind of input, do calculations, then spit out some kind of output then they exit.

OOP is good for systems that are started once and they will run till someone shut them down: GUI applications, games, servers, etc. The common in them, that the components of these applications are responding to events: GUI elements has an OnClick event, monsters in a game may have an OnHit event, a server respond to the incoming connection by creating a working thread, etc. These event processor components should be objects.


Many people will confuse OOP with specific implementations of OOP. User10326, for example, mentions virtual inheritence and methods. These are not OOP concepts, they are specific implementation of OOP problems.

In general, OOP will likely have more overhead than procedural languages, but it's not strictly certain it will. So, it's appropriate to say that most OOP languages have more overhead than non-oop languages, and therefore those specific languages may not be as suitable for low memory conditions.

I think the real answer is that different paradigms may be more appropriate for a given problem than OOP. For example, functional based languages like F# (even though F# is still object oriented) is better for some problems (scientific problems for instance).

Functional languages don't have to be object oriented, but they're not mutually exclusive. A procedural language can be functional as well.

I'd say that no particular paradigm can be a perfect fit for any given problem domain. Some are closer, some can't be used at all, but always the best language for modelling a problem domain is the very language of that domain itself. And they are all different. – SK-logic Feb 27 '11 at 16:39

The only clear case (For me anyhow..) is when writing "Disposable" code for a one time task IE the code will be run once then tossed.

There is no need for any re-use.

There is no need to re-fractor.

There is no need for maintainability.

There is no real need for readably.

Get the thing working, as quickly as possible, test it, make backups in case it blows up, run it & toss it (Or archive it if you the sentimental type).

You implicitly state that all non OOP code is disposable? – Rook Feb 27 '11 at 16:20
No, I say this is a clear case to not use OOP. – Morons Feb 27 '11 at 16:27
Sometimes it's more of an effort to give up good habits. – JeffO Feb 27 '11 at 19:20
I'm not sure this is a case where OOP is ill suited, but a case where one could "get by" without it. – glenviewjeff Jun 19 '11 at 20:45
I often see "temporary" "throw away" code end up being maintained way longer than initially intended. So I'd rather disagree with this answer. – Joris Van Regemortel Jun 19 '15 at 13:43

protected by gnat Aug 4 '15 at 5:16

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.