Learning Java

L

Lew

Superb point/counterpoint exchange, comrades, with many points on both sides.

.... fast-forwarding ...
However, the argument here is about where a lot of the procedural logic
goes. The attempt to keep it all in domain classes failed a long time
ago. People have adjusted, often quite well. What's been missing is a
general acknowledgement that we write a *lot* of procedural Java code,
and maybe work on ways to formalize how to do that well. DCI is one
approach.

Pretty good job of teasing apart the two questions of, "Is that
object-oriented?" and, "Is that good code?".

Other discussions in this forum have called out the distinction between an
"object" in a sense useful to computer programming and an "object" as it's
usually taught to programmers. Classic pedagogical examples like "A Ford
/is-a/ Car that /has-an/ Engine" do some harm to understanding what an object
really is in a programming sense.

Part of the difficulty in the discussion here is to converge on a definition
of "object-oriented". Some, amongst whom I will presume to number Arved, hold
to a very rigid technical definition, fortunately devoid of value judgment,
with the notion of degree of compliance to that definition. It's attractive,
because his characterization allows an unambiguous statement like, "This
program is 73% object oriented."

Except that orientation is by design an imperfect and teleological notion. I'd
prefer a more, well, objective term such as "objectified", or
"object-compliant". You can orient yourself to objects but still digress to
what we've been pleased to call "procedural" code.

Regardless. The central message that emerges is that 100% object-compliant
code is not necessarily a good thing and rarely if ever seen in Java code
(that works). At less than 100%, a programmer still thinks in terms of objects
(orients themself to them), but occasionally needs some function to stand as
its own sort of object (what a first-class notion), or procedure, apart from
the purity of a fantastic "object model", and strays from the object path to
static methods and such.

And yet - and yet -

If it's good code, and I'm willing to bet sight unseen that both Arne and
Arved write very good code, there will be attributes of encapsulation,
inheritance, and polymorphism throughout, even to the static constructs. The
mental model for class-level behavior in Java might still conceive in
"object-oriented" terms that which Java itself cannot directly express.
(Functional programmers: time to jump in with your functional-flavor of the
month rant.)

Don't make "object-oriented" a religion. If it makes you more comfortable to
reason Arved's way, and call what you do "73% object-oriented", or to go
Arne's way and say, "Sure, it's object-oriented, static methods
notwithstanding", or to frame it some other way, go for it. Just be ready to
map your understanding to common terms when talking with others, and continue
to write good code.
 
M

markspace

What's been missing is a
general acknowledgement that we write a *lot* of procedural Java code,
and maybe work on ways to formalize how to do that well. DCI is one
approach.


Hmm, perhaps. However, I had to learn OOD on my own (I graduated before
it came fully into vogue), and I've always been keenly aware that the
need for procedural code in OOD seems to be general accepted.

