|  | best practice design of this simple example - your thoughts? |  | |
| | | stefoid |  |
| Posted: Wed Jul 30, 2008 2:04 am Post subject: best practice design of this simple example - your thoughts? |  |
| |  | |
Hi, I am not an OO expert, and I have been thinking about some basic aspects, trying to formulate my own simple set of principles.
For instance, the lack of agreement about MVC and the various 'rules' for good OO design that are often contradictory confuses me.
Here is a simple, yet very frequent problem presented below. What are the CRCs for this problem to come up with 'the best' solution?
Problem:
1) We have a 'business object'. doesnt matter what it does. Some aspect of this object needs to be displayed in a GUI and the user can interract with the GUI to cause some change in the object.
2) Some aspects of the object must be persisted to a database.
Thats it. A common as muck scenario I would think, and yet if I could work out the best way to approach an example design, Im sure it would clear up a lot of conflicting issues in my head.
If you would like to propose the CRCs for this design, or point me to a link that you think already catpures your thoughts, that would be great. |
| |
| | | Phlip |  |
| Posted: Wed Jul 30, 2008 2:04 am Post subject: Re: best practice design of this simple example - your thoug |  |
| |  | |
stefoid wrote:
| Quote: | For instance, the lack of agreement about MVC and the various 'rules' for good OO design that are often contradictory confuses me.
|
Good OO designs are DRY - they obey "Don't Repeat Yourself".
Far from a "lack of agreement", this ideal is extremely widespread. The ideal leads - almost like proofs lead to theorems - to concepts like "Single Responsibility Principle" or "Liskov Subsitution Principle". You can generate any pattern in the book /Design Patterns/ by DRYing its motivation up.
Further, OO designs should freely submit to unit testing without rampant coupling. Coupling means "to change A you must also change B". I read that in a book this weekend, /Head First Software Development/ by Foamy the Squirrel. Unit tests should be easy to set up, so they force code to avoid runaway dependencies.
MVC is generally what you get by applying those forces to a "full stack" problem, with a front-end, middleware, and a back-end. The disagreement naturally arises when different applications require different implementations of MVC. This is a Good Thing - it's the process in action.
| Quote: | 1) We have a 'business object'. doesnt matter what it does. Some aspect of this object needs to be displayed in a GUI and the user can interract with the GUI to cause some change in the object.
2) Some aspects of the object must be persisted to a database.
Thats it.
|
Then look up ActiveRecord!
-- Phlip |
| |
| | | Patrick May |  |
| Posted: Wed Jul 30, 2008 2:04 am Post subject: Re: best practice design of this simple example - your thoug |  |
| |  | |
stefoid <stevenmathers@yahoo.com> writes:
| Quote: | Problem:
1) We have a 'business object'. doesnt matter what it does. Some aspect of this object needs to be displayed in a GUI and the user can interract with the GUI to cause some change in the object.
2) Some aspects of the object must be persisted to a database.
Thats it. A common as muck scenario I would think, and yet if I could work out the best way to approach an example design, Im sure it would clear up a lot of conflicting issues in my head.
|
If you just need CRUD (create, read, update, delete) behavior on data, a.k.a. the Put The Damn Data On The Screen pattern, use a CRUD tool.
If you have more complex behaviors in your business objects, there are OO techniques to help with dependency management.
Regards,
Patrick
------------------------------------------------------------------------ S P Engineering, Inc. | Large scale, mission-critical, distributed OO | systems design and implementation. pjm@spe.com | (C++, Java, Common Lisp, Jini, middleware, SOA) |
| |
| | | Stefan Ram |  |
| Posted: Wed Jul 30, 2008 2:04 am Post subject: Re: best practice design of this simple example - your thoug |  |
stefoid <stevenmathers@yahoo.com> writes:
| Quote: | Thats it. A common as muck scenario I would think, and yet if I could work out the best way to approach an example design, Im sure it would clear up a lot of conflicting issues in my head.
|
Depending on what one wants to minimize (like run-time or developement time), there will be several possible approaches.
You might have described requirements for a piece of CRUD
LINK
software. There are already many frameworks for this.
While the classical MVC is not always used, often there will be a model-view separation involving the observer pattern. |
| |
| | | stefoid |  |
| Posted: Wed Jul 30, 2008 7:43 am Post subject: Re: best practice design of this simple example - your thoug |  |
| |  | |
Some of you guys are being too practical. Im talking from a theoretical design viewpoint.
Let me have a crack at an example Class Responsbility Collaborators deal
---------------------------------
Class: BusiObj
Responsibilities: changeSomethingAboutBusinessModel drawMyself persistMyself alertListenersToModelChange
Collaborators: DisplayObj DataBaseObj
Class: DisplayObj
Responsibilities: Abstraction of display drawing functionality
Collaborators: any object that wants to draw itself
Class: ViewObj
Responsibilites: UpdateViewOfBusiObj AcceptUserInput ListenForModelChanges
Collaborators: BusiObj
Class: DataBaseObj
Responsibilities: saves data to database
So in this design, ViewObj Listens for 1) ViewObj calls BusiObj->draw() to tell it to draw itself in a particular place on the screen. 2) BusiObj uses Display to draw itself with drawing functions (delgates actual drawing to Display) 3) ViewObj accept users input and calls BusiObj-
| Quote: | changSomethingAboutBusinessModel 4) BusiObj possibly makes the change and Base->persist(modelData) |
5) BusiObj alerts listeners to model change 6) ViewObj calls BusiObj->draw() to tell it to draw itself in a particular place on the screen. and so on... |
| |
| | | Patrick May |  |
| Posted: Wed Jul 30, 2008 9:05 am Post subject: Re: best practice design of this simple example - your thoug |  |
| |  | |
stefoid <stevenmathers@yahoo.com> writes:
| Quote: | Class: BusiObj
Responsibilities: changeSomethingAboutBusinessModel drawMyself persistMyself alertListenersToModelChange
|
This violates the Single Responsibility Principle. An object that isn't part of the GUI library shouldn't know about drawing itself. An object that isn't part of the persistence layer shouldn't know about persisting itself. It also has the potential to violate the Open-Closed Principle when new interfaces must be supported. You don't want to have drawMyselfAsHTML, drawMyselfAsSwing, etc. Finally, alertListenersToModelChange should probably be generic behavior, not part of the base class.
I'm heading out to work, but my quick recommendation is to read _Design Patterns_ to identify some techniques to separate your business, presentation, and persistence logic.
Regards,
Patrick
------------------------------------------------------------------------ S P Engineering, Inc. | Large scale, mission-critical, distributed OO | systems design and implementation. pjm@spe.com | (C++, Java, Common Lisp, Jini, middleware, SOA) |
| |
| | | Phlip |  |
| Posted: Wed Jul 30, 2008 9:24 am Post subject: Re: best practice design of this simple example - your thoug |  |
stefoid wrote:
| Quote: | Some of you guys are being too practical.
|
Sorry. I will try not to let it happen again.
(-: |
| |
| | | Stefan Ram |  |
| Posted: Wed Jul 30, 2008 1:17 pm Post subject: DRY (was: best practice design of this simple example - your |  |
| |  | |
Phlip <phlip2005@gmail.com> writes:
| Quote: | Good OO designs are DRY - they obey "Don't Repeat Yourself".
|
A question regarding this:
A customer has build a device (hardware) and needs an interface library in /two/ different programming languages (for example, in Java and C++). This library will expose low-level functions of the device via higher-level operations of some objects (classes) as an interface for application programs.
The programmer uses a preprocessor to generate the source code in both languages. So, when he learns, for example, that he understood something wrong about the device or when the interface of the device was modified, he only needs to change something once in his pre-code. The preprocessor then will generate the code in the two languages from this new version.
He has not repeated himself.
But now the customer starts to complain that other programmers will have to invest too much time when they want to maintain the code base, because they need a lot of additional time to learn his preprocessor system and pre-language before they can start to read and change the pre-code.
So, what is the best way to apply »DRY« in this case? |
| |
| | | H. S. Lahman |  |
| Posted: Wed Jul 30, 2008 1:40 pm Post subject: Re: best practice design of this simple example - your thoug |  |
| |  | |
Responding to Stefoid...
| Quote: | Hi, I am not an OO expert, and I have been thinking about some basic aspects, trying to formulate my own simple set of principles.
|
The first thing to do is learn about basic OOA/D. B-) [The "Books" category of my blog has some suggestions on how to find a good book in the subject.]
| Quote: | For instance, the lack of agreement about MVC and the various 'rules' for good OO design that are often contradictory confuses me.
Here is a simple, yet very frequent problem presented below. What are the CRCs for this problem to come up with 'the best' solution?
Problem:
1) We have a 'business object'. doesnt matter what it does. Some aspect of this object needs to be displayed in a GUI and the user can interract with the GUI to cause some change in the object.
|
I agree with Ram; it depends on what kind of software you are building.
MVC is one of several generic models for CRUD/USER processing that works quite well in RAD environments. Such models are based on the notion that the application is basically a pipeline between the database and the UI whose main job is data entry for the database or presenting database data in a form that will be useful to the user for subsequent analysis. IOW, the primary problem being solved is conversion of data representations with only very basic modifications of the data.
Typically the canned infrastructures that support such models are object-based rather than object-oriented, so they often don't represent good OOA/D practice. That's because they are highly tailored to the sort of transaction processing and client/server environments where CRUD/USER processing lives. So the infrastructures are designed around ease of generalizing that environment. That's fine and classic OO development is usually overkill for such processing, but it might account for some of the conflicts you identified.
However, when applications become more complex with complicated processing of the data, then the layered pipeline models tend to break down and one needs to approach OOA/D from scratch. The application structure tends to become hierarchical with multiple peer subsystems at each level. For example, both the database access and UI become low level peer service subsystems whose mission is to communicate with persistence and the user, respectively. They provide a very generic interface so that the specific persistence or display paradigms actually used are hidden from the rest of the application. [The "Application Partitioning" category on my blog has more information on how this is done.]
Thus the fundamental architecture of the application and the emphasis placed on things like persistence and UI paradigms is very different depending on what sort of software one is constructing. Consequently, the way design principles are applied is quite different. So there is no one-size-fits-all answer to your question.
| Quote: | 2) Some aspects of the object must be persisted to a database.
Thats it. A common as muck scenario I would think, and yet if I could work out the best way to approach an example design, Im sure it would clear up a lot of conflicting issues in my head.
|
As a simple example of the disparity in view points, let's look at how some layered model infrastructures work. (I don't use MVC, so I don't know enough about its infrastructure to use it as an example.) Sometimes they will use composition via inheritance to map objects across layer boundaries. In that case a business object might inherit from Persistable (a superclass provided by the infrastructure). Then when the object needs to be saved to the DB one might invoke a persist() method provided by the Persistable implementation. That method would handle the details of dumping the object attributes to, say, an RDB table in the database.
This is very convenient and saves the developer a lot of keystrokes when there is a 1:1 mapping between RDB tables and objects, which is usually the case in CRUD/USER processing. However, it is a terrible design from an OOA/D viewpoint because persistence has nothing at all to do with the business semantics of the object. IOW, cohesion has been completely trashed by mixing problem space abstraction (business entities) with complex computing space mechanisms (RDB storage). [As an exercise, try walking into your local car dealer and asking to see a Persistable Honda Accord. B-)]
In fact, in non-CRUD/USER applications a 1:1 mapping between business objects and RDB table rows is the exception rather than the rule. So one wants to send a message to somebody else to persist the data. That somebody else would gather the data from whatever objects have it and would construct the appropriate update query. IOW, the concerns of persistence have been completely decoupled from the business logic and encapsulated in an object or subsystem whose sole mission in life is to convert the problem solution view to the RDB view.
Now this is a somewhat extreme example of an approach that is not used much anymore and MVC doesn't work this way. Nonetheless the View and Model are intimately related and the general idea still applies.
-- There is nothing wrong with me that could not be cured by a capful of Drano.
H. S. Lahman hsl@pathfindermda.com Pathfinder Solutions LINK blog: LINK "Model-Based Translation: The Next Step in Agile Development". Email info@pathfindermda.com for your copy. Pathfinder is hiring: LINK (888)OOA-PATH |
| |
| | | Phlip |  |
| Posted: Thu Jul 31, 2008 2:50 am Post subject: Re: DRY |  |
Stefan Ram wrote:
| Quote: | But now the customer starts to complain that other programmers will have to invest too much time when they want to maintain the code base, because they need a lot of additional time to learn his preprocessor system and pre-language before they can start to read and change the pre-code.
|
This is a DSL like any other. Much of modern programming revolves around DSLs; new programmers are expected to pick them up. Even the "builder pattern" in Java is a domain-specific language.
| Quote: | So, what is the best way to apply »DRY« in this case?
|
The unit tests are generally just as DRY, right?
-- Phlip |
| |
| Page 1 of 2 .:. Goto page 1, 2 Next | |
|
|