OO design: Identifying classes

wallst

Junior Member
Jul 24, 2012
6
0
0
Hi,
I have started to try and design a system using OO principles. I have the model, but now I'm stuck on the next step. I followed the steps to identify the domain model and the classes. inheritance aggregation etc.
E.g
Hotel has rooms
Hotel has customers
Customers have reservations
Reservations have rooms
Manager is a customer
Single is a room
Double is a room

I want to build a reservation system, but I dont how the above helps me.
I can identify responsibilities with these classes, makereservation with customer etc. Customer can log in and make a reservation.
You get the data from the customer it sends the data to a reservation object which creates a reservation and stores it to a file. Thats fine, I understand this.
However, I need a method that tells the customer object if rooms are available, before it can simply reserve a room.
I have 5 rooms. on July 8th 4 rooms are booked, 2 customers want to reserve a room for July 8th. The above system will allow them to do so, unless I have something that tells the system only one room is available. Normally I would check a file or database for July 8th, if there are 4 records returned and I have 5 rooms, one is available, but how do you do this with objects? Hope I'm not demonstrating complete stupidity, but unfamiliar with OOP.
 

wallst

Junior Member
Jul 24, 2012
6
0
0
Not using database, using a csv file instead. The data end is fine, I can work that out when it comes to it or make changes where necessary. The logic of using objects to work as a control system is what's confusing me. If I get the data from the user, I can write the data to the correct file. But between those two sides, I need a control system. e.g Get dates, get userID, getRoom,CONTROL SYSTEM, write to file. The control system will getRoom(if available). In my domain, I dont have this control system, do I just add a class called Control, that does the work other classes cant do.
Thanks
 

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,589
5
0
Your control system is the Hotel Operations
 

wallst

Junior Member
Jul 24, 2012
6
0
0
Design pattern?? No, I'm hardly familiar with clasess OOP etc. Thats the purpose of this system, just to get experience in designing classes and then implementing them. Plan to work on Patterns, etc, once I have at least polymor encapsulation inheritance abstraction better understood.
My control system is the hotel operations??
So this means that Hotel class has access to rooms and reservations.
Hotel has rooms.
Reservations have rooms.
Hotel has customers.
Hotel is connected to all the required, so I give Hotel class the responsibilities of control as Hotel knows about all the objects. Reservations doesn't know about customers who have no reservations. Is that the idea?
data(rooms+reservations+customers). Available rooms can be found through the hotel class.
Code:
Public class Hotel
variables
singlerooms=10;doublerooms=10
methods
Hotel has rooms
Hotel has reservations

Code:
getAvailableRooms("Single",date)
      Search reservations file for single+date match.
      Found =5. 
      Return singleRooms-found
Hotel has customers
Code:
getReservation()
    Search reservations file for custID
     Return found
 

douglasb

Diamond Member
Apr 11, 2005
3,157
0
76
^ that's the basic idea. Hotel class would (presumably) know about literally everything except other instances of Hotel. Maybe you have a class above that knows about different Hotels. Maybe not, if you only have to keep track of one Hotel. If there is only one Hotel, and there will NEVER be more than one Hotel for your application, then consider making the Hotel class static.
 

MooseNSquirrel

Platinum Member
Feb 26, 2009
2,587
318
126
In my humble opinion you are not tackling this with the right approach.

What is the most important item in a reservation system?
 

douglasb

Diamond Member
Apr 11, 2005
3,157
0
76
I would probably add a "Calendar" class or something similar. You could have a row for each day of the year in your CSV, and a boolean column for each hotel room. Then just set the column for each room/day to true or false depending on if that room is reserved for that day.
 

BrightCandle

Diamond Member
Mar 15, 2007
4,762
0
76
Oo is not about the real life entities. Instead you need to think about the operations you need to do like reserving and see what data they modify. A class is the grouping of operations that work on the same data. While in then real world a hotel contains lots of rooms its probably not an useful class for modelling the system based on then approach I have suggested.
 

Cerb

