Do you think Object Oriented Programming is a solution to complexity. Why? This topic may be a bit controversial but my intentions to know the answer of Why from the experts here !
There is no solution to complexity.
In "The Mythical Man-Month", Fred Brooks discusses the difference between accidental and essential complexity in programming. Accidental complexity is caused by our tools and methods, such as having to write and test additional code in a language because we can't express our ideas directly, and things like that. New methods and techniques can reduce accidental complexity. I can write programs faster and better than I could twenty-five years ago, because I have better languages and tools.
Essential complexity comes from the fact that what we try to do with programming is inherently complicated, and that there is an irreducible complexity. "Essential", in this context, means "relating to the essence of the thing" rather than "very necessary".
Therefore, he claimed that there would be no silver bullet, that writing software would continue to be difficult.
I strongly recommend that you read his book: specifically, I recommend the Silver Anniversary edition, with an additional essay "No Silver Bullet". In that, he reviews the proposed solutions to complexity and considers their impact. (What he finds the most effective is shrink-wrap software - write something complex once, and sell thousands or millions of copies.)
Now, object-oriented programming helps, when done right, by creating abstractions and hiding away complexity. An object of a class has a certain defined behavior that we can reason from, without caring about the complexity of the implementation. Properly written classes have low coupling with each other, and divide-and-conquer is an excellent way to deal with complexity if you can get away with it. They also have high cohesion, in that they're a set of functions and data that relate very closely to each other.
I expect you'll get some better answers shortly, but here's a simple one:
OOP helps* with complexity by modeling software in a way closer to the way we model everything else in the world. It's just generally easier to image a ball object interacting with a wall object than it is to imagine a series of routines and data structures to do the same thing, since it's closer to how we interact with the real world.
*Because nothing can 'solve' complexity
|show 1 more comment|
I think the current mainstream definition of OOP is not a good solution for managing complexity.
If you go back to its roots, I believe Alan Kay was influenced by "lisp" a great deal.
Because Lisp hasn't been corrupted by mainstream adoption, it probably managed to conserve its core values. So I think looking at how lisp tackles this problem of complexity might gives us some insight, and we can use it as a basis to sort of judge how useful is OOP at dealing with complexity.
If you look at the end of the "Lecture 3a: Henderson Escher Example" of SICP, Hal Abelson proposes that complexity is managed not by breaking the task into smaller subtasks, but by creating layers of abstraction. At the highest level, you express the solution to the complicated problem in terms of the the solution to the lower level of abstraction.
I think OOP was originally intended as a mechanism to create these layers of abstractions.
Unfortunately nowadays, OOP is (ab)used to write spaghetti code/structures.
I will make up an example: an FPS multi-player game.
At the highest level, the game works by having a bunch of players running around a map and shooting at each other using weapons.
At the next lower level, we have to talk about maps and weapons and players. Perhaps we can talk about them as physical objects that interact within the world of the game.
At the next lower level, we can talk about how objects interact physically (movement, collisions, etc).
And so on and so forth.
What this means, (and I'm sort of quoting from SICP..), is that at each layer, we not only solve a particular specific problem, but a class of problems that sort of fall in the neighborhood of the problem we're trying to solve. So if there's a small change in the problem's description, it would likely require only a small change in the solution.
So, the wise way to use OOP is to create layers of abstractions, at each level of abstraction, you solve the problem at hand using the "objects" from the level that's directly below.
Here's the bit I was quoting from the lecture: http://www.youtube.com/watch?v=CYtrfncMqHQ
|show 2 more comments|
Object-oriented programming has roots that can be traced to the 1960s. As hardware and software became increasingly complex, manageability often became a concern. Researchers studied ways to maintain software quality and developed object-oriented programming in part to address common problems by strongly emphasizing discrete, reusable units of programming logic.
An object-oriented program may thus be viewed as a collection of interacting objects, as opposed to the conventional model, in which a program is seen as a list of tasks (subroutines) to perform. In OOP, each object is capable of receiving messages, processing data, and sending messages to other objects. Each object can be viewed as an independent 'machine' with a distinct role or responsibility. The actions (or "methods") on these objects are closely associated with the object itself.
This separation of concerns, along with other features of Object Orientation such as polymorphism, inheritance, message passing, decoupling and encapsulation, provide a logical and conceptual framework by which the complexity of large programs can be managed in a highly effective way.
As usual I disagree with everyone. Far from giving you tools to manage complexity, OOP creates a huge amount of complexity because it is an inadequate and mathematically bogus paradigm. It confuses programmers no end, to try to model things with OOP that cannot be modelled with OOP.
In my view the seminal work here is Meyer's Object Oriented Software Construction. It details a set of requirements, including one I regard as crucial: the Open-Closed Principle. This says that a thing must be open for extension but closed for use, at the same time.
Meyer proceeds to derive Object Orientation from these requirements, as embodied in Eiffel. Encapsulation provides closure, inheritance open-ness, and the "thing" mentioned is the class.
I regard this work as good science because Meyer was demonstrably wrong, and it is possible because of the quality of his work, to pin point the error and fix it.
The error is making the class, or type, the unit of modularity. That's wrong, and provably so. Even Meyer recognized the problem (called the covariance problem), that OOP cannot handle relations of arity higher than one (that is, OOP works fine for properties but fails on binary relations). In Eiffel, this problem resulted in an unsound in the type system!
The solution is quite clear. The unit of modularity must be bigger than a single type. It must consist of several types, and the methods relating them.
It is hardly surprising that this model of abstraction is backed by the mathematical theory of abstraction, namely category theory: types are objects of a category, and methods (functions) are arrows.
With this model, the representations of several types are known to a set of functions. The representation is hidden from the public, so this is encapulsation, but we use modules, not classes.
The Standard Meta-Language (SML) and Ocaml are based directly on this model. Ocaml also has classes and OOP: it's not useless because OOP gives you dispatch on properties, aka dynamic binding. However most real world problems involve relations and it is hardly surprising classes aren't used much in Ocaml.
It is hardly surprising inheritance is hardly used at all in the C++ Standard template library.
The simple fact is, OOP does not give you the right tools to handle complexity, it doesn't even give you the tools to handle really simple problems, instead it has mislead and confused two generations of programmers. Far from helping, OOP is the most Evil and Bad thing that has happened to programming in since C, Fortran and Cobol started to get tired.
There are many kinds of complexity to software development. At the programming level, OOP seeks to address complexity by using objects and classes to model the problem domain. A well-known guru said problem solving is just representing the problem so that the solution is the representation itself. Hence, by abstraction using classes, encapsulation using access modifiers and methods, inheritance for specifying relationship and reuse, composition in establishing relationship and collaboration between classes, polymorphism as a means to simplify the determination of different behaviors in similar objects, complexity can be managed.
There are also other ways to manage software complexity, for example, Logic (Prolog) and Functional (Haskell) programming.
At a level higher than programming, we need Design Patterns and Principles to guide OOP. Hence OOP is managing complexity at a low (coding) level while these methodologies such as Design Patterns and Principles guide the design of the solution at a higher (system and application) level and make software development and handling complexities more manageable.
To answer your question, yes, OOP is just a solution to handling complexity among many other solutions. It is a solution at a low level. We need Design Patterns and Principles to guide OOP in a higher level.
Object oriented programming manages essential and optional complexity, but does not reduce either.
I prefer the definition provided by Eric Steven Raymond in The Art of Unix Programming, because it delineates between essential, optional, and accidental complexity. http://www.faqs.org/docs/artu/ch13s01.html#id2964646
OOP does nothing for essential or optional complexity, they are a function of the program's requirements. It can have an effect on accidental complexity, in that you can create a more elegant design sometimes with OOP. Sometimes however, the design is worse when using OOP.
Complex problems cannot be rendered simpler through technology, they can only be managed through technology.
OOP is a technology, a concept, and a way to approach a problem.
OOP gives you the tools to enforce a design that can make it easier to manage complexity, but you can just as easily have a bad design that increases your complexity. In other words, if not used properly, you can have technology-induced complexity in your problems.
Keep in mind that there are many other aspects that will dictate how successful your project will be (i.e. project management style, problem definition, change management, etc...). The technology you use is only relevant in how much will it help you manage the problem.
In the end, object oriented programming cannot be a solution to complexity; it's just a tool to manage it. (if used properly)
Object Orientation (as conventionally used) is a useful tool in many circumstances, but it isn't a sufficient solution to complexity.
In particular, it often adds a lot of "incidental complexity". Examples are the complexity surrounding implementation inheritance, the need to provide lots of "standard functionality" suach as equals() and hashCode() etc. A nice presentation by Stuart Halloway on this topic: "Simplicity Ain't Easy"
Objects in most languages also tend to encapsulate a lot of mutable state - which in a concurrent world is increasingly starting to look like a poor design decision. Again an interesting video by Rich Hickey looks at the distinction between object identity and state, and how it might be a mistake to conflate the two.
Object oriented programming is a way of representing a problem, nothing more, nothing less. It is, in and of itself, not any less complex than any other programming paradigm. A well designed OOP system manages and reduces complexity, but it is also very easy to design a system that is much more complex than necessary and gets in the way of everything.
As oft said of C++, OOP gives you enough rope to hang yourself.
I think YES, just because it allows you to slice complexity into small self-containing "building blocks" that hide details, and then use them to create the functionality you need, step by step, layer by layer.
Divide and conquer.
To some degree...
Why? Because it facilitates very logical modularity. At least in comparison to procedural programming where it's all too tempting to just write huge piles of spaghetti code.
The reason Object-oriented programming seems to help us handle complexity is because it forces us to write code in a specific fashion instead of a huge variety of ways. Task-oriented programming is much more intuitive, which is why programming started that way. Object-orientation takes training and practice to understand and use effectively, but by constraining programming into a certain path, it allows those trained to effectively maintain the code that was written.
It's no more logical or real-world than any other method, it's just a way of focusing our problem solving through similar lenses. A lot of technical specialties use the paradigm of a non-intuitive rigid methodology to handle the complexity of their tasks.
A third method to handle complexity would be functional programming, and there will be probably be other new methods in the future also.
i think it's more of a solution to maintainability, because, as a programmer, you are supposed to put methods where you have the data, thus creating an object model of your application.
yes, it's also a solution to complexity by providing a model for you to "see" your code in a natural way, as objects that have properties and possible actions
OO can help deal with complexity, it cannot solve it.
I believe that the most valuable thing that C++ adds to C is the virtual function table.