Arne said:
But this is where you completely have misunderstood
I have not.
The date builder you ask for requires calendar info.
The date builder I ask for requires a bog-standard Gregorian calendar,
not a localized one, because it is used to turn things like
network-layer timestamps into Dates, and low-layer stuff uses pretty
standardized formats. It's dates, intervals, and timing policies dropped
in by the user (as ordinary input, or as part of the local business
rules configuration) that (arguably!) need a full-blown general Calendar
system. And I'd still warrant that for 99% of major business
applications a bog-standard Gregorian calendar does the job here too.
The 12th day in the 11th month in the 2008th year is now after
the Gregorian calendar, but completely different times after
other calendars.
And how often is a file's time-stamp or something similar encoded in any
other than the Gregorian calendar? The most localization you typically
have to deal with there being time-zones, IF the filesystem is dumb
enough to store dates instead of seconds-since-the-epoch under the hood.
Network timestamps have been standardized: Gregorian calendar; UTC+0000,
or else with the timezone specified in the timestamp (e.g. "Date: Wed,
12 Nov 2008 22:44:10 -0500", from the header of your own news post,
specifies the time zone as UTC-0500).
These do not require a fully-general, polymorphic, localized calendar to
convert into a java.util.Date, only a Gregorian calendar parametrized by
a time zone offset.
Database timestamps and filesystem timestamps may be less standardized
in structure, but I think Julian or Arabic (or God help us Mayan)
calendars are downright rare or just plain do not occur in these either.
Your polymorphic Calendar is only useful at the top layers, not the
bottom. (And putting one in a dependency-injected business-policy object
counts as top layers.)
I18N was prioritized by Java.
Which means peripheral java.*/javax.* classes instead of peripheral
third-party classes, no more.
Most real world Java apps has web frontends.
Irrelevant.
And no - it is not the PL that decide to send out bills and add
interests to the account the 1st.
Sure it is. The BLL asks a policy object when to do these things. The
policy object is a dependency injection from the PL, and its specific
implementation is really part of the PL. That is the only sensible
architecture, because the BLL should not be cluttered up with
locale-dependent code or special cases; it should delegate to a policy
object that can be set appropriately at installation/setup time.
This is much the way the AWT code is not shot through with if Windows
then this, if MacOS then that, if X then theother type trichotomies;
instead it punts to a Toolkit object that is a black box to it. The
Toolkit object's exact class is OS-dependent. This means if ever a
fourth system became very popular, like say (on some frosty Friday in
July) BeOS, and they go to support it, they just need to stick a fourth
Toolkit subclass into the system and some code to detect a BeOS host
environment on startup and pick that subclass, instead of do a search
for every trichotomy of the sort mentioned above in the AWT code and add
BeOS code at each spot (making them quadrachotomies, or whatever it
should be called). This makes adding support for more host GUIs much
easier -- easy enough there probably already is BeOS support and a bunch
of even more obscure ones and probably wouldn't be if they hadn't done
everything through a Toolkit object.
Likewise the BLL should be parametrized by an object that determines
anything tricky, locale-dependent, dependent on local business rules,
and the like. That's a lot more than "which days are Tuesdays, which are
weekends" and the like that Calendar can answer, by the way -- it tends
to depend on local business rules, tax laws, sometimes even what
specific clients and partners and suppliers a business has. Such an
object is a virtual necessity if the software is not custom-made for one
business, and a wise idea even if it is (the business may move, the
business environment may change, the business may expand into a chain
that has branches in multiple environments). This object will be a
configuration parameter, so passed down from the PL. And this object,
needed *anyway*, is then the natural place to put any code that calls on
Calendar in deciding when to pay what bill and so forth. That is, why have
if (businessPolicy.isRentDueOnFirstOfMonth()) {
if (calendar.get(DAY_OF_MONTH) == 1) {
payRent();
}
}
when we can have
if (businessPolicy.isRentDue()) {
payRent();
}