Elite Member
Aug 26, 2000
17,484
33
86
I'd have to second that, and add that this kind of problem was what the relational database model was come up for (well, actually, it was mostly for employee info and reports, but that's surprisingly similar :)). OOP is great at abstracting and categorizing, in code and computer memory, the already abstract and well-categorized, like treating different types of IO as similar, handling the ugly details inside the classes, and creating more intricate data structures, without a programmer using them needing to know or care how they are implemented.

Here's a nice [heavily biased] read to get you thinking:
http://reocities.com/tablizer/myths.htm

It's not that OOP is really bad, though it is over-sold and over-used, but that the common folkways and folklore trying to make it out like it can be thought of as down to earth does little good (Dijkstra thought it did quite bad things, actually, and I come to agree with those ideas more and more, over time).

A board or card game would be much a better real world "thing" to make OOP for learning, as they already tend to have neat hierarchical categories, each thing in one is intimately tied to actions that may be taken within some set of rules, and all of it is already really a finite set of abstractions.

Make a simple chess game in an imperative OOP language, then in a LISP-a-like. While you may have some, "aha," functional moments, and your final application of rules in the imperative version will reflect that, you will prefer working with the imperative OOP version, <Justin>I gayhruntee</Justin>. I would lean towards board games with different pieces on the same board, so that some degree of polymorphism-as-typing is intuitively useful (even checkers qualifies, with king rules, though chess or Stratego would probably be more engaging for that purpose; Monopoly, as well, but that's a much more complicated game).

Seriously, don't worry about design patterns like MVC, for now, either. MVC, easily the most common, is practically a natural outcome of trying to use OOP principles for everything (especially polymorphism/inheritance for data fields and structures), then realizing how the added complexity breaks and bloats everything (more-so than running a DBMS along-side your application :), which is the common way to handle parts of the M and V portions), finally directing you towards divorcing your data, interfaces, and controlling logic as much as you reasonably can, because you will end up with ungodly mess if you don't.

Also, exactly where the 'view' in MVC begins and ends is something that can typically only be truly decided by having a manager state it, then smiling, nodding, and naming named things in your code to reflect that dividing line. Just so you know, because that will inevitably be a question that is hard to find good answers for. Not that there's anything [fundamentally] wrong with MVC, just that implementation is rarely as neat and tidy as requirements and presentations make it look. Not only that, but I'm not sure that thinking in terms of such design patterns matters at all, if you aren't working as part of a team, since on your own, you have access to, and the ability to change, any internal structural details, as you would like to do so. Design patterns are largely emergent. Build stuff, now. Then, try to pigeonhole it.

Practically every bit of OO 'theory' that came after Smalltalk-80 (Simula 67->Smalltalk->*) is rooted not so much in logical needs of the program, but in business needs of developing and maintaining software in a timely and budget-friendly manner. Keep that in mind, as well.
 

wallst

Junior Member
Jul 24, 2012
6
0
0
I would probably add a "Calendar" class or something similar. You could have a row for each day of the year in your CSV, and a boolean column for each hotel room. Then just set the column for each room/day to true or false depending on if that room is reserved for that day.

I thought of this idea as it would make things very simple for available rooms. Otherwise I would have to read every reservation on the system to check what its data and room type is and sum the data. Your way is much faster and easier to work with.

What is the most important entity in your reservation system
Guessing reservations are the most important entity or room bookings as they connect customers to my products.
you are not tackling this problem correctly. OO is about grouping cohesive operations and data
This is responsibility driven design.
I'm trying to create a new driven design, using every conceivable approach.
Maintain room bookings. This could be done by the Calendar class suggested by Douglas.
Make reservation, Get reservation and CancelReserve, these are similar operations, so could you put these in an interface class?
Maintain hotel data. Class. Maintain Customer data. Class. Maintain room info. Class???(somebody questioned this class previously).
Now I have a question about a reservation class. When somebody checksIn, it is no longer a reservation, it becomes a CheckIn. On the day of checkOut, CheckIn becomes a checkOut. Then, it would become a completed and paid reservation.Reservation->CheckIn->CheckOut->CompletedHotelBooking. Is that inheritance?
1)Would I store these entities in the same csv file with an additional Boolean element. So reservation would be TFFF->FTFF->FFTF->FFFT.
Sorry guys, must be driving you crazy with this.
My assumptions of OOP were very naive. I thought it was modelled on the real world, I see now my mistake, it should be modelled on the operations and data. DDD and RDD Try as best as you to group the data-responsibilty cohesively. Reservation object has access to reserve data, make it responsible for reservation. Customer object has customer data, make it responsible for CRUD customers.
2) Are these correct assumptions?
3) Define the responsibilities of the system and then work out the best way to achieve this. e.g Maintain room bookings. the Calendar class. Each time a reservation is made, the reservation class will notify the calendar class of certain date and tell it room type e.g if Single Rooms>0 then SingleRooms-1.
 

