domain logic patterns transaction script domain model table module service layer

36
ENTERPRISE APPLICATION ARCHITECTURE

Upload: gwen-beasley

Post on 11-Jan-2016

234 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

ENTERPRISE APPLICATION ARCHITECTURE

Page 2: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

Domain Logic Patterns

Transaction Script Domain Model Table Module Service Layer

Page 3: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

Transaction Script

Organizes business logic by procedures where each procedure handles a single request form the presentation

Page 4: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

TS: How It Works

Each business transaction corresponds to one transaction script Business transaction: Book a hotel room Tasks: check room availability, calculate rates,

update the database – all handled in one BookARoom script.

Transaction scripts access the database directly Don’t call any logic in the presentation layer Organization

Each script is a procedure Related scripts are enclosed in one class Each script is in one class.

Page 5: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

TS: Architecture

TransactionScriptbusinessTransaction1()businessTransaction2()businessTransaction3()

Gateway

findDataForBusinessTransaction1(sql_query)insertRecordsForBusinessTransaction1(sql_insert, items)updateRecordsForBusinessTransaction2(sql_update, items)…

sql_query= “ SELECT * FROM table 1…”sql_insert = “INSERT into tablei…”sql_update = “ UPDATE tablei …”sql_delete = “DELETE FROM …”

DB

Page 6: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

TS: When to use it

When the domain logic is very simple When transactions do not have a lot

of overlap in functionality

Page 7: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

Example Revenue Recognition A contract is signed for one product The revenue of a contract may not be recognized

right away. Different types of product may have different

revenue recognition schedule Three types of product

Word Processor: revenue recognized right away Spreadsheet: 1/3 today, 1/3 in 60 days, 1/3 in 90 days. Database: 1/3 today, 1/3 in 30 days, 1/3 in 60 days.

Product

Nametype

Contract

date _signedrevenue

RevenueRecognitionAmount

date

11 * *

Page 8: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

TS: Example

