Related
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I have been programming in object-oriented languages for years now but secretly I look at some of the things my colleagues do with envy. A lot of them seem to have some inner OO instinct that I don't have - no matter how hard I try. I've read all the good books on OO but still can't seem to crack it. I feel like the guy who gave 110% to be a professional footballer but just didn't have the natural talent to make it. I'm at a loss and thinking of switching careers - what should do I?
I would say focus less on the OO programming and focus more on the OO design. Grab a paper and a pencil (or maybe a UML modelling tool), and get away from the screen.
By practicing how to design a system, you'll start to get a natural feel for object relationships. Code is just a by-product of design. Draw diagrams and model your application in a purely non-code form. What are the relationships? How do your models interact? Don't even think about the code.
Once you've spent time designing... then translate it to code. You'll be surprised at just how quickly the code can be written from a good OO design.
After a lot of design practice, you'll start seeing common areas that can be modularized or abstracted out, and you'll see an improvement in both your designs and your code.
The easiest way is to learn concepts such as SOLID, DRY, FIT, DDD, TDD, MVC, etc. As you look up these acronyms it will lead you down many other rabbit holes and once you are done with your reading you should have a good understanding of what better object-oriented programming is!
SOLID podcasts: http://www.hanselminutes.com/default.aspx?showID=168, http://www.hanselminutes.com/default.aspx?showID=163
SOLID breakdown: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
DRY: http://en.wikipedia.org/wiki/Don%27t_repeat_yourself
FIT: http://www.netwellness.org/question.cfm/38221.htm
DDD: http://dddcommunity.org/
DDD required reading: http://www.infoq.com/minibooks/domain-driven-design-quickly
TDD: http://en.wikipedia.org/wiki/Test-driven_development
MVC: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
And yes, rolling up your sleeves and coding is always a good idea. Make a small project to the best of your current abilities. Then read an article from above. Then refactor your code to meet the needs of what you just read. Repeat until you have refactored the hell out of your code. At the end you should not only know what OO is all about but you should be able to explain why it is important and how to get their the first time. Learning how to refactor is a key to good code too. What is right now is not right tomorrow.
Too many people think of coding first, objects, last.
You can read all the books you want but that's not going to teach you how to think in an object-oriented fashion--that takes practice and a certain methodology.
Here are a few methods that have
helped me: When you're away from
work and open-minded you can
practice by looking at everything as an object. Don't look at these
objects and wonder how you're going
to program them, look at them as
properties and functions only and
how they relate or inherit from each
other. For example, when you see a
person, they are an object and
therefore would represent a class.
They have properties like hair
color, skin tone, height, etc. They
do certain functions as well. They
walk, talk, sleep, etc. Some of the
functions these people do returns
results. For example, their working
function returns a dollar amount.
You can do this with everything you
see because everything is an object.
Bicycle, car, star, etc.
Before coding a project, design it by
using post-it notes and a dry-erase
board. This will make good practice
until you get the hang of this.
Think of your specific
object/function/property. Each of
those items will have its own
post-it note. Place them as a
hierarchy on the dry-erase board. In
this regard, function/properties
will be placed under the object. If
you have another object, do the same
for that one. Then ask yourself, do
any of these post it notes
(objects/functions/properties)
relate to each other. If two objects
use the same function, create a
parent object (post-it note) and put
it above the others with the
reusable function under the new
note. Draw a line using the
dry-erase marker from the two child
objects to the parent.
When all this is done, then worry
about the internals of how the class
works.
My suggestion would be to learn something different.
Learn functional programming, and apply what you learn from that to OOP. If you know C++, play around with generic programming.
Learn non-object-oriented languages.
Not just because you should use all these things as well (you should), or because they should completely replace OOP (they probably shouldn't), but because you can apply lessons from these to OOP as well.
The secret to OOP is that it doesn't always make sense to use it. Not everything is a class. Not every relationship or piece of behavior should be modeled as a class.
Blindly trying to apply OOP, or striving to write the best OOP code possible tends to lead to huge overengineered messes with far too many levels of abstraction and indirection and very little flexibility.
Don't try to write good OOP code. Try to write good code. And use OOP when it contributes to that goal.
In many fields there's a "eureka" moment where everything kind of comes together.
I remember feeling frustrated in high school geometry. I didn't know which theorem to apply on each step of the proof. But I kept at it. I learned each theorem in detail, and studied how they were applied in different example proofs. As I understood not only the definition of each theorem, but how to use it, I built up a "toolbox" of familiar techniques that I could pull out as needed.
I think it's the same in programming. That's why algorithms, data structures, and design patterns are studied and analyzed. It's not enough to read a book and get the abstract definition of a technique. You have to see it in action too.
So try reading more code, in addition to practicing writing it yourself. That's one beauty of open source, you can download lots of code to study. Not all of that code is good, but studying bad code can be just as educational as studying good code.
Learn a different language! Most developers using only Java (just as an example) have only a limited understanding of OO because they cannot separate language features and concepts. If you don't know it yet, have a look at python. If you know python, learn Ruby. Or choose one of the functional languages.
The aswer is in your question ;)
Practice, practice, practice.
Review your own code and learn from the mistakes.
TDD has helped me most in improving my overall skillset including OOP.
The more code you write, the more you will notice the pitfalls of certain programming practices. After enough time, and enough code, you will be able to identify the warning signs of these pitfalls and be able to avoid them. Sometimes when I write code, I will get this itch in the back of my mind telling me that there may be a better way to do this, even though it does what I need it to. One of my greatest programming weaknesses is "over-analyzing" things so much that it starts to dramatically slow down development time. I am trying to prevent these "itches" by spending a little more time on design, which usually results in a lot less time writing code.
...secretly I look at some of the things my colleagues do with envy. A lot of them seem to have some inner OO instinct that I don't have - no matter how hard I try...
I think you have answered your own question here. Reading good code is a good start, and understanding good code is even better, but understanding the steps to get to that good code is the best. When you see some code that you are envious of, perhaps you could ask the author how he/she arrived at that solution. This is entirely dependent on your work environment as well as the relationships with your colleagues. In any event, if anyone asks me the thought process behind any code I write, I don't hesitate to tell them because I know I would want them to do the same for me.
Language designers have interpreted "Object Oriented Programming" in different ways. For instance, see how Alan Kay, the man who first used the term OOP, defined it:
OOP to me means only messaging, local
retention and protection and hiding of
state-process, and extreme
late-binding of all things. It can be
done in Smalltalk and in LISP. There
are possibly other systems in which
this is possible, but I'm not aware of
them.
(Quoted from http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en).
It might seem strange that he don't consider Java and C++ OOP languages! But as the designer of one of the first and best OOP languages (Smalltalk) he has his own valid reasons for that. Why did Alan Kay consider Lisp an Object Oriented language but not Java? That question demands serious consideration by anyone who claims to understand OOP.
Erlang has an altogether different implemntation of OOP, Scheme has another.
It is worth considering all these alternative views. If possible learn all these languages! That will give you a broader outlook, put some new and powerful tools in your hand and make you a better programmer.
I have summarized my experiments with implementing an OOP language, based on ideas borrowed from Smalltalk, Scheme and Erlang in this article.
public void MasteryOfOOP()
{
while(true)
/* My suggestion is: */
DO: find a lot of well-written object oriented code and read it. Then
try to use the insights from it on your own coding. Then do it again. Then
have a colleague who is a good OOP look at it and comment. Maybe post a chunk
of your code on SO and ask for how it could be improved.
Then read some more of those books. Maybe they make a little more
sense now...?
Now go back to the top of this post, and do it again.
Repeat Forever.
}
}
If you're lost as to how to design object-oriented systems, start with the data. Figure out what stuff you need to keep track of and what information naturally goes together (for example, all of the specs of a model of car group together nicely).
Each of these kinds of thing you decide to track becomes a class.
Then when you need to be able to execute particular actions (for example, marking a model of car as decommissioned) or ask particular questions (for example, asking how many of a given model of car were sold in a given year), you load that functionality onto the class it interacts with most heavily.
In general, there should always be a pretty natural place for a given bit of code to live in your class structure. If there isn't, that signals that there's a place where the structure needs to be built out.
There's too much information about objects. The most important thing is to master the basics and everything falls into place more easily.
Here's a way to think about objects. Think about data structures in procedural languages. They are a group of fields without behaviour. Think about functions that receive pointers to those data structures and manipulate the latter. Now, instead of having them separate, define the functions inside the definition of the the structures and assume the functions usually receive a pointer to the data structure to manipulate. That pointer is called this. In sum, think about objects as the combination of status (data) and behaviour (methods - the fancy name for functions in OOP).
This is the absolute basic. There are three more concepts you must absolutely master:
Inheritance - This is all about code reuse.
Encapsulation - This is all about hiding the implementation from the interface. Simply put, everything ought to be private until proven otherwise.
Polymorphism - It doesn't matter the type of the reference variable, but the type of the actual instance to know which behaviour (method) is called. Java doesn't make it easy to have this concept very visible because by definition everything is polymorphic. .Net makes it easier to understand as you decide what is polymorphic and what is not, hence noticing the difference in behaviour. This is achieved by the combination of virtual and override.
If these concepts are very well understood, you'll be fine.
One last final tip: You mention the best books. Have you read "Thinking in Java" by Bruce Eckel? I recommend this book even to people who are beginning in .Net, as the OOP concepts are clearly laid out.
Become more agile, learn junit testing and study about Domain Driven Design. I suggest the book Domain-Driven Design: Tackling Complexity in the Heart of Software although it's a bit tough at some points.
OOP skills comes over time. Reading 1, 2 ...10 books doesn't cut it. Practice writing some code. If you are working in a programming enviornment...that can be helpful. If not try getting into one. Offer to develop some application(s) for free. You have to get your hands dirty. Remember...no application is perfect from the ground up.That's why there is re-factoring.
Also...don't get carried away with the OOP too much...it somes over time. Worry about developing fully functional applications.
Try some programming in Self, one of the most pure OO languages around. So pure, in fact, that it doesn't even have classes, only objects. It also doesn't have variables, fields, statics, attributes, only methods. Also interesting is the fact that every object in the system is also an object on the screen and vice-versa.
Some of the interesting papers on Self are Prototype-Based Application Construction Using SELF 4.0 (the Self tutorial), Self: The Power of Simplicity and Organizing Programs Without Classes. Also, Self: The Video (Randall B. Smith; Dave Ungar) is terrific, having two of the language's designers explain Self's ideas.
This works for pretty much any concept, actually, at least for me: find the language which most purely embodies the concept you want to learn about and just use it.
OO finally clicked for me after I tried to program a bank-like program that handled transactions, calculated interest, and kept track of it all. I did it while I was learning Java. I would suggest just trying it, completing it, and then when you're done go look at a GOOD solution and see what you could've done better.
I also think OOP skills strenghten mostly with practice. Consider changing your company, if you've been there for more than 3 years. Certainly, this is not valid for all jobs, but often a man gets used to the projects and practices at a company and stops advancing as time passes.
Roll up your sleeves and code!
You said the answer yourself: practice. Best solution for this is to develop a game. Use the concepts you learnt in the books there.
Have you read the chapter on OO from the first edition of Scott Meyers "Effective C++" book? It didn't make it to later editions, but it was a great explanation. The title was basically "say what you mean, mean what you say" about suitable conventions.
Actually, you might like to see my answer to a similar question over here.
HTH
cheers,
OOP is not a thing you can master by reading thousands of books. Rather you have to feel the inner concepts. Read anything but try to feel what you read. Build a concept in the back of your mind and try to match those concepts when you face a new scenario. Verify and Update your concepts as you explore new things.
Good luck!
Plan things out. Ask yourself how you want your objects to relate to eachother and seek out how things can be changed and modularized.
Code things in such a way that if you wanted to change 1 piece of the code, you only have to change that 1 piece of code and not 50 instances of it.
beer helps. seriously. lie out on a couch with an A3 sized scribble pad, a pen and a beer. Lock the dog, cat and wife outside. And think about the problem while relaxed. Don't even dare draw an API on it!
Flowcharts, Responsibity cards (CRC) and beer (but not too much) go a long way.
Easiest way to refactor code is to not have to in the first place.
http://misko.hevery.com/code-reviewers-guide/
Those small simple rules will make you a better OO programmer. Follow the rules religiously as you code and you will find your code is better than it would otherwise be.
You'll also want to learn the Solid Principles: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
As much as these principles and ways of programming cause debate, they are the only way to truly write excellent code.
You may already write code this way and not know it-- if so, great. But if you need a goal to strive towards, these are the gold standard.
Give up! Why do you need that that OOP? Just write some usable app. Doesnt metter using OOP, procedual or functional approach.
Whataver approach you choose Python language should be sutable to practice it.
You're my target audience. Look at Building Skills in OO Design
Perhaps this can help.
I have an Access db I use for my checkbook (with a good amount of fairly simple VBA behind it) and I'd like to rewrite it as a stand-alone program with a SQL backend. I'm thinking of using either C++, Java, or Python. I had assumed, before I started, that I would write it OO because I thought that I would think "in OO terms" (due to a OO Logic class and a C++ class I took), but I'm finding that I can only visualize it as procedural (but maybe because I'm mentally stuck in thinking of how the db works in Access). How do I decide? Am I making sense or does it seem like I'm not understanding the concepts?
Thanks for your help.
I'd suggest OO - it's not harder than procedural programming, actually easier to maintain with the right tool. Delphi would be my choice - great DB programming support, visual designer, strongly-typed, plenty of components available. There are many great applications that are written in Delphi. Often underestimated, there are many reasons it's got a loyal following.
Now I'll duck as the Delphi-haters load up with tomatoes.
Well, OO may well be overkill, but it is excellent practice. Any code monkey can write procedural code. Its the path of least resistance in every case, which is why most people use it for one off apps that don't do much. However, if you're writing to get experience in working with OO, than it is best to think of it that way. You could start by designing an object that manages financial transaction, then you will also need a way to interact with the DB. Perhaps you could write a DB layer where you abstract away the database calls from the transaction object using the Entity framework where you could learn LINQ (or whatever the JAVA equivalent is). This is all assuming that you are doing this for fun and practice.
oo seems to be overkill for a simple checkbook app. Try something on a larger scale like something to manage all your financial accounts. This way designing an account class would make sense
Well it depends on your motivation. If you want a checkbook application as quickly as possible, just churn out the procedural code. No-one other than you will know the difference. If you want to use this application to better yourself as aprogrammer. Take the time to learn how to write in in OO.
I'd go with Python: no compiling and uses dynamic typing (you can use strict typing too if you want). Plus, it has a huge following in the open source community which means great support, tools, and documentation for free.
As for OO vs. Procedural -- all these languages you've mentioned could be written in a procedural style -- that is, one big class/method that does everything -- but you'll soon find that you'll want to follow DRY principles (Don't Repeat Yourself) and start with some private methods that do one particular thing well. From then, you'll want to group similar things into separate classes, and then from there you'll want to abstract those classes... see where I'm going here?
In my opinion you should concentrate less on the OO versus procedural thing. If you have the possibility to go procedural in the beginning, then go procedural. It's the easiest thing you can do to get you started. The OO thing, on the other hand, may just as well qualify as YAGNI (You Ain't Gonna Need It).
What you should do though, is to write tests, unit tests and then integration tests. And you should strive to write tests first. This way, even if you begin with a procedural application you may later on refactor it into a full-fledged OO application. But, only if you need objects. These tests will be you're safety net when moving around code in your application.
Trying to think your applications into object from the beginning may lead you to an point where you're stuck with your class hierarchies and architecture.
I'm not a genius, so I may be wrong, but in my experience, starting with simple functions and then thinking about grouping them into objects or modules is better than starting by saying: OK, I'll have this object that interacts with this object, which is implementing pattern X, so this way I'll decouple interface Y from implementation Z. Later on, you may observe that your domain model is weak. Take an evolutionary design path and start with small building blocks.
If you are looking for a quick app that you can extend, check out Dynamic Data.
I recently had a debate with a colleague who is not a fan of OOP. What took my attention was what he said:
"What's the point of doing my coding in objects? If it's reuse then I can just create a library and call whatever functions I need for whatever task is at hand. Do I need these concepts of polymorphism, inheritance, interfaces, patterns or whatever?"
We are in a small company developing small projects for e-commerce sites and real estate.
How can I take advantage of OOP in an "everyday, real-world" setup? Or was OOP really meant to solve complex problems and not intended for "everyday" development?
My personally view: context
When you program in OOP you have a greater awareness of the context. It helps you to organize the code in such a way that it is easier to understand because the real world is also object oriented.
The good things about OOP come from tying a set of data to a set of behaviors.
So, if you need to do many related operations on a related set of data, you can write many functions that operate on a struct, or you can use an object.
Objects give you some code reuse help in the form of inheritance.
IME, it is easier to work with an object with a known set of attributes and methods that it is to keep a set of complex structs and the functions that operate on them.
Some people will go on about inheritance and polymorphism. These are valuable, but the real value in OOP (in my opinion) comes from the nice way it encapsulates and associates data with behaviors.
Should you use OOP on your projects? That depends on how well your language supports OOP. That depends on the types of problems you need to solve.
But, if you are doing small websites, you are still talking about enough complexity that I would use OOP design given proper support in the development language.
More than getting something to just work - your friend's point, a well designed OO design is easier to understand, to follow, to expand, to extend and to implement. It is so much easier for example to delegate work that categorically are similar or to hold data that should stay together (yes even a C struct is an object).
Well, I'm sure a lot of people will give a lot more academically correctly answers, but here's my take on a few of the most valuable advantages:
OOP allows for better encapsulation
OOP allows the programmer to think in more logical terms, making software projects easier to design and understand (if well designed)
OOP is a time saver. For example, look at the things you can do with a C++ string object, vectors, etc. All that functionality (and much more) comes for "free." Now, those are really features of the class libraries and not OOP itself, but almost all OOP implementations come with nice class libraries. Can you implement all that stuff in C (or most of it)? Sure. But why write it yourself?
Look at the use of Design Patterns and you'll see the utility of OOP. It's not just about encapsulation and reuse, but extensibility and maintainability. It's the interfaces that make things powerful.
A few examples:
Implementing a stream (decorator pattern) without objects is difficult
Adding a new operation to an existing system such as a new encryption type (strategy pattern) can be difficult without objects.
Look at the way PostgresQL is
implemented versus the way your
database book says a database should
be implemented and you'll see a big
difference. The book will suggest
node objects for each operator.
Postgres uses myriad tables and
macros to try to emulate these nodes.
It is much less pretty and much
harder to extend because of that.
The list goes on.
The power of most programming languages is in the abstractions that they make available. Object Oriented programming provides a very powerful system of abstractions in the way it allows you to manage relationships between related ideas or actions.
Consider the task of calculating areas for an arbitrary and expanding collection of shapes. Any programmer can quickly write functions for the area of a circle, square, triangle, ect. and store them in a library. The difficulty comes when trying to write a program that identifies and calculates the area of an arbitrary shape. Each time you add a new kind of shape, say a pentagon, you would need to update and extend something like an IF or CASE structure to allow your program to identify the new shape and call the correct area routine from your "library of functions". After a while, the maintenance costs associated with this approach begin to pile up.
With object-oriented programming, a lot of this comes free-- just define a Shape class that contains an area method. Then it doesn't really matter what specific shape you're dealing with at run time, just make each geometrical figure an object that inherits from Shape and call the area method. The Object Oriented paradigm handles the details of whether at this moment in time, with this user input, do we need to calculate the area of a circle, triangle, square, pentagon or the ellipse option that was just added half a minute ago.
What if you decided to change the interface behind the way the area function was called? With Object Oriented programming you would just update the Shape class and the changes automagically propagate to all entities that inherit from that class. With a non Object Oriented system you would be facing the task of slogging through your "library of functions" and updating each individual interface.
In summary, Object Oriented programming provides a powerful form of abstraction that can save you time and effort by eliminating repetition in your code and streamlining extensions and maintenance.
Around 1994 I was trying to make sense of OOP and C++ at the same time, and found myself frustrated, even though I could understand in principle what the value of OOP was. I was so used to being able to mess with the state of any part of the application from other languages (mostly Basic, Assembly, and Pascal-family languages) that it seemed like I was giving up productivity in favor of some academic abstraction. Unfortunately, my first few encounters with OO frameworks like MFC made it easier to hack, but didn't necessarily provide much in the way of enlightenment.
It was only through a combination of persistence, exposure to alternate (non-C++) ways of dealing with objects, and careful analysis of OO code that both 1) worked and 2) read more coherently and intuitively than the equivalent procedural code that I started to really get it. And 15 years later, I'm regularly surprised at new (to me) discoveries of clever, yet impressively simple OO solutions that I can't imagine doing as neatly in a procedural approach.
I've been going through the same set of struggles trying to make sense of the functional programming paradigm over the last couple of years. To paraphrase Paul Graham, when you're looking down the power continuum, you see everything that's missing. When you're looking up the power continuum, you don't see the power, you just see weirdness.
I think, in order to commit to doing something a different way, you have to 1) see someone obviously being more productive with more powerful constructs and 2) suspend disbelief when you find yourself hitting a wall. It probably helps to have a mentor who is at least a tiny bit further along in their understanding of the new paradigm, too.
Barring the gumption required to suspend disbelief, if you want someone to quickly grok the value of an OO model, I think you could do a lot worse than to ask someone to spend a week with the Pragmatic Programmers book on Rails. It unfortunately does leave out a lot of the details of how the magic works, but it's a pretty good introduction to the power of a system of OO abstractions. If, after working through that book, your colleague still doesn't see the value of OO for some reason, he/she may be a hopeless case. But if they're willing to spend a little time working with an approach that has a strongly opinionated OO design that works, and gets them from 0-60 far faster than doing the same thing in a procedural language, there may just be hope. I think that's true even if your work doesn't involve web development.
I'm not so sure that bringing up the "real world" would be as much a selling point as a working framework for writing good apps, because it turns out that, especially in statically typed languages like C# and Java, modeling the real world often requires tortuous abstractions. You can see a concrete example of the difficulty of modeling the real world by looking at thousands of people struggling to model something as ostensibly simple as the geometric abstraction of "shape" (shape, ellipse, circle).
All programming paradigms have the same goal: hiding unneeded complexity.
Some problems are easily solved with an imperative paradigm, like your friend uses. Other problems are easily solved with an object-oriented paradigm. There are many other paradigms. The main ones (logic programming, functional programming, and imperative programming) are all equivalent to each other; object-oriented programming is usually thought as an extension to imperative programming.
Object-oriented programming is best used when the programmer is modeling items that are similar, but not the same. An imperative paradigm would put the different kinds of models into one function. An object-oriented paradigm separates the different kinds of models into different methods on related objects.
Your colleague seems to be stuck in one paradigm. Good luck.
To me, the power of OOP doesn't show itself until you start talking about inheritance and polymorphism.
If one's argument for OOP rests the concept of encapsulation and abstraction, well that isn't a very convincing argument for me. I can write a huge library and only document the interfaces to it that I want the user to be aware of, or I can rely on language-level constructs like packages in Ada to make fields private and only expose what it is that I want to expose.
However, the real advantage comes when I've written code in a generic hierarchy so that it can be reused later such that the same exact code interfaces are used for different functionality to achieve the same result.
Why is this handy? Because I can stand on the shoulders of giants to accomplish my current task. The idea is that I can boil the parts of a problem down to the most basic parts, the objects that compose the objects that compose... the objects that compose the project. By using a class that defines behavior very well in the general case, I can use that same proven code to build a more specific version of the same thing, and then a more specific version of the same thing, and then yet an even more specific version of the same thing. The key is that each of these entities has commonality that has already been coded and tested, and there is no need to reimpliment it again later. If I don't use inheritance for this, I end up reimplementing the common functionality or explicitly linking my new code against the old code, which provides a scenario for me to introduce control flow bugs.
Polymorphism is very handy in instances where I need to achieve a certain functionality from an object, but the same functionality is also needed from similar, but unique types. For instance, in Qt, there is the idea of inserting items onto a model so that the data can be displayed and you can easily maintain metadata for that object. Without polymorphism, I would need to bother myself with much more detail than I currently do (I.E. i would need to implement the same code interfaces that conduct the same business logic as the item that was originally intended to go on the model). Because the base class of my data-bound object interacts natively with the model, I can instead insert metadata onto this model with no trouble. I get what I need out of the object with no concern over what the model needs, and the model gets what it needs with no concern over what I have added to the class.
Ask your friend to visualize any object in his very Room, House or City... and if he can tell a single such object which a system in itself and is capable of doing some meaningful work. Things like a button isnt doing something alone - it takes lots of objects to make a phone call. Similarly a car engine is made of the crank shaft, pistons, spark plugs. OOPS concepts have evolved from our perception in natural processes or things in our lives. The "Inside COM" book tells the purpose of COM by taking analogy from a childhood game of identifying animals by asking questions.
Design trumps technology and methodology. Good designs tend to incorporate universal principals of complexity management such as law of demeter which is at the heart of what OO language features strive to codify.
Good design is not dependant on use of OO specific language features although it is typically in ones best interests to use them.
Not only does it make
programming easier / more maintainable in the current situation for other people (and yourself)
It is already allowing easier database CRUD (Create, Update, Delete) operations.
You can find more info about it looking up:
- Java : Hibernate
- Dot Net : Entity Framework
See even how LINQ (Visual Studio) can make your programming life MUCH easier.
Also, you can start using design patterns for solving real life problems (design patterns are all about OO)
Perhaps it is even fun to demonstrate with a little demo:
Let's say you need to store employees, accounts, members, books in a text file in a similar way.
.PS. I tried writing it in a PSEUDO way :)
the OO way
Code you call:
io.file.save(objectsCollection.ourFunctionForSaving())
class objectsCollection
function ourFunctionForSaving() As String
String _Objects
for each _Object in objectsCollection
Objects &= _Object & "-"
end for
return _Objects
end method
NON-OO Way
I don't think i'll write down non-oo code. But think of it :)
NOW LET'S SAY
In the OO way. The above class is the parent class of all methods for saving the books, employees, members, accounts, ...
What happens if we want to change the way of saving to a textfile? For example, to make it compactible with a current standard (.CVS).
And let's say we would like to add a load function, how much code do you need to write?
In the OO- way you only need the add a New Sub method which can split all the data into parameters (This happens once).
Let your collegue think about that :)
In domains where state and behavior are poorly aligned, Object-Orientation reduces the overall dependency density (i.e. complexity) within these domains, which makes the resulting systems less brittle.
This is because the essence of Object-Orientation is based on the fact that, organizationally, it doesn't dustinguish between state and behavior at all, treating both uniformly as "features". Objects are just sets of features clumpled to minimize overall dependency.
In other domains, Object-Orientation is not the best approach. There are different language paradigms for different problems. Experienced developers know this, and are willing to use whatever language is closest to the domain.
[Edit:] Earlier I asked this as a perhaps poorly-framed question about when to use OOP versus when to use procedural programming - some responses implied I was asking for help understanding OOP. On the contrary, I have used OOP a lot but want to know when to use a procedural approach. Judging by the responses, I take it that there is a fairly strong consensus that OOP is usually a better all-round approach but that a procedural language should be used if the OOP architecture will not provide any reuse benefits in the long term.
However my experience as a Java programmer has been otherwise. I saw a massive Java program that I architected rewritten by a Perl guru in 1/10 of the code that I had written and seemingly just as robust as my model of OOP perfection. My architecture saw a significant amount of reuse and yet a more concise procedural approach had produced a superior solution.
So, at the risk of repeating myself, I'm wondering in what situations should I choose a procedural over an object-oriented approach. How would you identify in advance a situation in which an OOP architecture is likely to be overkill and a procedural approach more concise and efficient.
Can anyone suggest examples of what those scenarios would look like?
What is a good way to identify in advance a project that would be better served by a procedural programming approach?
I like Glass' rules of 3 when it comes to Reuse (which seems to be what you're interested in).
1) It is 3 times as difficult to
build reusable components as single
use components 2) A reusable
component should be tried out in three
different applications before it will
be sufficiently general to accept into
a reuse library
From this I think you can extrapolate these corollaries
a) If you don't have the budget
for 3 times the time it would take you
to build a single use component, maybe
you should hold off on reuse. (Assuming Difficulty = Time)
b) If
you don't have 3 places where you'd
use the component you're building,
maybe you should hold off on building
the reusable component.
I still think OOP is useful for building the single use component, because you can always refactor it into something that is really reusable later on. (You can also refactor from PP to OOP but I think OOP comes with enough benefits regarding organization and encapsulation to start there)
Reusability (or lack of it) is not bound to any specific programming paradigm. Use object oriented, procedural, functional or any other programming as needed. Organization and reusability come from what you do, not from the tool.
Those who religiously support OOP don't have any facts to justify their support, as we see here in these comments as well. They are trained (or brain washed) in universities to use and praise OOP and OOP only and that is why they support it so blindly. Have they done any real work in PP at all? Other then protecting code from careless programmers in a team environment, OOP doesn't offer much. Personally working both in PP and OOP for years, I find that PP is simple, straight forward and more efficient, and I agree with the following wise men and women:
(Reference: http://en.wikipedia.org/wiki/Object-oriented_programming):
A number of well-known researchers and programmers have criticized OOP. Here is an incomplete list:
Luca Cardelli wrote a paper titled “Bad Engineering Properties of Object-Oriented Languages”.
Richard Stallman wrote in 1995, “Adding OOP to Emacs is not clearly an improvement; I used OOP when working on the Lisp Machine window systems, and I disagree with the usual view that it is a superior way to program.”
A study by Potok et al. has shown no significant difference in productivity between OOP and procedural approaches.
Christopher J. Date stated that critical comparison of OOP to other technologies, relational in particular, is difficult because of lack of an agreed-upon and rigorous definition of OOP. A theoretical foundation on OOP is proposed which uses OOP as a kind of customizable type system to support RDBMS.
Alexander Stepanov suggested that OOP provides a mathematically-limited viewpoint and called it “almost as much of a hoax as Artificial Intelligence” (possibly referring to the Artificial Intelligence projects and marketing of the 1980s that are sometimes viewed as overzealous in retrospect).
Paul Graham has suggested that the purpose of OOP is to act as a “herding mechanism” which keeps mediocre programmers in mediocre organizations from “doing too much damage”. This is at the expense of slowing down productive programmers who know how to use more powerful and more compact techniques.
Joe Armstrong, the principal inventor of Erlang, is quoted as saying “The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.”
Richard Mansfield, author and former editor of COMPUTE! magazine, states that “like countless other intellectual fads over the years (“relevance”, communism, “modernism”, and so on—history is littered with them), OOP will be with us until eventually reality asserts itself. But considering how OOP currently pervades both universities and workplaces, OOP may well prove to be a durable delusion. Entire generations of indoctrinated programmers continue to march out of the academy, committed to OOP and nothing but OOP for the rest of their lives.” and also is quoted as saying “OOP is to writing a program, what going through airport security is to flying”.
You gave the answer yourself - big projects simply need OOP to prevent getting too messy.
From my point of view, the biggest advantage of OOP is code organization. This includes the principles of DRY and encapsulation.
I would suggest using the most concise, standards-based approach that you can find for any given problem. Your colleague who used Perl demonstrated that a good developer who knows a particular tool well can achieve great results regardless of the methodology. Rather than compare your Java-versus-Perl projects as a good example of the procedural-versus-OOP debate, I would like to see a face-off between Perl and a similarly concise language such as Ruby, which happens to also have the benefits of object orientation. Now that's something I'd like to see. My guess is Ruby would come out on top but I'm not interested in provoking a language flame-war here - my point is only that you choose the appropriate tool for the job - whatever approach can accomplish the task in the most efficient and robust way possible. Java may be robust because of its object orientation but as you and your colleague and many others who are converting to dynamic languages such as Ruby and Python are finding these days, there are much more efficient solutions out there, whether procedural or OOP.
I think DRY principle (Don't Repeat Yourself) combined with a little Agile is a good approach. Build your program incrementally starting with the simplest thing that works then add features one by one and re-factor your code as necessary as you go along.
If you find yourself writing the same few lines of code again and again - maybe with different data - it's time to think about abstractions that can help separate the stuff that changes from the stuff that stays the same.
Create thorough unit tests for each iteration so that you can re-factor with confidence.
It's a mistake to spend too much time trying to anticipate which parts of your code need to be reusable. It will soon become apparent once the system starts to grow in size.
For larger projects with multiple concurrent development teams you need to have some kind of architectural plan to guide the development, but if you are working on your own or in small cooperative team then the architecture will emerge naturally if you stick to the DRY principle.
Another advantage of this approach is that whatever you do is based on real world experience. My favourite analogy - you have to play with the bricks before you can imagine how the building might be constructed.
I think you should use procedural style when you have a very well specified problem, the specification won't change and you want a very fast running program for it. In this case you may trade the maintainability for performance.
Usually this is the case when you write a game engine or a scientific simulation program. If your program calculate something more than million times per second it should be optimized to the edge.
You can use very efficient algorithms but it won't be fast enough until you optimize the cache usage. It can be a big performance boost your data is cached. This means the CPU don't need fetch bytes from the RAM, it know them. To achieve this you should try to store your data close to each other, your executable and data size should be minimal, and try using as less pointers as you can (use static global fixed sized arrays where you can afford).
If you use pointers you are continuously jumping in the memory and your CPU need to reload the cache every time. OOP code is full of pointers: every object is stored by its memory address. You call new everywhere which spread your objects all over the memory making the cache optimization almost impossible (unless you have an allocator or a garbage collector that keeps things close to each other). You call callbacks and virtual functions. The compiler usually can't inline the virtual functions and a virtual function call is relatively slow (jump to the VMT, get the address of the virtual function, call it [this involves pushing the parameters and local variables on the stack, executing the function then popping everything]). This matters a lot when you have a loop running from 0 to 1000000 25 times in every second. By using procedural style there aren't virtual function and the optimizar can inline everything in those hot loops.
If the project is so small that it would be contained within one class and is not going to be used for very long, I would consider using functions. Alternatively if the language you are using does not support OO (e.g. c).
"The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.” —Joe Armstrong
Do you want the jungle?
I think the suitability of OOP depends more on the subject area you're working in than the size of the project. There are some subject areas (CAD, simulation modeling, etc.) where OOP maps naturally to the concepts involved. However, there are a lot of other domains where the mapping ends up being clumsy and incongruous. Many people using OOP for everything seem to spend a lot of time trying to pound square pegs into round holes.
OOP has it's place, but so do procedural programming, functional programming, etc. Look at the problem you're trying to solve, then choose a programming paradigm that allows you to write the simplest possible program to solve it.
Procedural programs can be simpler for a certain type of program. Typically, these are the short script-like programs.
Consider this scenario:
Your code is not OO. You have data structures and many functions throughout your progam that operate on the data structures. Each function takes a data structure as a parameter and does different things depending on a "data_type" field in the data structure.
IF all is working and not going to be changed, who cares if it's OO or not? It's working. It's done. If you can get to that point faster writing procedurally, then maybe that's the way to go.
But are you sure it's not going to be changed? Let's say you're likely to add new types of data structures. Each time you add a new data structure type that you want those functions to operate on, you have to make sure you find and modify every one of those functions to add a new "else if" case to check for and add the behavior you want to affect the new type of data structure. The pain of this increases as the program gets larger and more complicated. The more likely this is, the better off you would be going with the OO approach.
And - are you sure that it's working with no bugs? More involved switching logic creates more complexity in testing each unit of code. With polymorphic method calls, the language handles the switching logic for you and each method can be simpler and more straightforward to test.
The two concepts are not mutually exclusive, it is very likely that you will use PP in conjunction with OOP, I can't see how to segregate them.
I believe Grady Booch said once that you really start to benefit a lot from OOP at 10000+ lines of code.
However, I'd always go the OO-way. Even for 200 lines. It's a superior approach in a long term, and the overhead is just an overrated excuse. All the big things start small.
One of the goals of OOP was to make reusability easier however it is not the only purpose. The key to learning to use objects effectively is Design Patterns.
We are all used to the idea of algorithms which tell us how to combine different procedures and data structures to perform common tasks. Conversely look at Design Patterns by the Gang of Four for ideas on how to combine objects to perform common tasks.
Before I learned about Design Patterns I was pretty much in the dark about how to use objects effectively other than as a super type structure.
Remember that implementing Interfaces is just as important if not more important than inheritance. Back in the day C++ was leading example of object oriented programming and using interfaces are obscured compared to inheritance (virtual functions, etc). The C++ Legacy meant a lot more emphasis was placed on reusing behavior in the various tutorials and broad overviews. Since then Java, C#, and other languages have moved interface up to more a focus.
What interfaces are great for is precisely defining how two object interact with each. It is not about reusing behavior. As it turns out much of our software is about how the different parts interact. So using interface gives a lot more productivity gain than trying to make reusable components.
Remember that like many other programming ideas Objects are a tool. You will have to use your best judgment as to how well they work for your project. For my CAD/CAM software for metal cutting machines there are important math functions that are not placed in objects because there is no reason for them be in objects. Instead they are exposed from library and used by the object that need them. Then there is are some math function that were made object oriented as their structure naturally lead to this setup. (Taking a list of points and transforming it in on of several different types of cutting paths). Again use your best judgment.
Part of your answer depends on what language you're using. I know that in Python, it's pretty simple to move procedural code into a class, or a more formal object.
One of my heuristics is a based on how the "state" of the situation is. If the procedure pollutes the namespace, or could possibly affect the global state (in a bad, or unpredictable way), then encapsulating that function in an object or class is probably wise.
My two cents...
Advantages of procedural programming
Simple designing (fast proof of concept, battle with dramatically
dynamic requirements)
Simple inter-project communications
Natural when temporal order matters
Less overhead at runtime
The more Procedural code become good the closer it's to Functional. And advantages of FP are well known.
I always begin designing in a top-down fashion and in the top parts it's much easier to think in OOP terms. But when comes the time to code some little specific parts you are much more productive with just procedure programming.
OOP is cool in designing and in shaping the project, so that the divide-et-impera paradigm can be applied. But you cannot apply it in every aspect of your code, as it were a religion :)
If you "think OO" when you're programming, then I'm not sure it makes sense to ask "when should I revert to procedural programming?" This is equivalent to asking java programmers what they can't do as well because java requires classes. (Ditto .NET languages).
If you have to make an effort to get past thinking procedurally, then I'd advise asking about how you can overcome that (if you care to); otherwise stay with procedural. If it's that much effort to get into OOP-mode, your OOP code probably won't work very well anyway (until you get further along the learning curve.)
IMHO, the long term benefits of OOP outweigh the time saved in the short term.
Like AZ said, using OOP in a procedural fashion (which I do quite a bit), is a good way to go (for smaller projects). The bigger the project, the more OOP you should employ.
You can write bad software in both concepts. Still, complex software are much easier to write, understand and maintain in OO languages than in procedural. I wrote highly complex ERP applications in procedural language (Oracle PL/SQL) and then switched to OOP (C#). It was and still is a breath of fresh air.
To this point, the arguments of using OO for DRY and encapsulation is just adding unnecessary complexity in terms of how implicit it is and just sheer of how many layers that a class can inherit a lot of properties and methods into it.
not to mention that it's really hard to design a good OO cause you'd end up adding unrelated/unnecessary things that are going to be inherited throughout the whole layers of classes that inherits them. which is really bad if one parent class gets messy, the whole codebase is messy. and gets refactored.
also the fact that those inherited properties are not specifically fit into the use case to the class that inherits it which requires to be overridden. and to the ones that don't need them at all just have them for no good reason.
for something that does not need to be shared, sure there's abstract properties. but you'd end up having to implement them in all the instances that tries to inherits them.
this inheritance is just too magicky and gets dangerous.
but I'd give OO credit on how it's good at enforcing of what should be available. but then again it's too much power that is really easy to be wrongly used.
In my opinion, final class should be the default. and you need to deliberately choose if you want to allow it to inheritance.
Most studies have found that OO code is more concise than procedural code. If you look at projects that re-wrote existing C code in C++ (not something I necessarily advise, BTW) , you normally see reductions in code size of between 50 and 75 percent.
So the answer is - always use OO!
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Since I started studying object-oriented programming, I frequently read articles/blogs saying functions are better, or not all problems should be modeled as objects. From your personal programming adventures, when do you think a problem is better solved by OOP?
There is no hard and fast rule. A problem is better solved with OOP when you are better at solving problems and thinking in an OO mentality. Object Orientation is just another tool which has come along through trying to make computing a better tool for solving problems.
However, it can allow for better code reuse, and can also lead to neater code. But quite often these highly praised qualities are, in-relity, of little real value. Applying OO techniques to an existing functional application could really cause a lot of problems. The skill lies in learning many different techniques and applying the most appropriate to the problem at hand.
OO is often quoted as a Nirvana-like solution to the software development, however there are many times when it is not appropriate to be applied to the issue at hand. It can, quite often, lead to over-engineering of a problem to reach the perfect solution, when often it is really not necessary.
In essence, OOP is not really Object Oriented Programming, but mapping Object Oriented Thinking to a programming language capable of supporting OO Techniques. OO techniques can be supported by languages which are not inherently OO, and there are techniques you can use within functional languages to take advantage of the benefits.
As an example, I have been developing OO software for about 20 years now, so I tend to think in OO terms when solving problems, irrespective of the language I am writing in. Currently I am implementing polymorphism using Perl 5.6, which does not natively support it. I have chosen to do this as it will make maintenance and extension of the code a simple configuration task, rather than a development issue.
Not sure if this is clear. There are people who are hard in the OO court, and there are people who are hard in the Functional court. And then there are people who have tried both and try to take the best from each. Neither is perfect, but both have some very good traits that you can utilise no matter what the language.
If you are trying to learn OOP, don't just concentrate on OOP, but try to utilise Object Oriented Analysis and general OO principles to the whole spectrum of the problem solution.
I'm an old timer, but have also programmed OOP for a long time. I am personally against using OOP just to use it. I prefer objects to have specific reasons for existing, that they model something concrete, and that they make sense.
The problem that I have with a lot of the newer developers is that they have no concept of the resources that they are consuming with the code that they create. When dealing with a large amount of data and accessing databases the "perfect" object model may be the worst thing you can do for performance and resources.
My bottom line is if it makes sense as an object then program it as an object, as long as you consider the performance/resource impact of the implementation of your object model.
I think it fits best when you are modeling something cohesive with state and associated actions on those states. I guess that's kind of vague, but I'm not sure there is a perfect answer here.
The thing about OOP is that it lets you encapsulate and abstract data and information away, which is a real boon in building a large system. You can do the same with other paradigms, but it seems OOP is especially helpful in this category.
It also kind of depends on the language you are using. If it is a language with rich OOP support, you should probably use that to your advantage. If it doesn't, then you may need to find other mechanisms to help break up the problem into smaller, easily testable pieces.
I am sold to OOP.
Anytime you can define a concept for a problem, it can probably be wrapped in an object.
The problem with OOP is that some people overused it and made their code even more difficult to understand. If you are careful about what you put in objects and what you put in services (static classes) you will benefit from using objects.
Just don't put something that doesn't belong to an object in the object because you need your object to do something new that you didn't think of initially, refactor and find the best way to add that functionality.
There are 5 criteria whether you should favor Object Oriented over Object Based,Functional or Procedural code. Remember all of these styles are available in all languages, they're styles. All of these are written in a style of "Should I favor OO in this situation?"
The system is very complex and has over approximately 9k LOC (Just an arbitrary level). -- As systems get more complex, the benefits gained by encapsulating complexity go up quite a bit. With OO, as opposed to the other techniques, you tend to encapsulate more and more of the complexity, which is very valuable at this level. Object Based or procedural should be favored before this. (This is not advocating a particular language mind you. OO C fits these features more than OO C++ in my mind, a language with a notorious reputation for leaky abstractions and an ability to eat shops with even 1 mediocre/obstinate programmer for lunch).
Your code is not operations on data (i.e. Database based or math/analysis based). Database based code is often more easily represented via procedural style. Analysis based code is often easier represented in a functional style.
Your model is a simulation of something (OO excels at simulations).
You're doing something for which the object based subtype dispatch of OO is valuable (aka, you need to send a message to all objects of a certain type and various subtypes and get an appropriate, but different, reaction out of all of them).
Your app is not multi-threaded, especially in a non-worker task method type of codebase. OO is quite problematic in programs which are multithreaded and require different threads to do different tasks. If your program is structured with one or two main threads and many worker threads doing the same thing, the muddled control flow of OO programs is easier to handle, as all of the worker threads will be isolated in what they touch and can be considered as a monolithic section of code. Consider any other paradigm actually. Functional excels at multithreading (lack of side effects is a huge boon), and object based programming can give you boons with some of the encapsulation of OO, however with more traceable procedural code in critical sections of your codebase. Procedural of course excels in this arena as well.
Some places where OO isn't so good are where you're dealing with "Sets" of data like in SQL. OO tends to make set based operations more difficult because it isn't really designed to optimally take the intersection of two sets or the superset of two sets.
Also, there are times when a functional approach would make more sense such as this example taken from MSDN:
Consider, for example, writing a program to convert an XML document into a different form of data. While it would certainly be possible to write a C# program that parsed through the XML document and applied a variety of if statements to determine what actions to take at different points in the document, an arguably superior approach is to write the transformation as an eXtensible Stylesheet Language Transformation (XSLT) program. Not surprisingly, XSLT has a large streak of functionalism inside of it
I find it helps to think of a given problem in terms of 'things'.
If the problem can be thought of as having one or more 'things', where each 'thing' has a number of attributes or pieces of information that refer to its state, and a number of operations that can be performed on it - then OOP is probably the way to go!
The key to learning Object Oriented Programming is learning about Design Pattern. By learning about design patterns you can see better when classes are needed and when they are not. Like anything else used in programming the use of classes and other features of OOP languages depends on your design and requirements. Like algorithms Design patterns are a higher level concept.
A Design Pattern plays similar role to that of algorithms for traditional programming languages. A design pattern tells you how create and combine object to perform some useful task. Like the best algorithms the best design patterns are general enough to be application to a variety of common problems.
In my opinion it is more a question about you as a person. Certain people think better in functional terms and others prefer classes and objects. I would say that OOP is better suited when it matches your internal (subjective) mental model of the world.
Object oriented code and procedural code have different extensibility points. Object oriented solutions make it easier to add new classes without modifying existing functions (see the Open-Closed Principle), while procedural code allows you to add functions without modifying existing data structures. Quite often different parts of a system require different approaches depending upon the type of change that is anticipated.
OO allows for logic related to an object to be placed within a single place (the class, or object) so that it can be decoupled and easier to debug and maintain.
What I have observed, is that every app is a combination of OO and procedural code, where the procedural code is the glue that binds all your objects together (at the very least, the code in your main function). The more you can turn your procedural code into OO, the easier it will be to maintain yor code.
Why OOP is used for programming:
Its flexibility – OOP is really flexible in terms of use implementations.
It can reduce your source codes by more than 99.9% – it may sound like I’m over exaggerating, but it is true.
It’s much easier in implementing security – We all know that security is one of the vital requirements when it comes to web development. Using OOP can ease the security implementations in your web projects.
It makes the coding more organized – We all know that a Clean Program is a Clean Coding. Using OOP instead of procedural makes things more organized and systematized (obviously).
It helps your team to work with each other easily – I know some of you had/have experienced team projects and some of you guys know that it’s important to have the same method, implementations, algorithm etc etc etc
It depends by the problem: the OOP paradigm is useful in designing distribuited systems or framework with a lot of entity living during the actions of the user (example: web application).
But if you have a math problem you will prefer a functional language (LISP); for a performance-critical systems you will use ADA or C, etc etc.
The language OOP is useful because too it use probabily the garbage collector (automatic use of memory) in the run of program: you you program in C a lot of time you must debug and correct manually a problem of memory.
OOP is useful when you have things. A socket, a button, a file. If you end a class in er it is almost always a function that is pretending to be a class. TestRunner more than likely should be a function that runs tests(and probably named run tests).
Personally, I think OOP is practically a necessity for any large application. I can't imagine having a program over 100k lines of code without using OOP, it would be a maintenance and design nightmare.
I tell you when OOP is bad.
When the architect writes really complicated, non-documented OOP code. Leaves half way through the project. And many of his common code pieces he used across various project has missing code. Thank god for .NET Reflector.
And the organization was not running Visual Source Safe or Subversion.
And I'm sorry. 2 pages of code to login is rather ridiculous even if it is cutely OOPed....