wallst

Junior Member
Jul 24, 2012
6
0
0
I'd have to second that, and add that this kind of problem was what the relational database model was come up for (well, actually, it was mostly for employee info and reports, but that's surprisingly similar :)). OOP is great at abstracting and categorizing, in code and computer memory, the already abstract and well-categorized, like treating different types of IO as similar, handling the ugly details inside the classes, and creating more intricate data structures, without a programmer using them needing to know or care how they are implemented.
A very good summary of OOP benefits. I may learn it word for word.
Here's a nice [heavily biased] read to get you thinking:
http://reocities.com/tablizer/myths.htm

It's not that OOP is really bad, though it is over-sold and over-used, but that the common folkways and folklore trying to make it out like it can be thought of as down to earth does little good (Dijkstra thought it did quite bad things, actually, and I come to agree with those ideas more and more, over time).
Perhaps somebody at my level shouldn't read that.


Seriously, don't worry about design patterns like MVC, for now, either. MVC, easily the most common, is practically a natural outcome of trying to use OOP principles for everything (especially polymorphism/inheritance for data fields and structures), then realizing how the added complexity breaks and bloats everything (more-so than running a DBMS along-side your application :), which is the common way to handle parts of the M and V portions), finally directing you towards divorcing your data, interfaces, and controlling logic as much as you reasonably can, because you will end up with ungodly mess if you don't.
Somebody somewhere asked me was I using MVC, so I then assumed I should as its the only one I was slightly aware of.
Also, exactly where the 'view' in MVC begins and ends is something that can typically only be truly decided by having a manager state it, then smiling, nodding, and naming named things in your code to reflect that dividing line. Just so you know, because that will inevitably be a question that is hard to find good answers for. Not that there's anything [fundamentally] wrong with MVC, just that implementation is rarely as neat and tidy as requirements and presentations make it look. Not only that, but I'm not sure that thinking in terms of such design patterns matters at all, if you aren't working as part of a team, since on your own, you have access to, and the ability to change, any internal structural details, as you would like to do so. Design patterns are largely emergent. Build stuff, now. Then, try to pigeonhole it.
Know about design patterns for interviews. This is too far ahead for me anyway, I'm simply looking to create a class system that will achieve my goal adhering to as much simplicity as possible. Can refactor and rework later. But thanks, can ignore design patterns for now. Excellent, designing system classes is proving difficult enough.

Practically every bit of OO 'theory' that came after Smalltalk-80 (Simula 67->Smalltalk->*) is rooted not so much in logical needs of the program, but in business needs of developing and maintaining software in a timely and budget-friendly manner. Keep that in mind, as well.
This is wonderful advice. I was beginning to think Software dev is now an art. Never mind the cost or time, make it beautiful. Actually, cost and maximizing profit are the roots of OOP.
A board or card game would be much a better real world "thing" to make OOP for learning, as they already tend to have neat hierarchical categories, each thing in one is intimately tied to actions that may be taken within some set of rules, and all of it is already really a finite set of abstractions.