To go back to one of the earliest sources, if you pick up a copy of
Bjarne Stroustrup's The C++ Language, there's a chapter (#23) that
explains his basic OOD philosophy. As a pedagogical example, he designs
a simple parser.

First, he makes some simple objects that correspond to the leaf nodes in
a parse tree. Then he designs the actual tree itself. Then he says
"Now I need to make it DO something." And he makes a class that he
calls a "driver" which is all procedural code and implements the actual
use cases of his simple parser, using the objects he previously created.

Iirc the Rational design process has a similar division. I personally
see procedural elements in design patterns like MVC, where the
controllers appear to me to be simply drivers like Stroustrup's driver
(although controllers do preform a more specialized kind of procedural
function). I think Arne post here a while back about a design pattern
that recognized procedural bits in an overall design pattern and called
them "services." Etc.

I think procedural method in OOD are recognized, but the may not be
specifically called out. It's assumed that you just recognize "Oh
s/he's writing some procedural code here." A lot of writing requires
the user to make a judgement how procedural needs to be, and design
appropriately. Reference objects tend to have longer procedural bits,
but that doesn't obviate the need for pure procedural code when
required. App start up and shutdown, for example, tend to be purely
procedural, and there's not reason to make them otherwise.
 
A

Arved Sandstrom

Hmm, perhaps. However, I had to learn OOD on my own (I graduated before
it came fully into vogue), and I've always been keenly aware that the
need for procedural code in OOD seems to be general accepted.

I don't get that same sense. I think programmers understand, when
looking at any method, that it's a chunk of _imperative_ code. You can't
avoid that in either procedural or OO code - imperative is what we've got.

Let's not lose sight of one major distinction between procedural and
object-oriented. In procedural we write procedures to operate on data,
and in OO we write data that can operate on itself.

I believe that anemic domain objects are legit OO if they truly have
little or no interesting behaviour. That is not exactly rare. You can't
blame a class for just having accessors if it's a really boring class.

What I do have a problem with are anemic domain objects that ought to
have behaviour, but that logic is parked somewhere else. That is now
procedural code and it's bad procedural code.

Example: why do so many people insist on leaving their JPA entity
classes anemic? Practically all available code examples foster this
impression, and the Java EE tutorial itself promotes this idea by
describing entities as "lightweight persistence domain object". Is there
actually a law that says that these particular domain classes can't be
given behaviour? Well, people sure think so, which is why you end up
with reams of code that operates on data structures (entity objects).
You often see people writing *Util classes that have methods to work on
JPA entities...just because they believe these are "special" objects.
Well, yeah, they are special, but not _that_ special.

To be fair, the Java EE tutorial also says that "Clients must access the
entity’s state through accessor or business methods." Thus indicating
that you can in fact have business methods in JPA entity classes. I just
don't see that a lot of programmers ever read that bit.

I don't agree with everything Adam Bien says, but in
http://www.javaworld.com/javaworld/jw-05-2009/jw-05-domain-driven-design.html
he notes that

"The vast majority of J2EE and Java EE applications are built in a
procedural way. The business logic is decomposed into tasks and
resources, which map, respectively, to services and anemic, persistent
entities. Such an approach works surprisingly well until type-specific
behavior for domain objects must be realized. Then the lack of object
orientation in the persistence layer can cause problems."

My argument is that many Java programmers end up precisely where Bien
describes, and like Bien says this often works quite well, but I sure
don't get the sense that they understand that this is procedural code.
They think it's OO - it's the terminology you hear.

Adam Bien notes that there is another possibility, a "lean" architecture
(http://www.javaworld.com/javaworld/jw-04-2009/jw-04-lean-soa-with-javaee6.html).
This focuses on SOA services. This has anemic domain objects but has the
virtue of having a reasoned argument behind it. I am not maybe 100%
behind it myself but at least there's a rationale.

Coplien and Bjornvig have obviously their book on "Lean Architecture",
where DCI figures strongly. This is a recognition that apps written in
an OO language contain a great deal of true procedural code, and DCI is
a system for imposing discipline on that, based on contextually
(use-case) making rich objects from anemic ones as needed, and letting
them interact with that runtime behaviour. DCI and what Bien presents
are different, but they both provide a rationale for recognizing and
formalizing procedural code in a nominally OO application.
To go back to one of the earliest sources, if you pick up a copy of
Bjarne Stroustrup's The C++ Language, there's a chapter (#23) that
explains his basic OOD philosophy. As a pedagogical example, he designs
a simple parser.

First, he makes some simple objects that correspond to the leaf nodes in
a parse tree. Then he designs the actual tree itself. Then he says
"Now I need to make it DO something." And he makes a class that he
calls a "driver" which is all procedural code and implements the actual
use cases of his simple parser, using the objects he previously created.

Iirc the Rational design process has a similar division. I personally
see procedural elements in design patterns like MVC, where the
controllers appear to me to be simply drivers like Stroustrup's driver
(although controllers do preform a more specialized kind of procedural
function). I think Arne post here a while back about a design pattern
that recognized procedural bits in an overall design pattern and called
them "services." Etc.

Sure enough. I don't recall Arne's post offhand, but Bien's lean
architecture is similar I suspect.

I don't have a problem with procedural. I know that much, sometimes
most, of application logic _is_ procedural. I'm all over procedural. :)
That's why I am so interested in DCI or anything else that offers a
decent thought process and techniques for being deliberate and
systematic with the procedural code.

And I am still a big fan of rich domain objects. I think - and DCI
advocates this - that if there is logic which is truly domain logic that
belongs to a class, that you jam it in that class. To return to JPA
entities, it's just wrong that if you've got hundreds of entity classes
that *none* of them have any business methods.
I think procedural method in OOD are recognized, but the may not be
specifically called out. It's assumed that you just recognize "Oh
s/he's writing some procedural code here." A lot of writing requires
the user to make a judgement how procedural needs to be, and design
appropriately. Reference objects tend to have longer procedural bits,
but that doesn't obviate the need for pure procedural code when
required. App start up and shutdown, for example, tend to be purely
procedural, and there's not reason to make them otherwise.

But here's the thing. If you start out the way Bien suggests a lot of
folks start out, by thinking procedural from the gitgo, you end up with
way more procedural than is right. And this is the kind of Java coding I
usually see.

AHS
 
A

Arne Vajhøj

You're pushing me too far over to one side when you characterize my
arguments. So far I've said little about static methods - I've been
noting the misuse of instance methods. I've focused deliberately on
instance methods because it is easier to disguise their misuse.

As far as static methods go, I don't think the use of *some* static
methods is bad either. They are inherently procedural, however. You
acknowledged that to some degree when you equated 'procedural = all
static'. I happen to think that the bar should be lower, that the more
of your code that you've jammed into static methods the more procedural
your code has become. There's no 0/100 black/white here.

I prefer static methods that are non-business-logic implementation
details, if you've got to use them at all. Like static factory methods.


It's OOP. It's _technically_ OOP. More discussion below.


Not always "good" OOP. Let's just call that "1990's OOP" or "1990's
accepted OOP".


That's exactly right: it became clear that the "emergent" premise behind
the rich domain model typically failed. People invariably had a
difficult time deciding where to put all their logic, because much of it
did not neatly belong to any one domain class. That led either to
abstract and dubious domain classes for the purpose of holding methods
that had no better home, or drove that change you referred to above (and
which I've criticized): creating lots of service classes in an
application layer, where this difficult-to-place logic gets put as
instance methods.

As a short-term response to the flaws inherent in the rich domain model
I have no serious problems with that change. A great deal of logic _is_
procedural, and you should code it up that way. But let's not call it
OO. My argument is just that, that a lot of Java code is procedural. I'm
not saying it's awful. When I previously used language like "ought to
have been", I'm saying that in reference to what you'd strive for with
classic, rich domain model OO.

This is my point exactly: that this change to lots of procedural, for
basically good reasons, has happened in Java (and other class-oriented
languages like C#). What is a problem is that people continue to insist
that this procedural code isn't.

My point is that it did not change to procedural - it changed
to a different type of OO.

OO is not a synonym for a rich domain model.

http://en.wikipedia.org/wiki/Object-oriented_programming#Fundamental_features_and_concepts

http://www.purl.org/stefan_ram/pub/doc_kay_oop_en

does not seem to conflict with what you call procedural.

Arne
 
A

Arved Sandstrom

My point is that it did not change to procedural - it changed
to a different type of OO.

OO is not a synonym for a rich domain model.

http://en.wikipedia.org/wiki/Object-oriented_programming#Fundamental_features_and_concepts

Believe me, I know. I experiment with Self a lot, have for a few years.
My first exposure to OOP - as in seriously thinking about it - was
actually Prograph about 20 years ago, followed by Smalltalk and C++ and
Perl 5 OOP shortly after. Add into that Javascript and Ruby and so
forth, and I think I have probably been more an object-oriented OO guy
rather than a class-oriented OO guy right from the gitgo. When you think
objects, even in a language like C# or Java that wants you to think of
class instances, you tend to not have a rich/anemic domain mindset in
the first place.

None of these languages really made me think about rich domain objects;
I didn't start reading about that until Java had been around for a
while...it seems like the OOP pundits wrote some of the more well-known
rich-domain model articles (like Fowler's article about anemic domain
models in 2003) after the evidence was starting to amass that rich
domain was actually problematic.

I won't say that I have written either predominantly rich or anemic
domain classes, I think over the past few decades it's been a mix as
required.

Fowler and his adherents, and the DDD people, would never have pushed
their ideas if there weren't a lot of folks who *never* bought into the
rich domain model in the first place. In other words, there have always
been a lot of OO programmers who write procedural.
http://www.purl.org/stefan_ram/pub/doc_kay_oop_en

does not seem to conflict with what you call procedural.

Arne

No, I don't think it does either. As you may have gathered from the
above, I'm very comfortable in a object-based OO environment as opposed
to a class-based OO environment, and I like the way Kay minimalizes what
is really essential.

I think of OO as being about objects - period - and to me an object is a
bundle of data that can do stuff to itself. That a great deal of teh
overall program code might be non-object, and simply call upon objects
when necessary, is not a concept I have an issue with.

AHS
 
G

Gene Wirchenko

On Sun, 06 May 2012 15:49:29 -0300, Arved Sandstrom

[snip]
I think of OO as being about objects - period - and to me an object is a
bundle of data that can do stuff to itself. That a great deal of teh
overall program code might be non-object, and simply call upon objects
when necessary, is not a concept I have an issue with.

You had to tell them that the emperor is wearing no clothes!

I agree with you. OOP is useful, but my toolbox is much bigger.

Forks are very useful for eating with, but I also use spoons and
knives. And chopsticks. And.

Sincerely,

Gene Wirchenko
 
S

Steve Graham

Steve said:
I've been a programmer for 3 decades working in mostly procedural
languages, although I have done some work with a couple of
object-oriented ones.

Which book would you recommend that I read to learn Java? Obviously, I
don't want to read a beginning programming book, nor do I want to study
one which presupposes I know something about Java or a lot about OO
concepts.

Thanks, Steve

Thank you all for your suggestions. Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,202
Latest member
MikoOslo

Latest Threads

Top