However, these are minor concerns in relation to its most glaring difference: Smalltalk greatly encourages programmers to write object oriented code while C++, Java, and VB do not. Most of the C++, Java, EJB, and COM objects I see just aren't. Smalltalk, on the other hand, makes writing procedural code difficult and messy (partly because of its library and partly because of its syntax). Writing good OO code takes discipline and a change of mindset that a lot of people just don't take.
OK, so what the heck is good Oo code as opposed to C++/VB OO code?
Whatever I say it is!
It appears when someone is talking OO, it is SmalltalkOo?
. Each handles Objects in its own way and can execute programs using the objects created and referenced. The good of ObjectOrientation
is in the Execution: If it works as intended it is GoodOoCode?
(as far as the end user is concerned). Stop arguing about it and write it if you want to use Objects, and don't write it if you don't want to use objects.
I believe the trivial answer to the question WhatIsGoodOoCode
implemented using OO concepts such as polymorphism and encapsulation.
In this case why does it matter if it's OO or not? "good OO code" is then a trivial and unseful syntagm, good code is enough. Focusing on writing "good OO code" can become a distraction.
I absolutely agree with your statement. OO is simple a means to an end. And it's nothing more than a stylistic mechanism, at that. GoodCode is really the only thing that matters.
Good OO code is the code which I say is OO and good. -- WillSargent
Even "concepts such as polymorphism and encapsulation" might be too high-flown for practical use. I like the XpSimplicityRules
Yes, good code is simple and straightforward.
Good O-O code is code which exploits the O-O features of the language to make the code design simple and straightforward.
For example good O-O code might exploit polymorphism to avoid using ugly big long case statements.
In order to write good O-O code you have to be familiar with the O-O features of the language, e.g. polymorphism and encapsulation (to use the fancy names). Also, you need to be familiar with how to use them to make your code simple and straightforward. For example, Kent Beck's Smalltalk Best Practice Patterns does this for Smalltalk.
O-O features are actually very good for making code simple and straightforward. That's the whole point of O-O. So, if you're coding in Java, or Smalltalk, or C++ and not exploiting the O-O features of the language to make it as simple and straightforward as you can, then you're writing bad code.
Good OO code has all the good properties of good procedural code.
Object oriented techniques enable and encourage one to build useful abstractions.
By "encapsulating" implementation details, such as data representation, behind a well defined procedural "interface" of logical methods one can perform, developers find it easier to implement useful abstractions.
Well Defined Abstractions are good for...
- Code Reuse: Another system that has a business use for the same abstraction can reuse it.
- Reliability and Robustness of code: Dependencies between code in different parts of the system are reduced, along with the probability of unintended side-effects of code changes. Also, a well-defined abstraction can be tested independently from the rest of the system, so testing is easier and more effective.
- Substitution: One can change the internal implementation -- data, algorithm, or even both -- without changing code that uses it. (Changing client code, distributed across the system, is often a good way to introduce bugs into a system.)
Parsing XML documents is complex.
And the XML standard has changed and been extended a number of times in recent months, requiring dramatic changes to parsing and validating code.
This is why it has been valuable to me that XML parsers present themselves to me in an object oriented manner:
While the implementations and internal storage of XML data have changed dramatically, most programs can continue to use the stable parts of interfaces -- those that have not changed at all, and be unconcerned about the internal details.
I've upgraded XML parsers several times, without having to rewrite or even change my client code at all.
This leads me to conclude that...
- "Good OO Code" provides sensible implementations of abstractions that are useful in the business domain.
I've found that programmers who have a hard time thinking abstractly will produce bad code.
And in an OO environment, they'll produce very bad
(Having a more powerful tool enables them to produce more damage. ;-)
In detail, "Good OO code"...
- Encapsulates implementation details behind meaningful methods: Like "ship product" and "is this point within the given shape (say, a polygon)". Not like "get or set property X."
- Methods and member variables are "normalized." IE: Every method and member variable is closely tied to each instance where they appear/are used (cohesion), and loosely coupled to outside classes/methods/procedures.
I've found that "Good OO Design" helps me build better systems faster with fewer bugs.
Your mileage may vary -- especially if your people are lazy or do stupid things. ;->
Is it okay if I challenge your example? What is wrong with parsing XML into a relational database or at least a table structure? (I agree that some RDBMS don't handle variable-length strings very well, but that is an implementation detail.) Then, we don't need to invent an interface from scratch to access it; we just use a known relational language (such as SQL, which is not perfect, but good enough). That is good "reuse" because we can use an existing protocol and conventions. And, because we can use a query language, we are less likely to have to anticipate every usage pattern in advance, as would be the case if designing an OOP interface. --top
Designing a relational structure to store XML sounds a lot like "invent[ing] an interface from scratch to access it". Saying that using a "known relational language" to access the database gives "good 'reuse' because we can use an existing protocol and conventions" is no different than saying a Java class gives good reuse because Java programmers know how to use Java classes.
No. Databases provides a full set of CollectionOrientedVerbs
out-of-the-box. Java does not. And, each designer will do it all differently. Relational rules reign in the "creativity" such that there are less chances of wild Picasso-ing. And if one decides to put a custom interface on top of the database, one can still reject that and use the database directly if they don't like the custom interface.
Which is clearly saying nothing at all. "Designing an OOP interface" does not require anticipating "every usage pattern in advance" -- but then I wouldn't expect you to have any substantive knowledge about object-oriented design.
That is rude. I did not insult you.
I have used OO systems/APIs that did not provide all the access techniques I needed, and so had to tediously write my own using the existing primatives. Are those designers also allegedly ignorant to OO like me? OO cannot compete with a query language for unanticipated or ad-hoc access or views. Writing stuff like join's by hand is a royal pain in the keester, for example. I would be glad to challenge you to an ad-hoc request contest. Just draft up your pet XML interface.
Another objection to your suggestion is that if the data belongs in XML in the first place (i.e., if it has a genuine hierarchical structure that is appropriate for being modelled by XML), it probably doesn't make a lot of sense to put it in a relational database anyway -- but I'm afraid that argument has probably been beaten to death elsewhere.
Well, I agree that XML is often misused, but relational can handle hierarchies just fine, even if they are created for the wrong reason. I would note that different vendors put more tree-oriented operations than others. There are also ways to include information that simplifies digging around in trees, such as the level number. The trick is to treat trees as one of many possible views of the same information. Relational does that better.
A similar XML discussion can be found in DedicatedStructuresVersusRdbms
Good OO code is reusable. Everything else we talk about here--polymorphism, encapsulation, inheritance; simplicity, straightforwardness, refactoring; cohesion, coupling--is meant to support that. If you've read your image thoroughly and are intimately knowledgeable in your base classes, and yet you have to start hacking up the image or subclassing the framework to the n
th degree to get some functionality, it's bad OO code. --AllanBaruz
"reusable" is a fuzzy concept until you actually get to reuse it. A much better measure is that Good OO code is testable
The question that started this page was OK, so what the heck is good Oo code as opposed to C++/VB OO code?
You can test C++ and VB code. That doesn't make the code written using these languages "good" OO code. Testability is a measure of working OO code, not good OO code.
According to LateWittgenstein
), the concept of "game" is hard to define--"fuzzy" as you put it--but we know one when we see one. We point to five roleplayers sitting at a table or to two soccer teams kicking a ball and we say, "game." When we try to reuse OO code, we know
whether it is good or not. If it would have been just as easy to code it from scratch, it's not good OO code.
So if it's a measure you want, try "effort to achieve reuse."
Here's some bad OO (pseudo)code:
int type = someObject.getType();
case FOO: doTheFooThing(someObject);
case BAR: doTheBarThing(someObject);
case BAZ: doTheBazThing(someObject);
... ad infinitum ...
Possibly worse is next if/then/else clauses. But "good" would look something like:
where you have separate subclasses for Foo, Bar, Baz...
One could argue that the above is not "bad" OO code but non-OO code. It is procedural. (Whether case statements are inherently evil is covered under SwitchStatementsSmell
See Also: OopGoesHalfWay