Software Design: Layers Detailed
Software Design: Layers Detailed
SOFTWARE DESIGN
Layers detailed
8/25/2019 Computer Science Department, TUC-N
Content
• Patterns for Enterprise Application Architecture [Fowler]
• Domain Layer Patterns
• Transaction Script
• Domain Model
• Table Module
• Active Record
• Data Source Patterns
• Row Data Gateway
• Table Data Gateway
• Data Mapper
• Presentation
• Template View
• Transform View
• Page Controller
• Front Controller
8/25/2019 Computer Science Department, TUC-N
References
• Martin Fowler et. al, Patterns of Enterprise Application
Architecture, Addison Wesley, 2003 [Fowler]
• Univ. of Aarhus Course Materials
• Univ. of Utrecht Course Materials
8/25/2019 Computer Science Department, TUC-N
Enterprise applications
• Example: B2C online retailer
• High volume of users: scalability
• Example: processing of leasing agreements
• Complicated business logic
• Rich-client interface
• Complicated transaction behavior
• Example: expense tracking for small company
8/25/2019 Computer Science Department, TUC-N
Principal layers
• See pattern Layers in [POSA]
• Here: applied to enterprise
applications
• Presentation logic
• Interaction with user
• Command-line or rich client or Web
interface
• Domain logic
• Validation of input and calculation of
results
• Data source logic
• Communication with database and
other applications
8/25/2019 Computer Science Department, TUC-N
Data Source Domain Presentation EA Patterns
Domain Model
Transaction Script
Basic Patterns
• Gateway
• Record Set
8/25/2019 Computer Science Department, TUC-N
Gateway
An object that encapsulates access to an external system
or resource
8/25/2019 Computer Science Department, TUC-N
Gateway - Benefits
• Easier handling of awkward API’s
Gateway - Example
build a gateway to an interface that just sends a message
using the message service
Confirmation message
messageType = ‘CONFIRM’;
args[0] = id;
args[1] = amount;
args[2] = symbol;
8/25/2019 Computer Science Department, TUC-N
Better…
8/25/2019 Computer Science Department, TUC-N
Record Set
An in-memory representation of tabular data
8/25/2019 Computer Science Department, TUC-N
• Pure patterns
• Transaction Script
• Domain Model
• Hybrid patterns
• Active Record
• Table Module.
8/25/2019 Computer Science Department, TUC-N
Transaction Script
Transaction Script
TS Features
• Business logic is organized by procedures
Example (http://lorenzo-dee.blogspot.ro/2014/06/quantifying-
domain-model-vs-transaction-script.html)
• Banking application
• Money transfer functionality
8/25/2019 Computer Science Department, TUC-N
8/25/2019 Computer Science Department, TUC-N
Analysis
• Strenghths
• Simplicity
• Weaknesses
• complicated transaction logic
• duplicated logic
8/25/2019 Computer Science Department, TUC-N
DM Features
• Business logic is organized as an OO model of the
domain
• Describes both data and behavior
• Different from database model
• Process, multi-valued attributes, inheritance, design patterns
• Harder to map to the database
• Pure patterns.
• Row Data Gateway,
• Table Data Gateway,
• Data Mapper
• …
8/25/2019 Computer Science Department, TUC-N
Table Module
• Provide a single object for all the behavior on a table
TS vs TM
8/25/2019 Computer Science Department, TUC-N
TS vs TM
8/25/2019 Computer Science Department, TUC-N
Implementation
• Database
Implementation
• calculate the amount of recognition due by a
particular day:
- select the appropriate rows in the revenue recognitions
table,
- sum up the amounts.
8/25/2019
Gateway class
class Gateway...
public ResultSet findRecognitionsFor(long contractID,
MfDate asof) throws SQLException
{
PreparedStatement stmt =
db.prepareStatement(findRecognitionsStatement);
stmt.setLong(1, contractID);
stmt.setDate(2, asof.toSqlDate());
RecognitionService class
class RecognitionService...
public Money recognizedRevenue(long contractNumber,
MfDate asOf)
{
Money result = Money.dollars(0);
try {
ResultSet rs =
db.findRecognitionsFor(contractNumber, asOf);
while (rs.next())
{
result =
result.add(Money.dollars(rs.getBigDecimal("amount")));
}
return result;
}
catch (SQLException e) {
throw new ApplicationException (e); }
}
8/25/2019
RR Domain Model
8/25/2019
• Domain Model:
• Create new Rev. Recog. Strategy class.
8/25/2019
Implementation
class RevenueRecognition...
private Money amount;
private MfDate date;
public RevenueRecognition(Money amount, MfDate
date)
{
this.amount = amount;
this.date = date;
}
public Money getAmount()
{
return amount;
}
boolean isRecognizableBy(MfDate asOf)
{
return asOf.after(date) || asOf.equals(date);
}
8/25/2019
Contract class
class Contract...
private List revenueRecognitions = new
ArrayList();
public Money recognizedRevenue(MfDate asOf)
{
Money result = Money.dollars(0);
Iterator it =
revenueRecognitions.iterator();
while (it.hasNext())
{
RevenueRecognition r =
(RevenueRecognition) it.next();
if (r.isRecognizableBy(asOf))
result = result.add(r.getAmount());
}
return result;
}
8/25/2019
Introducing strategies…
class Contract...
private Product product;
private Money revenue;
private MfDate whenSigned;
private Long id;
public Contract(Product product, Money
revenue, MfDate whenSigned)
{
this.product = product;
this.revenue = revenue;
this.whenSigned = whenSigned;
}
8/25/2019
Introducing strategies …
class Product...
private String name;
private RecognitionStrategy recognitionStrategy;
public Product(String name, RecognitionStrategy
recognitionStrategy)
{
this.name = name;
this.recognitionStrategy = recognitionStrategy;
}
public static Product newWordProcessor(String name)
{
return new Product(name, new
CompleteRecognitionStrategy());
}
public static Product newSpreadsheet(String name)
{
return new Product(name, new
ThreeWayRecognitionStrategy(60, 90));
}
public static Product newDatabase(String name)
{
return new Product(name, new
ThreeWayRecognitionStrategy(30, 60)); }
8/25/2019
Introducing strategies …
class RecognitionStrategy...{
abstract void
calculateRevenueRecognitions(Contract
contract); }
class CompleteRecognitionStrategy...
void calculateRevenueRecognitions(Contract
contract)
{
contract.addRevenueRecognition(new
RevenueRecognition(contract.getRevenue(),
contract.getWhenSigned()));
}
class ThreeWayRecognitionStrategy...
8/25/2019 Computer Science Department, TUC-N
Introducing strategies
class Contract...
public void calculateRecognitions()
{
product.calculateRevenueRecognitions(this
);
}
class Product...
void calculateRevenueRecognitions(Contract
contract)
{
recognitionStrategy.calculateRevenueRecog
nitions(contract);
}
8/25/2019
TM in the RR example
8/25/2019
RR problem with TM
8/25/2019
Implementation (C#)
class TableModule...
protected DataTable table;
protected TableModule(DataSet ds,
String tableName)
{
table = ds.Tables[tableName];
}
8/25/2019
ContractModule subclass
class ContractModule...
public ContractModule (DataSet ds) : base
(ds, "Contracts") {}
public DataRow this [long key]
{
get
{
String filter = String.Format("ID =
{0}", key);
return table.Select(filter)[0];
}
}
RevenueRecognition class
class RevenueRecognition...
public Decimal RecognizedRevenue (long contractID,
DateTime asOf)
{
String filter = String.Format("ContractID =
{0} AND date <= #{1:d}#", contractID,asOf);
DataRow[] rows = table.Select(filter);
Decimal result = 0;
foreach (DataRow row in rows)
{
result += (Decimal)row["amount"];
}
return result;
}
8/25/2019 Computer Science Department, TUC-N
Active Record
Fowler: An object that wraps a record data
structure in an external resource, such as a row
in a database table, and adds some domain logic
to that object.
Class operations
Implementation
class Person...
private String lastName;
private String firstName;
private int numberOfDependents;
Next Time
• More patterns