I was just emailing back and forth with Duncan about this issue. I'll
repeat here what I said there.
> However,
> what we do try to show is that not everyone in your organization has to
> know all the details about all of these technologies.
I agree wholeheartedly with *this*. But I don't think it always gets made
clear. Duncan was telling me about the Fusion Apps model: The vast
majority of Oracle Apps developers know very little Java. Instead, the a
cadre of fairly elite Java coders forms the OA Framework team, which does
almost everything that requires Java coding, in a sufficiently general way
that it can be declaratively adapted to specific instances. I think that's
a *great* way to proceed--in fact, it's the primary core of my "Extreme
Reusability" methodology--but it's *not* the way that I think most
customers would go after skimming the JDeveloper doc and collateral.
Take a look, for example, at the help topic "working productively in
teams." If this principle should be articulated anywhere, it should be
articulated there. But there's no mention of it--it's all about who
designs the EOs, who designs the VOs, and who designs the pages. (Not that
I don't think that's a useful division. But if you're not going to train
your whole team in Java, it's *certainly* not the most important
division.) Instead, I think a lot of teams have the following experience:
1) They go for ADF without having real Java knowledge *anywhere* on their
team, because they have the impression it's a 100%-declarative framework
(except maybe for a bit of scripting-style Java, which is trivial to learn
if you're familiar with *any* procedural language).
2) They try to build a real enterprise application.
3) They freak out.
Now, as a consultant, that process isn't all that bad for me, because Step
4 is usually, "They hire a consultant to pull them out of the fire." But
for the community generally, I think it would be better if people went
*in* to ADF knowing what they do and don't need. They don't need a team
full of Java experts, or even of solid Java programmers. But they are
going to need someone (or, if they're a big team producing a lot of big
apps, several someones--probably even more than that if they're a *huge*
team like Oracle Apps) to solve their Java problems for them. And if they
don't want to hire or train someone like this, they can at least move Step
4 earlier in the process.
Best,
Avrom
Grant
Steven Davelaar| Technology Director | Oracle Consulting Tel +31 30 669 8113 | Fax +31 30 669 9966 Oracle Nederland BV | Rijnzathe 6, 3454 PV De Meern, The Netherlands PO Box 147, 3454 ZJ De Meern,The Netherlands | KvK nr. 30096087 |
| Oracle Expert Services | JHeadstart |
| Klik hier, dan solliciteert Oracle bij jou! |
[I'm a little worried that I wander off-topic with this, but it's still
related enough that I won't move it yet--Chris, please feel free to move
to a new thread if you prefer.]
I agree with this generally, but I want to make a few amendments/notes.
> A couple of observations for people converting from Forms:
> 1. Understand MVC and never ever call Application Module or Queries
> from Managed Beans even when its possible to do so.
I don't think this is a huge risk for the Forms developers, at least. The
place where I usually see this happening is with *Java* developers who are
new to ADF. A Forms developer is likely to try going declarative first,
and declarative access to the bindings is *much* more accessible than
direct access to the underlying business components, and can't be done at
all by drag-and-drop. By the time a former Forms developer gets
comfortable enough with Java to even think about writing managed bean
classes (which takes a non-negligible amount of time), they're usually
familiar enough with ADF to not make this sort of mistake.
(But this *is* a significant problem for new-to-ADF Java developers. I've
actually seen the following code [*KIDS, DON'T TRY THIS AT HOME--IT'S AN
EXAMPLE OF A BAD PRACTICE*] in a session-scoped managed bean:
ApplicationModule myService =
Configuration.createRootApplicationModule("myorg.myapp.model.MyService",
"MyServiceLocal");
But I can't see a Forms developer doing the above by mistake.
> 2. The way UI is developed in Web applications is very different from
> Forms. Example Context menus should be never be used in web pages
> unless its an internal application where users will receive training.
A little quibble here: Context menus should never be used as the *sole*
way to access a piece of functionality in an extranet web UI. They should
only be used as *shortcuts* for other ways of doing the same thing. But
*duplicating* a function in, say, both a main menu and a context menu
(plus providing an accelerator, which you need anyway for accessibility)
is a great way to cater to *all* levels of users--from new users to power
users. People who don't find the context menu can still do the action, and
people who *do* find it can do it faster. Imagine JDev without the context
menus! Aaaaa!(Even though can't think of any action in JDev that actually
requires that you use one.)
> 3. The event handling is mechanism is very different from Forms. Say
> in Forms if component A affects component B then you would write code
> in a trigger of A. While in case of ADF B will listen to A and act
> accordingly. So in ADF we write the actual logic in one of the
> listeners of B.
I think this is right, although I'd say it a different way--a more MVC-ish
way. I'm assuming (can you clarify) that you mean cases like the
following:
Component A is one of component B's partialTriggers. Instead of writing
logic in component A that changes component B, you write (or, usually, get
for free) logic in component A that changes a value in the model. Then you
write an expression (as one of component B's attribute values) that refers
to the model.
What's missing from your description is that both component A and
component B have logic are really interacting using model layer--either in
the actual Model project or in managed beans that are being used as
non-databound model components. The only logic in *either* of them that
directly refers to the other is the logic in B that says, "recheck model
values when A is used and refresh."
I could see how a (mediocre, non-pattern using) Java developer could have
trouble with this sort of thing--trying to expose A and B as managed
properties and have A change B directly, but I don't really think a Forms
developer could make a mistake with this--what would they be tempted to
do?
It's also worth noting, as a sideline, that there *is* an exception to
this rule. Rarely but occasionally, you need to determine the partial
targets of A's action programmatically (e.g., B is a particular component
in a particular row of a table, and you need to discover the correct row
by skimming through the data being displayed, or B should only be
refreshed if A is used *and* some other condition obtains). In this case,
I don't believe there's any way to write logic on B that will make it
refresh at the appropriate time. Instead, you need to write,
RequestContext.getCurrentInstance.addPartialTarget(B);
in A's firing logic. This, by the way, is also one of the few reasons to
ever expose ADF Faces components in a backing bean.
If you meant in business components too, while the listener system is cool
and often very useful, there are *lots* of use cases (I'd say the
majority, by a significant margin) for letting A change B directly.