Академический Документы
Профессиональный Документы
Культура Документы
Encapsulation is what allows a client to interact with an object without knowledge of its
implementation details, a primary premise for loose coupling. In applications that use
data-aware widgets, the opposite is the case. The client and the database are very tightly
coupled. GUI code, business logic, and SQL statements are all interwoven throughout
the application source code. As a result, the application can become a maintenance
nightmare. Any changes in the database schema will surely cascade into unexpected
failures.
A much better approach utilizes the business object model. A business object is modeled
after a business or organization concept, such as a person, place, event, or process. It
represents a real-world entity such as an employee, product, invoice, or payment.
Business objects fully encapsulate the behavior that is expected from the entity they
model.
For example, an Item object in an invoicing application can be asked "How much is
available for sale?" or "What is the unit price when 10 units are purchased?" simply by
calling getQtyAvailable() or getUnitPriceForQty( qty ) methods in the object.
Below is a short list of reasons you might want to use business objects in your next
project:
1. Business objects fully insulate clients from business rules, the underlying data storage,
and concurrency issues, resulting in complete encapsulation. Because clients only
interact with business objects, changes can be made in the database without having to
touch a single line of code at the client.
2. Applications have an open architecture and are fully scalable. Business objects can be
implemented in a variety of configurations from client/server to n-tier.
3. Applications built with business objects are also much more maintainable. The
architecture separates responsibility into loosely coupled layers (i.e., user interface,
business objects, and data storage). Business objects can be loosely coupled to the user
interface using the model-view-controller (MVC) architecture. MVC is a modular
approach to GUI construction that separates the user interface, control of user input (i.e.,
event handling), and business objects into three different components that interact
together. Because of this separation of responsibility applications can be modified more
easily when the business needs change.
4. Business object models are based on procedures already established by the
organization. Experts in the problem domain who are not necessarily developers can
design the model. Developers can then implement it using any object-oriented language.
5. Business objects can be implemented as components that are reusable by different
client applications. Clients can have different user views (GUI interfaces) of the same
object depending on purpose.
6. Thin clients that run on the new network computers such us the NC or the NetPC, or
on other devices such as mobile phones, PDAs, or TV boxes, can be more easily
implemented. The client needs contain only user interface code-all business logic and
data storage code resides on other machines across the network.
The extra planning and effort required to implement an application using business objects
are well worth it. Business-object-based applications are much more robust and
maintainable than traditional two-layer applications. It's surprising that most popular IDEs
in use today still endorse the two-layer approach.
This diagram models a simple inheritance tree made up of a Person abstract class from which the
Employee and Customer concrete classes inherit.
Vertical Mapping. In vertical mapping, each class in the tree, whether abstract or concrete, is
mapped to a different table. All branch and leaf tables in the tree must be linked to their parent
tables. This can be accomplished by means of a foreign key column that references the primary key
of the parent table. In order to instantiate a concrete class using this method, a join query of the
concrete class table and all its abstract parent class tables must be performed. The table below
shows how our sample model is mapped to an Access database using vertical mapping:
Person Table
Column Name Data Type
PersonID AutoNumber
LastName Text(25)
FirstName Text(25)
Title Text(3)
Employee Table
Column Name Data Type
ID AutoNumber
PersonID Long
Since Date/Time
PayRate Currency
Customer Table
Column Name Data Type
ID AutoNumber
PersonID Long
Terms Text(25)
Owes Currency
The EMPLOYEE and CUSTOMER tables are related to the PERSON table via the PersonID
column. Thus, instantiating an employee object with OID=100 requires a join of the PERSON and
EMPLOYEE tables:
SELECT e.ID, p.LastName, p.FirstName,p.Title, e.Since, e.PayRate
FROM PERSON p, EMPLOYEE e
WHERE e.PersonID=p.ID AND e.ID=100;
This method closely mimics the class inheritance tree in the database, but can result in complex and
time consuming queries on moderately deep inheritance hierarchies. VBSF allows you to define this
type of mapping by mapping each class in the tree to its own table using a SUPERSET mapping.
Horizontal Mapping. Under horizontal mapping, each concrete class in the tree is mapped to a
different table. Each of these mapped tables contains columns for all attributes in its concrete class,
plus all attributes inherited from all its abstract parent classes. In other words, abstract classes are
not mapped to their own table. This approach provides very fast performance, and is simple to
design. However, if an attribute of an abstract parent class is changed, then potentially many tables
must be modified. Consequently, this method is most useful if the inheritance tree is more method
driven than attribute driven. To be more specific, if a substantial number of classes inherit a large
number of attributes from an abstract parent class, then the vertical or filtered methods might be
better choices.
As shown in the table below, the number of tables necessary to map our sample model to an Access
database using horizontal mapping is reduced to two. Retrieving an employee or customer in this
case involves querying only its corresponding table.
Employee Table
Column Name Data Type
ID AutoNumber
LastName Text(25)
FirstName Text(25)
Title Text(3)
Terms String
Owes Currency
Customer Table
Column Name Data Type
ID AutoNumber
LastName Text(25)
FirstName Text(25)
Title Text(3)
Since Date/Time
PayRate Currency
Filtered Mapping. In filtered mapping all concrete classes in the tree are mapped to the same table.
The table must contain columns for all attributes of all the abstract and concrete classes in the
inheritance tree (or the part of the tree using this mapping). In addition, a filter column is created in
the table. The value of the filter column is used to distinguish between subclasses. Abstract classes
are not mapped to this table. This approach provides adequate performance, but violates table-
normalization rules. More specifically, it could lead to a substantial number of NULL columns in the
table, wasting space. Consequently, this method is most useful if most of the attributes are inherited
from the abstract parent classes. As shown in the table below, only one table is necessary to map our
sample model to an Access database using filtered mapping.
Person Table
Column Name Data Type
ID AutoNumber
Type Integer
LastName Text(25)
FirstName Text(25)
Title Text(3)
Since Date/Time
PayRate_Owes Currency
Terms Text(25)
The Type column is used as a filter used to distinguish the type of object being stored. For
example, assuming that a Type=1 is used for employees, then to retrieve all employees from the
Person table we can issue the following query:
SELECT ID, LastName, FirstName, Title, Since, PayRate_Owes
FROM Person WHERE Type=1;
The Since column will always be NULL for customers, as will the Terms column for employees.
Notice, however, that the PayRate_Owes column can be used for both because of the common
data type.
VBSF provides specific support for filters in such a way that the filter column does not have to be
defined as an attribute in your business class. VBSF automatically reads and updates this column as
necessary. For detailed information about defining a filter for a persistent class see section 3.4.
Filter and Concurrency Columns.
Invoice Table
Column Name Data Type
ID AutoNumber
CustomerID Long
Date Date/Time
Invlineitem Table
Column Name Data Type
ID AutoNumber
InvoiceID Long
Description Text(30)
Price Currency
Qty Double
Customer Table
Column Name Data Type
ID AutoNumber
Name Text(30)
The POS class diagram and its table structure will be used in the following sections to discuss the
various ways one-to-one (husband-wife), one-to-many (father-child), and many-to-many
(Grandparent-child) objects relationships can be mapped to the relational model.
One-to-One Relationships
A to-one relationship is implemented in Java using a direct reference to another object. VBSF
supports two kinds of to-one relationships: contained and referenced. When an object holds a
contained reference to another object, it can create and delete its contained object. Furthermore,
when the holder of the contained reference is updated in the database (inserted, updated, or deleted),
all its contained references are automatically updated (this default behavior can be overridden at
runtime if necessary). In the POS diagram, the Invoice class has a to-one relationship with the
Customer class. If this reference is not contained, then when an Invoice is updated in the
database, its referenced Customer object is not automatically updated.
In the relational model a to-one relationship is usually maintained by means of an embedded foreign
key column. This foreign key column holds the value of the primary key (the object ID) of the row
(object) being referenced. In the POS table structure the Invoice table has an embedded foreign key
column named CustomerID. This column holds the value of the primary key column (i.e. ID) in the
Customer table.
A to-one relationship is implemented in VBSF by defining a Reference attribute. VBSF
transparently converts the foreign key reference to an object, and updates the value of the foreign
key column from referenced objects.
It is also possible to define a to-one relationship in the relational model using a join table. VBSF
also supports this scenario. In this case, however, the attribute must be defined as a Referenced
Collection. The only difference is that, by virtue of the association, the collection holds just one
referenced object instead of a collection of objects.
One-to-Many Relationships
In the object model there are two types of to-many relationships: aggregation (part-of), and
association (acquaintance). Under VBSF an aggregation relationship is defined by means of an
Owned Collection attribute, and an association relationship by means of a Referenced Collection
attribute. The difference between the two is that in an owned relationship when the owner is
updated in the database, all objects in all its owned collections are automatically updated (this
default behavior can be overridden at runtime if necessary).
In the relational model a one-to-many relationship can be defined either using an embedded foreign
key column, or using a join table. An embedded foreign key is a column defined in the table on the
many side of the relationship that holds a key to the table in the one side of the relationship. A join
table is a table whose sole purpose is to store mapping values between the key and foreign key of
the two tables involved in the relationship.
An owned relationship can only be implemented using an embedded foreign key column. A
referenced relationship can be implemented using either method-embedded foreign key or join
table. The following two sections discuss each case in further detail.
Owned Relationships (Aggregation)
In an owned relationship the owner class holds a reference to its owned collection using an Owned
Collection attribute and the owned class holds a direct reference to its owner using a Reference
attribute. An owner object automatically handles all inserts, updates and deletions of all its owned
objects in the database. VBSF automatically and transparently takes care of updating owned objects
in the database whenever an owner object is updated in the database. This behavior is recursive, so
if any owned objects are in turn owners (i.e. they hold other owned collections), all their owned
objects will also be updated in the database too, and so on. In this manner whole objects graphs can
be updated in the database in one operation. This type of behavior is known as persistence by
reachability, and is fully supported by VBSF.
An owned relationship is implemented in the relational model using an embedded foreign key
column in the table on the many side of the relationship. In the POS diagram the Invoice class
has a one-to-many relationship with the InvoiceLineItem class. In the POS table structure the
Invlineitem table has an embedded foreign key column named InvoiceID. This column holds the
value of the primary key column (i.e. ID) in the Invoice table.
VBSF transparently reads and updates the embedded foreign key column value of owned objects.
Referenced Relationships (Association)
In a one-to-many association, the class on the one side of the relationship does not own the other
class, it merely references it. This means that an object on the one side (also referred to as the
holder of the collection) of the relationship cannot create, update, or delete objects on the many side
of the relationship, it can only retrieve them. In this case, the holder uses a Referenced Collection
attribute to reference its associated collection instead of an Owned Collection attribute. A
Referenced Collection attribute can also be used to hold collections of objects of the same class as
the holder of the collection.
A Referenced Collection attribute can handle the association in the database by using either an
embedded foreign key column or a join table. To handle the association using a join table, the
referenced collection attribute must be mapped to a join table. See section 4.6. Defining Joins for
Referenced Collections for details.
Many-to-Many Relationships
A many-to-many relationship can be thought of as a bi-directional one-to-many association. To
create this type of relationship you simply define a Referenced Collection attribute in each of the
classes involved in the relationship. In the relational model a many-to-many relationship can be
defined either using foreign key columns or using a join table.
To use foreign keys, an embedded foreign key column is defined in each of the tables involved in
the relationship. Each foreign key column holds the key to the other table. The next section
discusses various ways to implement many-to-many associations using join tables.
BOM Table
Column Name Description
ID Primary Key
BOM Table
Column Name Description
ID Primary Key
Category Table
Column Name Data Type
ID AutoNumber
Number Text(10)
Description Text(25)
The Locator table below contains three simple attributes named Type, LocatorNo, and Description,
and an additional embedded foreign key field named ContactID that links it to its Contact owner:
Locator Table
Column Name Data Type
ID AutoNumber
ContactID Long
Type Integer
LocatorNo Text(15)
Description Text(25)
The Contact table below contains an object reference foreign key field named CategoryID:
Contact Table
Column Name Data Type
ID AutoNumber
LastName Text(25)
FirstName Text(25)
Title Text(3)
CategoryID Integer