posted Feb 12, 2011, 2:47 AM by Alar Raabe
Guidelines
for implementing and packaging business logic:
- Prerequisite is the
traditional architectural layering of application, where:
- Presentation
layer contains only "presentation logic" -- code, that is
needed to organize the presentation (mapping) of business information on
screen, and to accept and validate the user input from the input devices
(e.g. keyboard and mouse). Presentation layer is usually specific to the
given user interface device (e.g. web, GUI, mobile phone, ...). As much
as possible presentation logic should be declarative (e.g. layout and
mappings) or generated.
- Business
Process layer contains "process logic" -- code, that integrates
the business functions into business processes, organizes the access to
the business rules, and flow of control and information through the
business functions. Business process layer manages conversational state
and business transactions (sessions). Externalization of process logic
and business rules allows easy reconfiguration of business functionality
and provides flexibility required by the business. Business rules should be
side-effect free and as much as possible declarative.
- Business
Service layer contains "business logic" -- code, that performs
transactional business functions or business services, packaged into
business service components (usually business functions are grouped
around "subject areas" -- e.g. business functions dealing with
same business information should be grouped together). Business functions
are usually transactional and stateless, they delegate all the
state-management and data-intensive functionality to the database layer
components. Business service layer could be further divided into two
sub-layers: complex business functions and elementary business functions
that are reused by the complex business functions to perform their task.
Statelessness of business services allows easy scalability by deploying
more instances of business service components.
- Database
layer contains "data access/processing logic" -- that is code,
that encapsulates access to business data (implements mappings to data
store structures), enforces syntactic integrity constraints on business
data, and performs or delegates data-intensive business functions to the data store execution engine (stored procedures). As much as possible
data access logic should be declarative (e.g. mappings) or
generated.
- Integration
layer contains "integration logic" -- that is code, that
encapsulates connections to other applications (implements mappings to
external data formats, and manages conversational state connected to
integration). As much as possible integration logic should be declarative
(e.g. mappings) or generated.
- All layers could
be, if needed, distributed over different processes and/or computers.
A business function is a
function that gives business benefit to the user. A business function is
described by a business use-case.
- To identify what is the
business functionality in given application, following question should be
asked: "What remains unchanged, if the user interface and data
storage technologies will change?".
- As much as possible (when using J2EE platform):
- All
presentation logic should be implemented in presentation layer (using
JavaScript/Java or Flex or whatever has chosen).
- All
process logic, management of conversational state, and business rules
should be implemented in business process layer (using BPEL/Java).
- All
business functions that do not need large amount of data should be
implemented in business service layer as business services (using Java).
- All
business functions that need large amount of data should be implemented
in database layer (using stored procedures).
- All
business state should be managed in database.
- Interfaces for business
functions should (when using J2EE platform):
- Be
defined using Java (and all bindings to other systems (e.g. WSDL/XSD for
WS) will be generated from the service interface definitions),
- Should
be coarse-grained to avoid latency problems related to the remote access,
- Conform
to rules for remotable interfaces (take into account that methods could
be called remotely),
- Always
have a service context (representing business context, time context and
technical context) as a required input/output argument of every method
(this could be used for carrying conversational state is such need will
arise -- e.g. partitioning result of a method that returns large amount
of data),
- Contain
extension points that could be used to extend/customize the business
function (without changing the public interface of business function),
- Use
synthetic technical IDs or keys (which should not containing business
data) to represent identities of business objects in the interface (such
IDs should be considered temporary -- e.g. users of business
functions should not rely that they are same in successive uses of given
business function),
- Use
return values for communicating business exceptions,
- Use
Java exceptions only for technical exceptions.
- Be
documented according to the JavaDoc best practices, so that for every
method in the service interface following is described:
- The
business function performed ("what"),
- The
meaning of input and output parameters,
- The
meaning of technical exceptions,
- The
purpose and usage of the method illustrated with examples.
- Business service
components should have following interfaces:
- Business
service interfaces, through which all business functions that given
business service component offers, could be accessed.
If needed business service should have two separate business service
interfaces with different granularity to be used for different
situations:
- Fine-grained
interface (where single transaction requires small amount of data and
provides small piece of business functionality) for local usage where
transport mechanism provides low-latency connection to the service
component, and
- Coarse-grained
interface (where single transaction requires large amount of data and
provides large piece of business functionality) for remote usage
where transport mechanism provides high-latency connection to the
service component.
- Configuration
interface, through which the variability offered by the business service
component is configured (usually during setup/startup process).
- Management
interface, through which service component could be identified (for
configuration identification) and managed during run-time.
- Service
provider interfaces for other business or supporting services that given
business service component requires for performing its functions
- Reusable assets should
be treated same way as third-party products:
- Reusable
assets should have:
- Dedicated
development team.
- Its
own development goals, roadmap (together with a process for collecting
feature requests), and release cycle (changes to the public interfaces
should be done through deprecation and phase-off cycle).
- A
support service (together with a process for reacting to the defect
reports and releasing fix-packs).
- Reusable
asset should be isolated from the "client code" by isolation
and customization layer.
- Package
of reusable asset should contain:
- Release
notes.
- Developer's
package:
- Programmer's
Guide;
- Programmer's
Reference;
- Installation
scripts and database scripts (creation and upgrade);
- Interface
definitions;
- Development
binaries (if such are different from production binaries) and parameter
files;
- Source
code for debugging purposes;
- Development
dependencies (if such are different from production dependencies);
- Usage
(and customization) example(s) with the build scripts.
- Operational
package:
- Installation
and Configuration Guide;
- Operation
and Administration Guide;
- Installation
scripts and database scripts (creation and upgrade);
- Production
binaries and parameter files;
- Production
dependencies.
|
|