Make a simple chess game in an imperative OOP language, then in a LISP-a-like. While you may have some, "aha," functional moments, and your final application of rules in the imperative version will reflect that, you will prefer working with the imperative OOP version, <Justin>I gayhruntee</Justin>. I would lean towards board games with different pieces on the same board, so that some degree of polymorphism-as-typing is intuitively useful (even checkers qualifies, with king rules, though chess or Stratego would probably be more engaging for that purpose; Monopoly, as well, but that's a much more complicated game).
I like the idea of a cheese game and accept it would give me a better understanding of OOP principles, however, I've spent quite a while at his hotel system, so I'll keep this suggestion for when I give up on reservations. Thanks for all the advice, really thought provoking and beneficial to me.
Much appreciated.
 

Cerb

Elite Member
Aug 26, 2000
17,484
33
86
Know about design patterns for interviews.
10,000ft viewpoint ones, maybe. But, there are useful design patterns that aren't like that, such as the observer pattern, which you are likely to implement poorly and incompletely, when not considering it (shades of Greenspun's tenth rule?); but that you can implement pervasively, in ways that improve your code and design process, if you recognize early on that you're halfway to using it. Because, at that point, you can go check out mountains of both academic and commercial research, and real-world use cases, where people have already made, and corrected, mistakes in using it, and also found ways you didn't think of to extend it.

Memorizing lists of them will do no good, and don't worry about the hair-splitting details between some, but try to familiarize yourself with them, in general, so that you won't get trapped trying to hack your way around fixable problems you didn't even quite realize you were creating. The apparently simple 'right way' to do some patterns has often been arrived at by people smarter, more creative, and more experienced than you or I, spending thousands of hours trying to figure it out in the context of actual programs, only much later for someone else to look at the result, make a diagram of it, give it a name, and make it look easy :).

When somebody checksIn, it is no longer a reservation, it becomes a CheckIn. On the day of checkOut, CheckIn becomes a checkOut. Then, it would become a completed and paid reservation.Reservation->CheckIn->CheckOut->CompletedHotelBooking. Is that inheritance?
Yes, though it's generally not used that way (a Reservation would just have a field added for its current stage, since making new derived objects gets expensive, cumbersome, and harder to document as it becomes more pervasive). Inheritance is the taking of the properties of one class to derive another (common OOP languages don't do multiple inheritance, some do as a series of single inheritances, while some allow arbitrary multiple inheritance, allowing true union types). You generally don't want to do that just to represent a change of state, because, really, an object exists primary to store a certain kind of state (as defined by its class). Each one should have all the info of all its predecessors, so it would be just as well to have all the fields in one class, with the ability to get the current stage in the process, and have unset fields as null or other special values. Separating them could be done just as well by placing them in different collections, where appropriate. You're doing the technique right, but that would beg for spaghetti code and unnecessary complexity over time in a real application, compared to making the base reservation class a bit more robust.

A more canonical example: let's say, for instance, you make a Person class, which stores and ID and name (since name might not be unique). It has setters and getters. Everyone in the world, and some business entities, are Persons.

Now then, you want special properties for hotel staff, so you make Staffmember from Person, adding a job title and hours. Staffmember inherits Person. It is now a subtype of Person. Anything that can use a Person can also use a Staffmember.

Well, you then want a customer to be distinct from any hotel staff, so you make a Customer from Person, too. Dunno what else you'd add, but still, it's a Person for parts that need a Person, where anything dealing with extra info for a Customer would only allow Customer subtypes*.

The usefulness of this, when applied well, is that any container that has a Person can also have a Customer or Staffmember. Consider:
Code:
Person as {
  ID as unqiue_ID
  name as string
}
Reservation as {
  day_for as date
  day_reserved_on as date
  room_reserved as room
  reserved_for as Person
  reserved_by as Person
}
Now setting the room as reserved by a staff member for a staff member, where staff members are actually objects of their own class, will work just fine, since a staff member is a subcategory of a person, in the system, and thus should have any and all properties of a Person, as well as additional properties related to being workers for the hotel.

As well, other classes and functions that just want a Person will have no access to additional customer or business-related information, even though you are storing it in the same actual structure in memory.

As a note, not all OOP languages allow subtyping via inheritance, though languages that don't are not often used, because that's one of the more handy features of OOP.

