Domain-Driven Design: Tackling Complexity in the Heart of Software


Example Package Coding Conventions in Java



Download 7,21 Mb.
Pdf ko'rish
bet77/343
Sana17.11.2022
Hajmi7,21 Mb.
#867526
1   ...   73   74   75   76   77   78   79   80   ...   343
Bog'liq
Eric Evans 2003 - Domain-Driven Design - Tackling Complexity in the Heart of Software

Example
Package Coding Conventions in Java
In Java, imports (dependencies) must be declared in some individual class. A modeler probably
thinks of packages as depending on other packages, but this can't be stated in Java. Common
coding conventions encourage the import of specific classes, resulting in code like this:
ClassA1


import packageB.ClassB1;
import packageB.ClassB2;
import packageB.ClassB3;
import packageC.ClassC1;
import packageC.ClassC2;
import packageC.ClassC3;
. . .
In Java, unfortunately, there is no escape from importing 
into
individual classes, but you can at
least import entire packages at a time, reflecting the intention that packages are highly cohesive
units while simultaneously reducing the effort of changing package names.
ClassA1
import packageB.*;
import packageC.*;
. . .
True, this technique means mixing two scales (classes depend on packages), but it communicates
more than the previous voluminous list of classes—it conveys the intent to create a dependency on
particular 
MODULES
.
If an individual class really does depend on a specific class in another package, and the local
MODULE
doesn't seem to have a conceptual dependency on the other 
MODULE
, then maybe a class
should be moved, or the 
MODULES
themselves should be reconsidered.
The Pitfalls of Infrastructure-Driven Packaging
Strong forces on our packaging decisions come from technical frameworks. Some of these are
helpful, while others need to be resisted.
An example of a very useful framework standard is the enforcement of 
LAYERED ARCHITECTURE
by
placing infrastructure and user interface code into separate groups of packages, leaving the
domain layer physically separated into its own set of packages.
On the other hand, tiered architectures can fragment the implementation of the model objects.
Some frameworks create tiers by spreading the responsibilities of a single domain object across
multiple objects and then placing those objects in separate packages. For example, with J2EE a
common practice is to place data and data access into an "entity bean" while placing associated
business logic into a "session bean." In addition to the increased implementation complexity of
each component, the separation immediately robs an object model of cohesion. One of the most
fundamental concepts of objects is to encapsulate data with the logic that operates on that data.
This kind of tiered implementation is not fatal, because both components can be viewed as
together constituting the implementation of a single model element, but to make matters worse,
the entity and session beans are often separated into different packages. At that point, viewing the
various objects and mentally fitting them back together as a single conceptual 
ENTITY
is just too
much effort. We lose the connection between the model and design. Best practice is to use EJBs at
a larger grain than 
ENTITY
objects, reducing the downside of separating tiers. But fine-grain objects
are often split into tiers also.
For example, I encountered these problems on a rather intelligently run project in which each
conceptual object was actually broken into four tiers. Each division had a good rationale. The first
tier was a data persistence layer, handling mapping and access to the relational database. Then
came a layer that handled behavior intrinsic to the object in all situations. Next was a layer for


superimposing application-specific functionality. The fourth tier was meant as a public interface,
decoupled from all the implementation below. This scheme was a bit too complicated, but the
layers were well defined and there was some tidiness to the separation of concerns. We could have
lived with mentally connecting all the physical objects making up one conceptual object. The
separation of aspects even helped at times. In particular, having the persistence code moved out
removed a lot of clutter.
But on top of all this, the framework required each tier to be in a separate set of packages, named
according to a convention that identified the tier. This took up all the mental room for partitioning.
As a result, domain developers tended to avoid making too many 
MODULES
(each of which was
multiplied by four) and hardly ever changed one, because the effort of refactoring a 
MODULE
was
prohibitive. Worse, hunting down all the data and behavior that defined a single conceptual class
was so difficult (combined with the indirectness of the layering) that developers didn't have much
mental space left to think about models. The application was delivered, but with an anemic domain
model that basically fulfilled the database access requirements of the application, with behavior
supplied by a few 
SERVICES
. The leverage that should have derived from 
MODEL-DRIVEN DESIGN
was
limited because the code did not transparently reveal the model and allow a developer to work
with it.
This kind of framework design is attempting to address two legitimate issues. One is the logical
division of concerns: One object has responsibility for database access, another for business logic,
and so on. Such divisions make it easier to understand the functioning of each tier (on a technical
level) and make it easier to switch out layers. The trouble is that the cost to application
development is not recognized. This is not a book on framework design, so I won't go into
alternative solutions to that problem, but they do exist. And even if there were no options, it would
be better to trade off these benefits for a more cohesive domain layer.
The other motivation for these packaging schemes is the distribution of tiers. This could be a
strong argument if the code actually got deployed on different servers. Usually it does not. The
flexibility is sought just in case it is needed. On a project that hopes to get leverage from 
MODEL-
DRIVEN DESIGN
, this sacrifice is too great unless it solves an immediate and pressing problem.
Elaborate technically driven packaging schemes impose two costs.
If the framework's partitioning conventions pull apart the elements implementing the
conceptual objects, the code no longer reveals the model.
There is only so much partitioning a mind can stitch back together, and if the framework uses
it all up, the domain developers lose their ability to chunk the model into meaningful pieces.
It is best to keep things simple. Choose a minimum of technical partitioning rules that are essential
to the technical environment or actually aid development. For example, decoupling complicated
data persistence code from the behavioral aspects of the objects may make refactoring easier.

Download 7,21 Mb.

Do'stlaringiz bilan baham:
1   ...   73   74   75   76   77   78   79   80   ...   343




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish