views:

1514

answers:

27

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?

+1  A: 

Roll up your sleeves and code!

John at CashCommons
What do you think he's been doing? He's looking for a different method.
Ludwi
Ludwi: He's been exposed to enough methods. He needs to use them.
John at CashCommons
I hate these answers. Practice makes permanent, not perfect.
Martin
Whenever I see someone saying that he's read a lot of books (which he has) and still doesn't get it, then they haven't tried enough. If you don't like my answer, IDGARA, but trying stuff is where I've made most of my progress, not finding yet another opinion to confuse me.
John at CashCommons
+18  A: 

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%5Frepeat%5Fyourself

FIT: http://www.netwellness.org/question.cfm/38221.htm

DDD: http://domaindrivendesign.org/

DDD required reading: http://www.infoq.com/minibooks/domain-driven-design-quickly

TDD: http://en.wikipedia.org/wiki/Test-driven%5Fdevelopment

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.

Andrew Siemer
Not all of those acronyms necessarily have anything to do with object oriented design though. (i.e. the DRY principle remains important in any type of programming language)
wds
I agree. But they do still apply to proper object oriented programming.
Andrew Siemer
+2  A: 

TDD has helped me most in improving my overall skillset including OOP.

jamesaharvey
+3  A: 

The aswer is in your question ;)

Practice, practice, practice.

Review your own code and learn from the mistakes.

Neil N
Along the lines of Neil's answer here, what is so different about your code and their code? Could you <del>steal</del> borrow their patterns. :-)
Frank V
A: 

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.

RibaldEddie
+1  A: 

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.

cherouvim
A: 

You're my target audience. Look at Building Skills in OO Design

Perhaps this can help.

S.Lott
Your link isn't working.
jamesaharvey
Thanks -- markdown doesn't like URL's with _'s.
S.Lott
+17  A: 

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.

zombat
A: 

You said the answer yourself: practice. Best solution for this is to develop a game. Use the concepts you learnt in the books there.

Aviral Dasgupta
A: 

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.

McAden
+7  A: 

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.

Achim
A: 

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,

Rob Wells
+2  A: 

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.

chaos
A: 

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.

+4  A: 

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.

Bill Karwin
agree about the eureka moment. I used to feel the same way Supertux did, about patterns and architecture, and one day my mind just opened up. I had to read a lot though.
silverCORE
+6  A: 

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.

jalf
+1  A: 

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.

Saif Khan
+1  A: 

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.

Jörg W Mittag
A: 

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!

JMSA
+1  A: 

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.

SuperSized
+2  A: 

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.

Vijay Mathew
A: 

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.

Joe Philllips
+1  A: 

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.

Vladimir Grigorov
+1  A: 

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.

Rui Craveiro
+3  A: 

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.

  1. 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.

  2. 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.

  3. When all this is done, then worry about the internals of how the class works.

Brian
A: 

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.

burnt_hand
A: 
       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.

        }
    }
Alex Baranosky