1)Would I store these entities in the same csv file with an additional Boolean element. So reservation would be TFFF->FTFF->FFTF->FFFT.
Sorry guys, must be driving you crazy with this.
You can, but...if you're going to do that, why not have a byte or enum in Reservation, then store it out as a number, as well? Say, 0 means something is wrong (exception, just in case), 1 is a made reservation, 2 is a checked in, 3 is checked out, 4 is done. Or, you could even make the CSV descriptive, parsing words back in and matching them to the numbers, which would allow the internal implementation to be more decoupled (no point in wasting the space of storing and working on strings in the system, for such basic work).

Customer object has customer data, make it responsible for CRUD customers.
Alternatively, make it just store and access a customer's data, with a separate class for actually handling the CRUD portion for the whole set of data. Either way works. The latter adds to modularity, but since that kind of modularity tends not to be re-used, since it's likely coupled to Customer-specific info, it's more a matter of preference in style and thought process (note: re-use is one of those things that is simply not paradigm-dependent, either; OOP, functional, straight imperative, even procedural...as long as you can name entry and exit points, you can re-use code, if it is made to handle a general enough case).

2) Are these correct assumptions?
Maybe? I'd say they're a little too vague to be certain, still. Definitely on the right track, though.

3) Define the responsibilities of the system and then work out the best way to achieve this. e.g Maintain room bookings. the Calendar class. Each time a reservation is made, the reservation class will notify the calendar class of certain date and tell it room type e.g if Single Rooms>0 then SingleRooms-1.
Yes. Also, while they are always bad ways to do it, stick to one viewpoint for a certain aspect of the program. Data organization, data flow, observer/messaging, and other patterns are often equally viable (it's handy to know some, to recognize when you're half-assed doing one, and doing it right is well-documented, or doing on that's wrong for your task), but at some point, what really matters is deciding one aspect of the design, like decision-making (responsibility-driven), interface, data storage/persistence, etc. is extremely important, and making that aspect's needs a conceptual framework, where the rest of the program must make sense in its context (making code that someone else can easily internalize the workings of should often be equally, if not more, important, than caring about the computer executing it). That the same narrow design idea hardly ever works well for both front ends and back ends of real applications, leading to needing some reconciliation between each other, is part of how many design patterns (like the pervasive MVC) come to emerge.

Make reservation, Get reservation and CancelReserve, these are similar operations, so could you put these in an interface class?
P.S. I happened to think about this after getting some coffee. Forget, for a moment, that languages support explicit interface types of classes. That's an implementation detail that is language-specific, and usually an ad-hoc way of adding features they either didn't think were needed at first, or weren't sure how to add without breaking rules they wanted to keep coherent.

One of the more realistic benefits of OOP (though the same can usually be done in functional languages, w/o objects, as well, and some imperative non-OO languages, but almost all OO languages are made with this in mind), over other paradigms, for practical long-lived applications is that you don't need to care. That's what encapsulating values and sub-objects behind setters and getters really gets you. The ability to care about the higher-level aspects, without being overly concerned about the lower-level aspects in the process, until you need to optimize certain code.

Why does that matter? Let's say that you have a collection of objects being accessed by these functions, and each object is a complete reservation object. Now, your program is live, making some money, and you're needing more performance in doing simple operations on reservations, after reaching millions of them in the system, or you need to search through those millions quicker, and are finding that faster computers aren't able to do it well enough. They've hit a capacity wall. So, you profile it with random data similar to the customer(s)'s in question, and find that those reservation objects are eating up a ton of time, but the CPU is mostly stalled. So you investigate more, and find that your collection, and the objects, have too much overhead and indirection, causing bad results from prefetchers, and a cache footprint far larger than the data size.

So, you need to make each reservation smaller in memory, make searching through many of them easier, and make each lookup a better fit to HW speculation (binary searches over a flat-ish binary tree, skip-lists, reduce call depths of complex container objects, etc.). Now, there are quite a few ways to do this, the best varying by other variables, including time available, library options, latency requirements, and so on. The best way could be to hide it all behind views in a local database. It could be to make it a simple tree of radix-order-ordered (list of 1xx, then 2xx, then 4xx, etc.) lists/arrays, for quick access and searching. It could be best/easiest to have simple in-memory structures, an optimized file format, and SSDs to store it.

The nice thing about a class with those setters and getters, and other methods to hide access to the actual data, is that you can make a new version of your program, with the optimized reservation storage and search system, and only need to make a handful of changes outside of that system itself, because >90% of the code only cares that the methods of the object(s), sent the right arguments, will return the expected results. Without that kind of encapsulation, you have to either be extremely rigid in defining abstractions (I mean, the same thing can be done in C, but C does not exactly encourage it, or make it easy to read and write), or be paranoid as all hell when about minor structure-related side-effects, when having to update the rest of the application that relies on reservation's old behaviors not changing. The class defines an interface, so you can add a layer behind that, if needed or desired, that is much more than the basic set, get, add, remove, filter, etc., that appears to waste more space than anything else.

http://en.wikipedia.org/wiki/Program_optimization#Quotes

I'm a big fan of eager evaluating functional languages for general use, but if there's one huge benefit that imperative OOP has, over other viable business-world options, it's being able to dig in and optimize when necessary, but leave it well enough along when that's not needed, even when you're dealing with weird code that's been written by 50 people over the least 10-20 years.

Perhaps somebody at my level shouldn't read that.
You might not understand it all, yet, but basically, don't drink the Kool-aid. Procedural sucks (for any kind of higher-level thought, it really does; but somehow stable systems keep getting made in them), imperative sucks (too many chances to shoot yourself in the foot; but you know, computers kind of exist to manipulate state, and algorithms are never written as state-free function definitions), functional sucks (computers do state, not expression evaluation; but compare bugs per programmer-hour), OO sucks (how much space in this thread has been showing its limitations...yet, something that wide user base can make decent use of matters more than perfection within a narrow domain, and OOP is sufficiently versatile), and so on.

Our tools shape our thoughts as more than we'd like, so learning more is always a good thing**. But, there has yet to be a programming paradigm or specific language that can do everything really well (even the outstanding languages make huge trade-offs between code for humans to use, and performance on a computer), and at least half of the supposed benefits of any given paradigm are leaps of faith (strictly procedural to any decent structured programming probably being the one paradigm difference that lacks the need for faith). At the end of day, each good language is like a different brand and model of multitool.


* Also, to see why relational is the bees knees for this, consider what you'd do when you need a staff member to b a customer in another hotel...relational has ways to deal with it that can be implemented almost identically across non-relational DBMSes (Person table, Customer table with Person.ID as FK/PK, Staff table with Person.ID as FK/PK, handle compatibility issues in views), where the logically necessary decision is language-dependent for OO. The dirty secret of DBMSes, too, is that you can hide both occasional relational model obtuseness, and SQL implementation inadequacies, in triggers and sprocs, so it looks all clean and simple from the outside :).

** on that note, after you get a better handle on OOP, if you haven't already, go learn a LISP.
 
Last edited:

wallst

Junior Member
Jul 24, 2012
6
0
0
by Cerb
Our tools shape our thoughts more than we'd like, so learning more is always a good thing**
An insight applicable to all discussions not just within the Software world.

We should get Noam Chomsky on this thread.:biggrin:


by Cerb
Functional sucks, Imperative sucks, OOP sucks.
"I know my own nation best. That's why I despise it the most. And I know and love my own people too, the swine. I'm a patriot. A dangerous man"

We've not quite achieved perfection just yet.

But seriously, Cerb, I cant thank you enough for the insights, you have really opened up the software realm to me, the infinite ways to achieve anything. My previous narrow view has been expanded, a lot. I'm not frightened by it, but intrigued. I have a lot to consider, but more importantly an interesting road to travel. I thought, Get a tool, Java, get OOP principles and thats it. Boredom. But now, boredom isn't something that can be achieved easily e.g Financial Engineering. Buy Low, sell high. Boring and pointless!! Thanks for your time also.
 

slashbinslashbash

Golden Member
Feb 29, 2004
1,945
8
81
Cerb, thanks for your contributions to this thread! I had kind of stalled in building a website (which is functional enough, but needs more functionality added) because I was trying to OOP-ize it. I have now realized that I really should just keep on doin' what I've been doin' and just get it finished.
 

MooseNSquirrel

Platinum Member
Feb 26, 2009
2,587
318
126
I'd have to second that, and add that this kind of problem was what the relational database model was come up for (well, actually, it was mostly for employee info and reports, but that's surprisingly similar :)). OOP is great at abstracting and categorizing, in code and computer memory, the already abstract and well-categorized, like treating different types of IO as similar, handling the ugly details inside the classes, and creating more intricate data structures, without a programmer using them needing to know or care how they are implemented.