RecognitionServicecalcRecognitions(contract#)recognizedRevenue(contract#, date)createContract(id, revenue, prod_id, date)…

DatabaseGateway

findContract(contract#)findRecognitionsFor(contract#, date)insertRecognition(contract#, revenue, date)…

Sql_findContract = “ SELECT * FROM Contract WHERE id = ?”Sql_findRecogns = “select* from recog Where cid=? and date<?”Sql_insertContract = “INSERT into contract…”

DB

Page 9: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

createContract()

Sequence Diagram: test cases

:RecognitionService :DatabaseGateway

:Tester

insertContract()INSERT into contract …

:Database

calcRecognitions()insertRecognition()

INSERT iinto Recog…

recognizedRevenue()findRecognitionsFor()

SELECT * FROM …

insertRecognition()INSERT iinto Recog…

INSERT iinto Recog…insertRecognition()

Page 10: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

TS: Example

class Gateway { static String findRecogns = “SELECT * FROM revenueRecognition WHERE contract = ? And date <= ?”; static String findContract = “SELECT * FROM contract c, product p WHERE c.id = ? And c.pid = p.id”; public ResultSet findRecognitionsFor(int contrno, Date d) { PreparedStatement s = db.prepareStatement(findRecongs); s.setInt(1, contrno); s.setDate(2, d); ResultSet result = s.executeQuery(); return result; } public ResultSet findContract(int contrno) { PreparedStatement s = db.prepareStatement(findContract); s.setInt(1, contrno); ResultSet result = s.executeQuery(); return result; }}

Page 11: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

TS: Exampleclass RecognitionService { private Gateway gw = new Gateway(); public Money recognizedRevenue(int contrno, Date d) { Money Result = Money.dollar(0); ResultSet rs = gw.findRecognitionsFor(contrno, d); while (rs.next()) { result = result.add(rs.getBigDecimal(“amount”)); } return result; } public void calculateRevenueRecognitions(int contrno) { ResultSet contrs = gw.findContract(contrno); totalRevenue = contrs.getBigDecimal(“revenue”); dates = contrs.getDate(“date_signed”); type = contrs.getChar(“type”); if (type == ‘S’) { db.insertRecognition(contrno, totalRevenue/3, date); db.insertRecognition(contrno, totalRevenue/3, date+60); db.insertRecognition(contrno, totalRevenue/3, date+90); } else if (type = ‘W’) { db.insertRecognition(contrno, totalRevenue, date); } else if (type == ‘D’ { ... }...

Page 12: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

Domain Model

An object model of the domain that incorporates both behavior and data

Page 13: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

DM: Revenue Recognition

ProductNametype

Contract

date _signedrevenue

RevenueRecognitionAmount

date

1

1*

*

recognizedRevenue(date)calculateRecognitions()

calcRecognitions(contrct)

RecognitionStrategy

CompleteRecognitionStrate

gy

*1

Three-wayRecognitionStrate

gy

calcRecognitions(contrct)

isRecognizableBy(date)

DB

Page 14: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

DM: Exampleclass RevenueRecognition { private Money amount; private Date date; public RevenueRecognition(Money amnt, Date d) {...} public Money getAmount() { return amount; } public boolean isRecognizableBy(Date date) { return this.date.before(date) || this.date.equals(date); }...}class Contract { private List revenueRecognitions = new ArrayList(); public Money recognizedRevenue(Date date) { Money result = Money.dollar(0); Iterator it = revenueRecognitions.iterator(); while (it.hasNext()} { RevenueRecognition r = (RevenueRecognition)it.next(); if (r.isRecognizableBy(date)) result = result.add(r.getAmount()); } return result; }...

Page 15: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

DM: Exampleclass RevenueRecognition { private Money amount; private Date date; public RevenueRecognition(Money amnt, Date d) {...} public Money getAmount() { return amount; } public boolean isRecognizableBy(Date date) { return this.date.before(date) || this.date.equals(date); }...}class Contract { private List revenueRecognitions = new ArrayList(); public Money recognizedRevenue(Date date) { Money result = Money.dollar(0); Iterator it = revenueRecognitions.iterator(); while (it.hasNext()} { RevenueRecognition r = (RevenueRecognition)it.next(); if (r.isRecognizableBy(date)) result = result.add(r.getAmount()); } return result; }...

Page 16: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

DM: Exampleclass Contract { private Product product; private Money amount; private Date dateSigned; private long id; public Contract(Product p, Money amnt, Date d) {...} public void addRecognition(RevenueRecognition rr) { revenueRecognitions.add(rr); } public Date getDateSigned() { return dateSigned; } public void calcRecognitions() { product.calcRecognitions(this); }...}interface RecognitionStrategy { public void calcRevenueRecognitions(Contract c);}

Page 17: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

DM: Exampleclass CompleteRecognitionStrategy implements ... { public void calcRevenueRecognitions(Contract c) { c.addRecognition(new RevenueRecognition( c.getAmount(), c.getDateSigned()); }}class ThreeWayRecognitionStrategy implements ... { private int firstRecognitionOffset; private int secondRecognitionOffset; public ThreeWayRecognitionStrategy(int offset1, int offset2) { this.firstRecognitionOffset = offset1; this.secondRecognitionOffset = offset2; } public void calcRevenueRecognitions(Contract c) { c.addRecognition(new RevenueRecognition( c.getAmount()/3, c.getDateSigned()); c.addRecognition(new RevenueRecognition( c.getAmount()/3, c.getDateSigned()+offset1); c.addRecognition(new RevenueRecognition( c.getAmount()/3, c.getDateSigned()+offset2); } ... }

Page 18: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

DM: Exampleclass Product { private String name; private RecognitionStrategy recogStrategy; public Product(String name, RecognitionStrategy rs) { this.name = name; this.recogStrategy = rs; } public void calcRecognitions(Contract c) { recogStrategy.calcRecognitions(c); } 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)); }}

Page 19: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

DM: Exampleclass Tester { public static void main(String[] args) { Product word = Product.newWordProcessor(“IntelWord”); Product calc = Product.newSpreadsheet(“calc II”); Product db = Product.newDatabse(“DB IV”);

Date today = System.today(); Contract c1 = new Contract(word, 300000, today); c1.calcRecognitions(); Contract c2 = new Contract(calc, 24000, today); c2.calcRecognitions(); // sequence diagram – next slide Contract c3 = new Contract(db, 540000, today); c3.calcRecognitions();

System.out.println(c1.recognizedRevenue(today + 10)); System.out.println(c2.recognizedRevenue(today + 70)); System.out.println(c3.recognizedRevenue(today + 80)); }}

Page 20: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

product:Product

c2.:Contract

calcRecognitions()

calcRecognitions(c2)

DM: Sequence Diagram: c2.calcRecognitions()

rr1:RevenueRecognition

recogStrategy:RecognitionStrategy

(amount/3, date)

calcRecognitions(c2)

Mount = getAmount()

date = getDateSigned()

addRecognition(rr1)rr2:RevenueRecognition

rr3:RevenueRecognition

addRecognition(rr2)

addRecognition(rr3)

(amount/3, date + 60)

(amount/3, date + 90)

:Tester

Page 21: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

c2.:Contract

recognizedRevenue(date)

isRecognizableBy(date)

DM: Sequence Diagram: c2.recognizedRevenue()

rr[0]:RevenueRecognition rr[1]:RevenueRecognition rr[2]:RevenueRecognition

:Tester

getAmount()

isRecognizableBy(date)

getAmount()

isRecognizableBy(date)

return result

Page 22: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

Table Module

A single instance that handles the business logic for all rows in a database table or view Each module is responsible for all the

CRUD operations on the corresponding table.

No other modules are supposed to CRUD directly on the table

Each module also includes business logic that is tightly related to the table.

Page 23: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

TM: Architecture

Table_1TableModule_1

CRUD operations on Table_1Business Logic related to Table_1

Attributes

Table_2TableModule_2

CRUD operations on Table_2Business Logic related to Table_2

Attributes

Table_nTableModule_n

CRUD operations on Table_nBusiness Logic related to Table_n

Attributes

Database

Page 24: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

TM: Example - Tables

Product

Contract RevenueRecognitionId: Number

dateSigned: Daterevenue: Numberprod_id: Number (FK)

Id: Numbername: Stringtype: String

Id: Numberamount: Numberdate: Date c_id: Number (FK)

Page 25: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

TM: Example - Modules

Product

Contract RevenueRecognition

Insert(cid, revenue, prod_id, date)calculateRecognitions(c_id)

getProductType(prod_id)

Insert(c_id, amount, date)recognizedRevenue(c_id, date)

DB

Page 26: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

:Product

:Contract

getContract(id)

getProductID()

TM: Sequence Diagram: calcRecognitions()

:RevenueRecognition

:Tester

contract:ResultSet

getProductType(pid)

calcRecognitions(cid)

insert(cid, revenue/3, date)

insert(cid, revenue/3, date+60)

insert(cid, revenue/3 date+90)

getRevenue()

getDateSigned()

return result

DB

SELECT

SELECT

INSERT

INSERT

INSERT

Page 27: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

recognizedRevenue(c_id, date)

getAmount()

TM: Sequence Diagram: recognizedRevenue()

:RevenueRecognition:Tester

recognitions:ResultSet

:Contract

getRecognitions(c_id, date)

getAmount()

getAmount()

return result

DB

SELECT

Page 28: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

Service Layer

Defines an application’s boundary with a layer of services that establishes a set of available operations and coordinates the application’s response in each operation. Two type of business logic

Domain logic: pure logic of the business domain E.g., calculating revenue recognitions of a contract

Application logic: application responsibilities E.g., notifying administrators and integrated

applications, of revenue recognition calculations

Page 29: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

TM: Example - Modules

Domain Model

Service Layer

Data Loader

DB

User Interfaces

Integration

Gateways

Page 30: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

SL: Architecture

Domain logic: Domain model layer Application logic: Service layer Service layer:

Operation Scripts – A set of classes that implement application logic but delegate to domain model classes for domain logic.

Clients interact with the operation scripts Operation scripts for a subject area are

encapsulated in a class named SubjectService.

Page 31: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

SL: Services and Operations Determined by the needs of clients Derived from use case models

Data validation CRUD operations on domain objects Notification of people or other integrated

applications All responses must be coordinated and

transacted automatically by the service layer

Page 32: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

SL: When to Use It

When there are many different kinds of clients

When the response may involve application logic that needs to be transacted across multiple transactional resources

Page 33: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

SL: Example

Revenue Recognition New requirements: once revenue

recognitions are calculated, it must Email a notification to contract

administrators Publish a message to notify other

integrated applications

Page 34: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

SL: Example

RecognitionServicecalcRevenueRecogs(contr#)recognizedRevenue(contr#, date)

ApplicationService

EmailGateway

sendEmail(toAddr, subj, body)

getEmailGateway(): EmailGatewaygetIntegrationGateway(): IntegrationGateway

IntegrationGateway

publishRevenueRecogs(contract)

Contract ProductRevenueRecognition

Domain Model

Page 35: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

SL: Exampleclass RecognitionService extends ApplicationService { public void calcRevenueRecogs(contractNo) { Transaction trans = Transaction.getNewTransaction(); trans.begin();

// delegate to domain objects Contract contract = Contract.getContract(contractNo); contract.calcRecognitions(); Contract c2 = new Contract(calc, 24000, today);

// interact with transactional sources getEmailGateway().sendEmail(contract.getAdminEmail(), “RE: contract revenue recognitions”, contract.getId() +”Recognitions calculated”); getIntegrationGateway().publishRevenueRecogs(contract);

trans.commit(); }}

Page 36: Domain Logic Patterns  Transaction Script  Domain Model  Table Module  Service Layer

Domain Logic: Summary

Transaction Script One script per user request/action Good for simple, no-overlapping business logic

Domain Model A set of interrelated objects for business logic Good for application with complex business logic

Table Module A module for the CRUD operations and business logic for a

table in DB Compromise between Transaction Script and Domain Model

Service Layer Application logic is separated into a new layer from domain

logic Good for applications that have complex application logic –

interacting with multiple transactional resources