Related
An object oriented application is made up of several different objects. Before engineers start writing code for the participating objects:
How does one decide what should be an object?
Your question is too open as to admit a concrete answer, so let me provide some thoughts that could help you get started.
Let's assume that we are going to use a pure OO language like Smalltalk where everything is an object.
When working with objects for representing some reality (or fantasy) you usually don't try to identify all of them before you start. Instead, you identify the few that first come to mind as good representatives of your domain. For instance, if you are writing an application for modeling some aspects of Chemistry, you might want to start with Atom and Molecule.
Generally speaking, you should try to focus on concrete an important entities from your domain. Do not think in their interactions yet.
Once you have identified the first few objects, you should focus on the inherent behavior of each of them. For instance, if you are modeling a colony of ants, then your Ant objects will have to know how to move around, how to get back to the nest, how to cut or carry a leaf, etc.
As soon as you add more and more methods to your objects you will discover new objects that are required to enhance the behavior of the ones you have identified. For instance, if you are modeling a chess game, and you have already identified the Pawn object, you will soon realize that you need to model the CheckBoard, the CheckGame and so on.
So, the identification of objects is not something you try to address before you start. Instead, it is something that you will naturally discover by the evolution of your model. As your objects mature, i.e., as they learn more things, they will "reveal" which other objects are still missing.
In the course of your modeling you will likely hit some pieces of knowledge you lack. Here is when you need to ask a domain expert, read or study related material, ask questions in fora such as Stack Overflow, etc. In this regard you will find yourself learning more about the domain so you can "explain" your newly acquired knowledge to your objects. In some regards you will feel that your objects are asking you questions that you would have never conceived yourself and all these activities will fruitfully populate your model with an increasing number of classes (or prototypes) and methods.
I must say this is a very interesting question, how someone identify the object. Based on my knowledge I would like to say that programmer should not worry about object as it is the representation of something. It is good to relate object oriented programming with real world. So programmer should firstly identify the class which can be the real world entity and then to describe that real world entity we need object.
For suppose you are developing a project for the librarian, who informed you below problem
"As a librarian, I want library management system where there are different types of reader for books, magazines, CDs and DVDs" (something like this)
So developer can easily identify the class based on its real world representation
classes should be
Librarian
Book
Magazine
CD
Reader
And object can be Programming C++ book, Advance JAVA book. Hardik is the reader etc.
So, the object is the representation of the real world entity, which has some specific meaning.
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.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
The question seems pretty simple, and so is the answer. I am a developer who recently started working. So far I had taken few bachelor and master level courses on OOP. And yet I am not comfirtable and confident with OOP concepts. Recently, I was searching for employment opportunities and I found that many employers were keen to know how much confident I am on OOP concepts.
I have a very strong theorotical knowledge on OOP concepts. Although this theorotical knowledge is helping me in clearing the interviews and getting a job but when it comes to implementation I am getting dumb. If you ask me what is reflection then you will get a perfect answer from me, but if someone asks me why and where do we use it, then I get fumbled.
Now I really want to know what I should do when I am not getting an opportunity to implement all or most of the OO concepts in my projects.
Also I really feel with all the latest development tools and programming environments, many of the programmers are getting pampered to use already built components, frameworks and libraries and this is might create a vacuum of good architects.
I want to become a successful architect and for that I think I must be very strong in this area.
Then I thought of learning NHibernate where you will be dealing with objects entirely.
Now what I need is few valuable tips that would help me in grasping all or most of the OOP concepts.
It sound like you're missing real programming experience. Nothing will substitute that.
Go working, exercise, read, learn from your more experienced colleagues. Eventually you'll get it.
As for very advanced tools, you are correct. They produce code monkeys in ever increasing amounts. If you see it right now you are on a good start. Just keep to the path. Good architects will always be needed and valued.
You want to start looking at design patterns. Knowing the when, how and why of using OOP is more valuable than knowing OOP itself.
Frameworks are great and I don't fault people for using them. But, there is still a lot of room for great architects in this space. Exploit the gap of programmers knowing how to use them, but not why or when. Frameworks quickly become a hammer looking for a nail for many developers. Open source is your friend here - dive into the source code and learn them from the inside out so you really understand what's being done and why.
In my experience, you learn the "conceptual" side of development from school and the "applications" side from real experience. There is no substitute for working on the job; no matter how much schooling I've had it never equates to what I've learned doing the real work. This is why it's also a good idea to get an internship in college if you're able.
As for the value of OOP itself, I find that it's most useful in large projects and in team projects. The whole point is to break down the solution into workable "conceptual" elements which makes intercommunication between team members easier as well as visualizing the solution. Visualization is the other big pro to OOP.
One thing to note about OOP IMHO is that entry level developers tend to overuse a lot of the OOP concepts. Not everything requires inheritance. Design patterns are extremely useful but also shouldn't be over applied. Look at your problem and first try to think of a solution on your own then compare it to known patterns and see if they provide a better answer. Simplicity can't be overrated.
Also, playing with tools like UML editors and Mind Mappers (such as XMind) are helpful in getting into the right frame of mind.
Check and see if there are any programming groups around you too; I find it's a good way to meet people that you can talk programming with and another advantage of OOP is its much easier to communicate programming ideas with.
Your next stop should be to look into design patterns (Applied OO). For an introductory text, check out Headfirst Design Patterns.
Interesting question. To some extent I've grown up with Object programming, I've evolved as the various frameworks have evolved, I'd never before considered how it would feel to come to a landscape where so many sophisticated frameworks already exist. Their very presence tends to inhibit that degree of fumbling and stumbling and generallly getting it wrong that leads to deeper understanding.
My perception though is that serious development is still a matter of good design, it's not all just fill-in-the-gaps, hey IOC framwork tell me what to do, programming.
You can enhance your theoretic knowlege by studying the "how" of the framworks you use. But I guess what you need is practical experience, can't comment upon what's open to you in your place of work, but if you can't get it there you may need to do some "hobbyist" or open source development.
One thing I would recommend is trying to get involved in design discussions, try to get your designs reviewed by experienced developers. With any luck they may even say: "hey why didn't you use reflection there ..."
It is the 'thinking' that is important, in OOP one needs to change thinking
while going about programming/developing in oop environment or using OOP
paradigm.
I have faced many a times this question myself: why use OOPL or
Object Oriented Programming Language when I can develop software in Procedural
Programming Language? Why use OOP methodology at all? What benefit does it have
what other non-oop doesn't?
I read from many sources (numerous books and articles on the subject to name!)
to trace the real reason, to hit the fundamental underlying idea or principle
for its being there as a paradigm of software engineering. I think what I found
is simple and that's why I suggest to bring a change in thinking.
If we look around we see things that surround us and the things we interact
with, directly or indirectly. We recognize them with names, we gave them.
Whatever the things are, either they exist in real plane or conceptual plane
and we 'know' them 'recognize' them and interact with them. And importantly we
'name' them. This naming is important because to interact with the 'things' and
for that knowledge of that interaction we need 'Names'.
What have you eaten today? Chocolate and coffee. So you have 'interacted' with
chocolate and coffee. Now Chocolate and coffee are edibles we have (humans)
have given names and with those names we recognize them. And also, we, in our
knowledge of our interaction with them - lets say keeping record of our
interaction with chocolate and coffee, know them with names as having
interacted with.
Interaction is a general term I am using here. Actually in our case, in the
example, you have performed an 'action' - eating. Through 'eating' action you
have interacted with chocolate and coffee. Now think this way, you, chocolate,
coffee are entities in the real world through an action came in interaction.
You may say a 'Process'.
What course Alice has enrolled for? Computer Science.
Computer Science does not have a real existence in the world in the sense a man
exists or a tree or a house, or coffee cup or other 'tangible things' exist. It
is a subject, 'conceptual thing'. The study of computer science has some
'topics' to be studied (or to have interaction with through our mental
faculty/processes)e.g discrete mathematics, design and analysis of algorithms,
Data Structure etc. Together they are named, as a subject of study, 'Computer
Science'. Now Alice 'study' (interaction) Computer Science.What is happening
here? OK, if We now think this way and say that Alice is a thing, an object.
Computer Science is a thing, an object.
Coffee is an object. Chocolate is an object. You, again, are an object. We find
that objects interacting with objects. Fantastic! One may exclaim! That's the
real world scenario! Actually it is a generalization reached through
Abstraction.
It is nothing but -at the surface level at least- naming with
meaning. Or you can say 'meaningful naming'. It is a process. It is so natural
and obvious to us that we simply overlook it.
In OOP we simply have to bring ourselves to this form of thinking process,
knowing and reminding ourselves that "Objects interact with Objects". Oh!
There are more than thinking only this. You have to remember that an object
may interact with itself! Think of you, what are you doing when you are
thinking? Yeah! And there is another very important thing I shall come to
in due time. Though I think it is obvious. But in due time. OK. What we
really do with computers? Actually we solve problems. Particularly those
problems which we try to do or solve in our minds. In broad sense we are
simulating mental processes in a machine, so designed by us. Remember AI is
still a far off thing in reality and there are debates both scientific and
philosophical, on whether a computer can become Intelligent at all. Another
way of putting it whether a computer can really simulate a real mental
process. But that's not for us to take here. Leave it!
If we want to solve problems in real life through a computing device we
would like to go as closely in representing the real life as possible.There
comes the term in OOP 'real life modelling'. It can be seen that in solving
real life problems, be it launching a space shuttle, or keeping the customer
and product sale information for processing we do abstraction and do
calculation, which is another form of abstract process, in turn we deal with
objects mentally, in our mind. So we represent real life objects (conceptual
objects such as numbers) in abstraction and deal with them with abstract
processes, as in mathematics. In computer too we would like to represent
objects and also like to represent processes in the form of objects. So here
comes the Object Orientation so to speak to software engineering. Now comes
that 'due time' to deal with another aspect of OO.
To go back to our example, What did you eat? Eating is an action, a form of
interaction. Which can be thought of as process which again can be thought of
as an Object, like a processes is thought of and represented as 'function' or
'routine' or 'procedure' in Non-OOPL. In OOP we can represent (abstract away)
eating as a process embodied as an object. Similarly studying is an object. In
the same line of thinking 'thing' and 'process' both be thought of as objects
and be represented in virtual plane which is computer memory. Therefore
Alice-an Object-Studies-an object-Computer Science-an Object is valid in OOP
parlance as far as our argument goes.
Can we write a piece of code here? Lets try.
class Alice {
private String name;
private String address;
private String stdID;
private Course courseOfStudy;
... other codes...
public void studies(Course sub) {
courseOfStudy=sub;
}
...
public Course getStudyCourse() {
return courseOfStudy;
}
}
class Course {
codes....
}
This way in OOP (here Java code) one can go about writing codes. I have just
given a simplistic coding. One can come up with better coding and design
approach depending on the software in mind to be written. In OOP design is very
important. So in thinking which I mentioned at the beginning the change should
be brought in. That's important! I prefer to go this way when it comes to OOPL
or OOAD, "everything is object".
Well that's what I wanted to say. You may or may not like it but comment and
say your mind.
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 asked to begin teaching C# and OO concepts to a group of procedural programmers. I've searched for ideas on where to begin, but am looking for general consensus on topics to lead with in addition to topics to initially avoid.
Edit
I intend to present information in 30 minute installments weekly until it no longer makes sense to meet. These presentations are targeted at coworkers at a variety of skill levels from novice to expert.
The best thing you can do is: Have a ton of Q&A.
Wikipedia's procedural programming (PP) article really hits where you should start:
Whereas procedural programming uses
procedures to operate on data
structures, object-oriented
programming bundles the two together
so an "object" operates on its "own"
data structure.
Once this is understood, I think a lot will fall into place.
In general
OOP is one of those things that can take time to "get," and each person takes their own path to get there. When writing in C#, it's not like the code screams, "I am using OO principles!" in every line. It's more of a subtle thing, like a foreach loop, or string concatenation.
Design center
Always use something (repeatedly) before making it.
First, use an object, and demonstrate the basic differences from PP. Like:
static void Main(string[] args)
{
List<int> myList = new List<int>();
myList.Add(1);
myList.Add(7);
myList.Add(5);
myList.Sort();
for (int i = 0; i < myList.Count; i++)
{
Console.WriteLine(myList[i]);
}
}
Using objects (and other OO things) first -- before being forced to create their own -- leads people down the path of, "Ok, I'm making something like what I just used," rather than "WTF am I typing?"
Inheritance (it's a trap!)
I would NOT spend a lot of time on inheritance. I think it is a common pitfall for lessons to make a big deal about this (usually making a cliché animal hierarchy, as others pointed out). I think it's critical to know about inheritance, to understand how to use the .NET Framework, but its nuances aren't that big of a deal.
When I'm using .NET, I'm more likely to "run into inheritance" when I'm using the .NET Framework (i.e. "Does this control have a Content property?" or "I'll just call its ToString() method.") rather than when I'm creating my own class. Very (very (very)) rarely do I feel the need to make something mimicking the taxonomy structure of the animal kingdom.
Interfaces
Coding to an interface is a key mid-level concept. It's used everywhere, and OOP makes it easier. Examples of this are limitless. Building off the example I have above, one could demonstrate the IComparer<int> interface:
public int Compare(int x, int y)
{
return y.CompareTo(x);
}
Then, use it to change the sort order of the list, via myList.Sort(this). (After talking about this, of course.)
Best practices
Since there are some experienced developers in the group, one strategy in the mid-level classes would be to show how various best practices work in C#. Like, information hiding, the observer pattern, etc.
Have a ton of Q&A
Again, everyone learns slightly differently. I think the best thing you can do is have a ton of Q&A and encourage others in the group to have a discussion. People generally learn more when they're involved, and you have a good situation where that should be easier.
The leap from procedural to object oriented (even within a language - for four months I programmed procedural C++, and classes were uncomfortable for a while after) can be eased if you emphasize the more basic concepts that people don't emphasize.
For instance, when I first learned OOP, none of the books emphasized that each object has its own set of data members. I was trying to write classes for input validation and the like, not understanding that classes were to operate on data members, not input.
Get started with data structures right away. They make the OOP paradigm seem useful. People teach you how to make a "House" class, but since most beginning programmers want to do something useful right away, that seems like a useless detour.
Avoid polymorphism right away. Inheritance is alright, but teach when it is appropriate (instead of just adding to your base class).
Operator overloading is not essential when you are first learning, and the special ctors (default, dtor, copy ctor, and assignment operator all have their tricky aspects, and you might want to avoid that until they are grounded in basic class design).
Have them build a Stack or a Linked List. Don't do anything where traversal is tricky, like a binary tree.
Do it in stages.
High level concepts : Describe what an object is and relate it to real life.
Medium level concepts: Now that they got what object is, try compare and contrast. Show them why global variable is bad compared to an encapsulated value in a class. What advantage they might get from encapsulating. Start introducing the tennets of OOP (encapsulation, inheritance)
Low Level concepts: Go in further into polymorphism and abstraction. Show them how they can gain even better design through polymorphism and abstraction.
Advance concepts: SOLID, Interface programming, OO design patterns.
Perhaps you should consider a problem that is work related and start with a procedural implementation of it and then work through (session by session) how to make an OOP implementation of it. I find professionals often grasp concepts better if it is directly related to real examples from their own work place. The junk examples most textbooks use are often horrible for understanding because they leave the student wondering, why on earth would I ever want to do that. Give them a real life reason why they would want to do that and it makes more sense.
I would avoid the "a bicycle is a kind of veichle" approach and try to apply OO to an environment that is fairly specific and that they are already used to. Try to find a domain of problems that they all recognize.
Excercise the basics in that domain, but try to move towards some "wow!" or "aha!" experience relatively early; I had an experience like that while reading about "Replace Conditional with Polymorphism" in Fowlers Refactoring, that or similar books could be a good source of ideas. If I recall correctly, Michael Feathers Working effectively with legacy code contains a chapter about how to transform a procedural program into OO.
Teach Refactoring
Teach the basics, the bare minimum of OO principles, then teach Refactoring hands-on.
Traditional Way: Abstractions > Jargon Cloud > Trivial Implementation > Practical Use
(Can you spot the disconnect here? One of these transitions is harder than the others.)
In my experience most traditional education does not do a good job in getting programmers to actually grok OO principles. Instead they learn a bit of the syntax, some jargon they have a vague understanding of, and a couple canonical design examples that serve as templates for a lot of what they do. This is light years from the sort of thorough understanding of OO design and engineering one would desire competent students to obtain. The result tends to be that code gets broken down into large chunks in what might best be described as object-libraries, and the code is nominally attached to objects and classes but is very, very far from optimal. It's exceedingly common, for example, to see several hundred line methods, which is not very OO at all.
Provide Contrast To Sharpen The Focus on the Value of OO
Teach students by giving them the tools up front to improve the OO design of existing code, through refactoring. Take a big swath of procedural code, use extract method a bunch of times using meaningful method names, determine groups of methods that share a commonality and port them off to their own class. Replace switch/cases with polymorphism. Etc. The advantages of this are many. It gives students experience in reading and working with existing code, a key skill. It gives a more thorough understanding of the details and advantages of OO design. It's difficult to appreciate the merits of a particular OO design pattern in vacuo, but comparing it to a more procedural style or a clumsier OO design puts those merits in sharp contrast.
Build Knowledge Through Mental Models and Expressive Terminology
The language and terminology of refactoring help students in understanding OO design, how to judge the quality of OO designs and implementations through the idea of code smells. It also provides students a framework with which to discuss OO concepts with their peers. Without the models and terminology of, say, an automobile transmission, mechanics would have a difficult time communicating with each other and understanding automobiles. The same applies to OO design and software engineering. Refactoring provides abundant terminology and mental models (design patterns, code smells and corresponding favored specific refactorings, etc.) for the components and techniques of software engineering.
Build an Ethic of Craftsmanship
By teaching students that design is not set in stone you bolster students' confidence in their ability to experiment, learn, and discover. By getting their hands dirty they'll feel more empowered in tackling software engineering problems. This confidence and practical skill will allow them to truly own the design of their work (because they will always have the skills and experience to change that design, if they desire). This ownership will hopefully help foster a sense of responsibility, pride, and craftsmanship.
First, pick a language like C# or Java and have plenty of samples to demonstrate. Always show them the big picture or the big idea before getting into the finer details of OO concepts like abstraction or encapsulation. Be prepared to answer a lot of why questions with sufficient real world examples.
I'm kinda surprised there's any pure procedural programmers left ;-)
But, as someone who started coding back in the early 80s on procedural languages such as COBOL, C and FORTRAN, I remember the thing I had most difficulty with was instantiation. The concept of an object itself wasn't that hard as basically they are 'structures with attached methods' (looked at from a procedural perspective) but handling how and when I instantiated an object - and in those days without garbage collection - destroyed them caused me some trouble.
I think this arises because in some sense a procedural programmer can generally point to any variable in his code any say that's where that item of data is directly stored, whereas as soon as you instantiated an object and assign values to that then it's much less directly tangible (using pointers and memory allocation in C is of course similar, which may be a useful starting point also if your students have C experience). In essence I suppose it means that your procedural -> OOPS programmer has to learn to handle another level of abstraction in their code, and getting comfortable with this mental step is more difficult than it appears. By extension I'd therefore make sure that your students are completely comfortable with allocating and handling objects before looking at such potentially confusing concepts as static methods.
I'd recommend taking a look at Head First Design Patterns which has really nice and easy to understand examples of object oriented design which should really help. I wouldn't emphasize the 'patterns' aspect too much at this point though.
I'm a vb.net intermediate programmer, and I'm learning OOP. One of the things I find is the lecturing about the concepts over and over is unnerving. I think what would be perfect documentation would be a gradual transition from procedural programming to full blown OOP rather than trying to force them to understand the concepts then have them write exclusively OOP code using all the concepts. That way they can tinker with little projects like "hello world" without the intimidation of design.
For example (this is for VB.NET beginners not advanced procedural programmers).
I think the first chapters should always be about the general concepts, with just a few examples, but you should not force them to code strictly OOP right away, get them used to the language, so that it's natural for them. When I first started, I had to go back and read the manual over and over to remember HOW to write the code, but I had to wade through pages and pages of lecturing about concepts. Painful!
I just need to remember how to create a ReadOnly Property, or something. What would be real handy would be a section of the book that is a language reference so you can easily look in there to find out HOW to write the code.
Then you briefly explaining how forms, and all the objects are already objects, that have methods, and show how they behave, and example code.
Then show them how to create a class, and have them create a class that has properties, and methods, and the new construct. Then have them basically switch from them using procedural code in the form or modules, to writing methods for classes.
Then you just introduce more advance codes as you would any programming language.
Show them how inheritance works, etc. Just keep expanding, and let them use thier creativity to discover what can be done.
After they get used to writing and using classes, then show how thier classes could improve, introducing the concepts one by one in the code, modifying the existing projects and making them better. One good idea is to take an example project in procedural code, and transform it into a better application in OOP showing them all the limitations of OOP.
Now after that is the advanced part where you get into some really advanced OOP concepts, so that folks who are familar with OOP already get some value out of the book.
Define an object first, not using some silly animal, shape, vehicle example, but with something they already know. The C stdio library and the FILE structure. It's used as an opaque data structure with defined functions. Map that from a procedural use to an OO usage and go from there to encapsulation, polymorphism, etc.
If they are good procedural programmers and know what a structure and a pointer to a function are, the hardest part of the job is already done!
I think a low level lecture about how Object Oriented Programming can be implemented in procedural languages, or even assembler, could be cool. Then they will appreciate the amount of work that the compiler does for them; and maybe they will find coding patterns that they already knew and have used previously.
Then, you can talk about best practices in good Object Oriented design and introduce a bit of UML.
And a very important thing to keep in mind always is that they're not freshmen, don't spend much time with basic things because they'll get bored.
Show Design Patterns in Examples
There where some plenty good answers, alright. I also think, that you should use good languages, good, skillful examples, but I have an additional suggestion:
I have learned what OOP means, by studying Design Patterns. Of course, I have of course learned an OO-language before, but until I was working on Design Patterns, I did not understand the power of it all.
I also learned much from OO-Gurus like Robert C. Martin and his really great papers (to be found on his companies site).
Edit: I also advocate the use of UML (class diagrams) for teaching OO/Design-Pattern.
The thing that made it click for me was introducing Refactoring and Unit Testing. Most of my professional programming career has been in OO Languages, but I spent most of it writing procedural code. You call a function on an instance of class X, and it called a different method on an instance of class Y. I didn't see what the big deal about interfaces was, and thought that inheritance was simply a concept of convenience, and classes were by and large a way of helping us sort and categorize the massive code. If one was masochistic enough, they could have easily go through some of my old projects and inline everything until you get to one massive class. I'm still acutely embarrassed at how bad my code was, how naive my architecture was.
It half-clicked when we went through Martin Fowler's Refactoring book, and then fully clicked when started going through and writing Unit and Fitnesse tests for our code, forcing us to refactor. Start pushing refactoring, dependency injection, and separation of the code into distinct MVC models. Either it will sink in, or their heads will explode.
If someone truly doesn't get it, maybe they aren't cut out for working on OO, but I don't think anyone from our team got completely lost, so hopefully you'll have the same luck.
I'm an OO developer professionally, but have had had procedural developers on my development team (they were developing Matlab code, so it worked). One of the concepts that I like in OO programming is how objects can relate to your domain (http://en.wikipedia.org/wiki/Domain-driven_design - Eric Evans wrote a book on this, but it is not a beginner's book by any stretch).
With that said, I would start with showing OO concepts at a high level. Try to have them design a car for example. Most people would say a car has a body, engine, wheels, etc. Explain how those can relate to real world objects.
Once they seem to grasp that high level concept, then I would start in on the actual code part of it and concepts like inheritance vs aggregation, polymorphism, etc.
I learned about OOP during my post-secondary education. They did a fairly good job of explaining the concepts, but completely failed in explaining why and when. They way they taught OOP was that absolutely everything had to be an object and procedural programming was evil for some reason. The examples they were giving us seemed overkill to me, partly because objects didn't seem like the right solution to every problem, and partly because it seemed like a lot of unnecessary overhead. It made me despise OOP.
In the years since then, I've grown to like OOP in situations where it makes sense to me. The best example I can think of this is the most recent web app I wrote. Initially it ran off a single database of its own, but during development I decided to have it hook into another database to import information about new users so that I could have the application set them up automatically (enter employee ID, retrieves name and department). Each database had a collection of functions that retrieved data, and they depended on a database connection. Also, I wanted an obvious distinction which database a function belonged to. To me, it made sense to create an object for each database. The constructors did the preliminary work of setting up the connections.
Within each object, things are pretty much procedural. For example, each class has a function called getEmployeeName() which returns a string. At this point I don't see a need to create an Employee object and retrieve the name as a property. An object might make more sense if I needed to retrieve several pieces of data about an employee, but for the small amount of stuff I needed it didn't seem worth it.
Cost. Explain how when properly used the features of the language should allow software to be written and maintained for a lower cost. (e.g. Java's Foo.getBar() instead of the foo->bar so often seen in C/C++ code).Otherwise why are we doing it?
I found the book Concepts, Techniques, and Models of Computer Programming to be very helpful in understanding and giving me a vocabulary to discuss the differences in language paradigms. The book doesn't really cover Java or C# as 00-languages, but rather the concepts of different paradigms. If i was teaching OO i would start by showing the differences in the paradigms, then slowly the differences in the 00-languages, the practical stuff they can pickup by themselves doing coursework/projects.
When I moved from procedural to object oriented, the first thing I did was get familiarized with static scope.
Java is a good language to start doing OO in because it attempts to stay true to all the different OO paradigms.
A procedural programmer will look for things like program entry and exit points and once they can conceptualize that static scope on a throwaway class is the most familiar thing to them, the knowledge will blossom out from there.
I remember the lightbulb moment quite vividly. Help them understand the key terms abstract, instance, static, methods and you're probably going to give them the tools to learn better moving forward.
As a second interview I get people to sit down and write code...I try to make the problem really technology independent.
My programming problems that I have don't really exercise peoples OO abilities. I tend to try and keep the coding problem solvable within 2 hours ish. So, I've struggled to find a problem small enough and involved enough that it exposes peoples OO design skills.
Any suggestions?
This is a problem that I use with some trainings, looks simple but is tricky OOP-wise:
Create model classes that will properly represent the following constructs:
Define a Shape object, where the object is any two dimensional figure, and has the following characteristics: a name, a perimeter, and a surface area.
Define a Circle, retaining and accurately outputting the values of the aforementioned characteristics of a Shape.
Define a Triangle. This time, the name of the triangle should take into account if it is equilateral (all 3 sides are the same length), isoceles (only 2 sides are the same length), or scalene (no 2 sides are the same).
You can go on and on with quadrelaterals (which include squares, rectangles, rhombi, etc) and other polygons.
The way that they would solve the above problems would reveal the people who understand OOP apart from those who don't.
ideally, you want to present a problem that appears difficult, but has a simple, elegant, obvious solution if you think in OO terms
perhaps:
we need to control access to a customer web site
each customer may have one or more people to access the site
different people from different customers may be able to view different parts of the site
the same person may work for more than one customer
customers want to manage permissions based on the person, department, team, or project
design a solution for this using object-oriented techniques
one OO solution is to have a Person, a Customer, an Account, and AccountPermissions, where the Account specifies a Person and a Customer and an optional Parent Account. the use of a recursive Account object collapses the otherwise cumbersome person/team/department/project structure a direct ERD solution might yield
I have used the FizzBuzz Programming Test. And shockingly can corroborate the claims made by the article. As a second follow up I have asked candidates to compute the angle(s) between the hands on an analog clock. We set up a laptop with VS 2008 installed and the stub in place. all they have to do is fill in the implementation.
I am always stunned at how poorly candidates do on these two questions. I really am.
Designing Social Security Application is something which I ask a lot of people during interviews.
The nice thing about this is everyone is aware of how it works and what things to keep track of.
They also have to justify their design and this really helps me get inside their head :)
(As there is lots of flexibility here)
Kind regards,
Whether or not people do some coding in the interview, I make it a point to ask this:
Tell me about a problem you solved recently using object oriented programming. You'd be surprised how often people cannot answer that simple question. A lot of times I get a blank stare, or they say something like "what do you mean? I program in .NET, which is all object oriented."
These aren't specifically OO Questions, but check out the other questions tagged interview-questions
Edit: What about implementing some design patterns? I don't have the best knowledge in the area but it seems as if you would be getting two questions for the price of one. You can test for both OO and Design pattens in the one question.
How about some sort of simple GUI. It's got inheritance, overriding, possibly events. If you mean for them to actually implement as part of the test then you could hand them a blank windows-form with an OnPaint() and tell them to get to it.
You could do worse than ask them to design a MapReduce library with a single-process implementation. Will the interface still work for a distributed implementation? What's the exception-handling policy? Should there be special support for chaining MapReduce jobs in a pipeline? What's the interface to the inputs and outputs? How are inputs chunked up? Can different inputs in one job go to different mappers? What defaults are reasonable?
A good solution in Python takes about a page of code.
I've got a super simple set. The idea is mainly to use them to filter out people who really don't know their stuff rather than filtering in the rock stars.
These are all 5 minute white-board type questions, so they are really not that hard. But the act of writing up code, and talking through it reveals a lot about a candidate - and is brilliant for exposing those that can otherwise BS through the talk.
Write a method that takes a radius of a circle as an argument, and returns the area of the circle (You would be amazed how many people struggle on this one!)
Write a program that accepts a series of numbers as arguments from the command line. Add them up, and print the sum
Write a class that acts as a keyed counter (basically a map that keeps track of how many times each key is "counted")