Here's a nice [heavily biased] read to get you thinking:
http://reocities.com/tablizer/myths.htm

It's not that OOP is really bad, though it is over-sold and over-used, but that the common folkways and folklore trying to make it out like it can be thought of as down to earth does little good (Dijkstra thought it did quite bad things, actually, and I come to agree with those ideas more and more, over time).

A board or card game would be much a better real world "thing" to make OOP for learning, as they already tend to have neat hierarchical categories, each thing in one is intimately tied to actions that may be taken within some set of rules, and all of it is already really a finite set of abstractions.

Make a simple chess game in an imperative OOP language, then in a LISP-a-like. While you may have some, "aha," functional moments, and your final application of rules in the imperative version will reflect that, you will prefer working with the imperative OOP version, <Justin>I gayhruntee</Justin>. I would lean towards board games with different pieces on the same board, so that some degree of polymorphism-as-typing is intuitively useful (even checkers qualifies, with king rules, though chess or Stratego would probably be more engaging for that purpose; Monopoly, as well, but that's a much more complicated game).

Seriously, don't worry about design patterns like MVC, for now, either. MVC, easily the most common, is practically a natural outcome of trying to use OOP principles for everything (especially polymorphism/inheritance for data fields and structures), then realizing how the added complexity breaks and bloats everything (more-so than running a DBMS along-side your application :), which is the common way to handle parts of the M and V portions), finally directing you towards divorcing your data, interfaces, and controlling logic as much as you reasonably can, because you will end up with ungodly mess if you don't.

Also, exactly where the 'view' in MVC begins and ends is something that can typically only be truly decided by having a manager state it, then smiling, nodding, and naming named things in your code to reflect that dividing line. Just so you know, because that will inevitably be a question that is hard to find good answers for. Not that there's anything [fundamentally] wrong with MVC, just that implementation is rarely as neat and tidy as requirements and presentations make it look. Not only that, but I'm not sure that thinking in terms of such design patterns matters at all, if you aren't working as part of a team, since on your own, you have access to, and the ability to change, any internal structural details, as you would like to do so. Design patterns are largely emergent. Build stuff, now. Then, try to pigeonhole it.

Practically every bit of OO 'theory' that came after Smalltalk-80 (Simula 67->Smalltalk->*) is rooted not so much in logical needs of the program, but in business needs of developing and maintaining software in a timely and budget-friendly manner. Keep that in mind, as well.

Well said. (props for the smalltalk reference!)

I programmed for 8 years in C, did some UniBASIC, moved onto C++ for another 8 years, learned Tcl/TK, Python, dabbled in Java...you get the picture.

The important thing to take from this is you may end up doing 80-90 % of your work in your programming language of choice (actually, your employer's programming languages of choice), but that last 10-20% will probably not lend itself to the problem at hand very well. You may be able to solve it in C++, but it will be challenging and painful, take a week to get right, and may take 30 minutes in Python.

Find a problem/task you would like to tackle and try it in 2 languages that support 2 different programming paradigms.

Some last advice:

Dont believe silver bullet magical thinking.

Agile will not inherently make managing the software creation process any better/easier.

OOP will not inherently make managing a massive code base any easier.

Design patterns do not inherently make breaking down a problem any easier.

Current popular language "L" will not inherently make problem "P" any easier to solve, but it will certainly help Oreilly sell more books :)