ENTERPRISE APPLICATION ARCHITECTURE Domain Logic Patterns Transaction Script

  • Slides: 36
Download presentation
ENTERPRISE APPLICATION ARCHITECTURE

ENTERPRISE APPLICATION ARCHITECTURE

Domain Logic Patterns Transaction Script Domain Model Table Module Service Layer

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

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

TS: How It Works Each business transaction corresponds to one transaction script Business transaction:

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 Book. ARoom 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.

TS: Architecture Transaction. Script business. Transaction 1() business. Transaction 2() business. Transaction 3() Gateway

TS: Architecture Transaction. Script business. Transaction 1() business. Transaction 2() business. Transaction 3() Gateway sql_query= “ SELECT * FROM table 1…” sql_insert = “INSERT into tablei…” sql_update = “ UPDATE tablei …” sql_delete = “DELETE FROM …” find. Data. For. Business. Transaction 1(sql_query) insert. Records. For. Business. Transaction 1(sql_insert, items) update. Records. For. Business. Transaction 2(sql_update, items) … DB

TS: When to use it When the domain logic is very simple When transactions

TS: When to use it When the domain logic is very simple When transactions do not have a lot of overlap in functionality

Example Revenue Recognition A contract is signed for one product The revenue of a

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 Name type 1 * Contract date _signed revenue 1 * Revenue. Recognition Amount date

TS: Example Recognition. Service calc. Recognitions(contract#) recognized. Revenue(contract#, date) create. Contract(id, revenue, prod_id, date)

TS: Example Recognition. Service calc. Recognitions(contract#) recognized. Revenue(contract#, date) create. Contract(id, revenue, prod_id, date) … Database. Gateway Sql_find. Contract = “ SELECT * FROM Contract WHERE id = ? ” Sql_find. Recogns = “select* from recog Where cid=? and date<? ” Sql_insert. Contract = “INSERT into contract…” find. Contract(contract#) find. Recognitions. For(contract#, date) insert. Recognition(contract#, revenue, date) … DB

Sequence Diagram: test cases : Tester : Recognition. Servi ce : Database. Gatew ay

Sequence Diagram: test cases : Tester : Recognition. Servi ce : Database. Gatew ay : Database create. Contract() insert. Contract() INSERT into contract … calc. Recognitions() insert. Recognition() INSERT iinto Recog… recognized. Revenue() find. Recognitions. For() SELECT * FROM …

TS: Example class Gateway { static String find. Recogns = “SELECT * FROM revenue.

TS: Example class Gateway { static String find. Recogns = “SELECT * FROM revenue. Recognition WHERE contract = ? And date <= ? ”; static String find. Contract = “SELECT * FROM contract c, product p WHERE c. id = ? And c. pid = p. id”; public Result. Set find. Recognitions. For(int contrno, Date d) { Prepared. Statement s = db. prepare. Statement(find. Recongs); s. set. Int(1, contrno); s. set. Date(2, d); Result. Set result = s. execute. Query(); return result; } public Result. Set find. Contract(int contrno) { Prepared. Statement s = db. prepare. Statement(find. Contract); s. set. Int(1, contrno); Result. Set result = s. execute. Query(); return result; } }

TS: Example class Recognition. Service { private Gateway gw = new Gateway(); public Money

TS: Example class Recognition. Service { private Gateway gw = new Gateway(); public Money recognized. Revenue(int contrno, Date d) { Money Result = Money. dollar(0); Result. Set rs = gw. find. Recognitions. For(contrno, d); while (rs. next()) { result = result. add(rs. get. Big. Decimal(“amount”)); } return result; } public void calculate. Revenue. Recognitions(int contrno) { Result. Set contrs = gw. find. Contract(contrno); total. Revenue = contrs. get. Big. Decimal(“revenue”); dates = contrs. get. Date(“date_signed”); type = contrs. get. Char(“type”); if (type == ‘S’) { db. insert. Recognition(contrno, total. Revenue/3, date); db. insert. Recognition(contrno, total. Revenue/3, date+60); db. insert. Recognition(contrno, total. Revenue/3, date+90); } else if (type = ‘W’) { db. insert. Recognition(contrno, total. Revenue, date); } else if (type == ‘D’ {. . . }. . .

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

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

DM: Revenue Recognition Contract date _signed revenue recognized. Revenue(date) calculate. Recognitions() * 1 Product

DM: Revenue Recognition Contract date _signed revenue recognized. Revenue(date) calculate. Recognitions() * 1 Product Name type calc. Recognitions(contrct) * 1 Recognition. Strategy calc. Recognitions(contrct) 1 * Revenue. Recognition Amount date is. Recognizable. By(date) DB Three-way Recognition. Strategy Complete Recognition. Strategy

DM: Example class Revenue. Recognition { private Money amount; private Date date; public Revenue.

DM: Example class Revenue. Recognition { private Money amount; private Date date; public Revenue. Recognition(Money amnt, Date d) {. . . } public Money get. Amount() { return amount; } public boolean is. Recognizable. By(Date date) { return this. date. before(date) || this. date. equals(date); }. . . } class Contract { private List revenue. Recognitions = new Array. List(); public Money recognized. Revenue(Date date) { Money result = Money. dollar(0); Iterator it = revenue. Recognitions. iterator(); while (it. has. Next()} { Revenue. Recognition r = (Revenue. Recognition)it. next(); if (r. is. Recognizable. By(date)) result = result. add(r. get. Amount()); } return result; }. . .

DM: Example class Revenue. Recognition { private Money amount; private Date date; public Revenue.

DM: Example class Revenue. Recognition { private Money amount; private Date date; public Revenue. Recognition(Money amnt, Date d) {. . . } public Money get. Amount() { return amount; } public boolean is. Recognizable. By(Date date) { return this. date. before(date) || this. date. equals(date); }. . . } class Contract { private List revenue. Recognitions = new Array. List(); public Money recognized. Revenue(Date date) { Money result = Money. dollar(0); Iterator it = revenue. Recognitions. iterator(); while (it. has. Next()} { Revenue. Recognition r = (Revenue. Recognition)it. next(); if (r. is. Recognizable. By(date)) result = result. add(r. get. Amount()); } return result; }. . .

DM: Example class Contract { private Product product; private Money amount; private Date date.

DM: Example class Contract { private Product product; private Money amount; private Date date. Signed; private long id; public Contract(Product p, Money amnt, Date d) {. . . } public void add. Recognition(Revenue. Recognition rr) { revenue. Recognitions. add(rr); } public Date get. Date. Signed() { return date. Signed; } public void calc. Recognitions() { product. calc. Recognitions(this); }. . . } interface Recognition. Strategy { public void calc. Revenue. Recognitions(Contract c); }

DM: Example class Complete. Recognition. Strategy implements. . . { public void calc. Revenue.

DM: Example class Complete. Recognition. Strategy implements. . . { public void calc. Revenue. Recognitions(Contract c) { c. add. Recognition(new Revenue. Recognition( c. get. Amount(), c. get. Date. Signed()); } } class Three. Way. Recognition. Strategy implements. . . { private int first. Recognition. Offset; private int second. Recognition. Offset; public Three. Way. Recognition. Strategy(int offset 1, int offset 2) { this. first. Recognition. Offset = offset 1; this. second. Recognition. Offset = offset 2; } public void calc. Revenue. Recognitions(Contract c) { c. add. Recognition(new Revenue. Recognition( c. get. Amount()/3, c. get. Date. Signed()); c. add. Recognition(new Revenue. Recognition( c. get. Amount()/3, c. get. Date. Signed()+offset 1); c. add. Recognition(new Revenue. Recognition( c. get. Amount()/3, c. get. Date. Signed()+offset 2); }. . . }

DM: Example class Product { private String name; private Recognition. Strategy recog. Strategy; public

DM: Example class Product { private String name; private Recognition. Strategy recog. Strategy; public Product(String name, Recognition. Strategy rs) { this. name = name; this. recog. Strategy = rs; } public void calc. Recognitions(Contract c) { recog. Strategy. calc. Recognitions(c); } public static Product new. Word. Processor(String name) { return new Product(name, new Complete. Recognition. Strategy()); } public static Product new. Spreadsheet(String name) { return new Product(name, new Three. Way. Recognition. Strategy(60, 90)); } public static Product new. Database(String name) { return new Product(name, new Three. Way. Recognition. Strategy(30, 60)); } }

DM: Example class Tester { public static void main(String[] args) { Product word =

DM: Example class Tester { public static void main(String[] args) { Product word = Product. new. Word. Processor(“Intel. Word”); Product calc = Product. new. Spreadsheet(“calc II”); Product db = Product. new. Databse(“DB IV”); Date today = System. today(); Contract c 1 = new Contract(word, 300000, today); c 1. calc. Recognitions(); Contract c 2 = new Contract(calc, 24000, today); c 2. calc. Recognitions(); // sequence diagram – next slide Contract c 3 = new Contract(db, 540000, today); c 3. calc. Recognitions(); System. out. println(c 1. recognized. Revenue(today + 10)); System. out. println(c 2. recognized. Revenue(today + 70)); System. out. println(c 3. recognized. Revenue(today + 80)); } }

DM: Sequence Diagram: c 2. calc. Recognitions() : Tester c 2. : Contract recog.

DM: Sequence Diagram: c 2. calc. Recognitions() : Tester c 2. : Contract recog. Strategy: Recognition. Str ategy product: Product calc. Recognitions() calc. Recognitions(c 2) Mount = get. Amount() date = get. Date. Signed() (amount/3, date) rr 1: Revenue. Recogniti on add. Recognition(rr 1) (amount/3, date + 60) rr 2: Revenue. Recogniti on add. Recognition(rr 2) (amount/3, date + 90) add. Recognition(rr 3) rr 3: Revenue. Recogniti on

DM: Sequence Diagram: c 2. recognized. Revenue() : Tester c 2. : Contract recognized.

DM: Sequence Diagram: c 2. recognized. Revenue() : Tester c 2. : Contract recognized. Revenue(date) rr[0]: Revenue. Recognit ion is. Recognizable. By(date) get. Amount() is. Recognizable. By(date) return result rr[1]: Revenue. Recognit ion rr[2]: Revenue. Recognit ion

Table Module A single instance that handles the business logic for all rows in

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.

TM: Architecture Table. Module_1 CRUD operations on Table_1 Business Logic related to Table_1 Table.

TM: Architecture Table. Module_1 CRUD operations on Table_1 Business Logic related to Table_1 Table. Module_2 CRUD operations on Table_2 Business Logic related to Table_2 Table_1 Attributes Table_2 Attributes Database Table. Module_n CRUD operations on Table_n Business Logic related to Table_n Attributes

TM: Example - Tables Contract Id: date. Signed: revenue: prod_id: Number Date Number (FK)

TM: Example - Tables Contract Id: date. Signed: revenue: prod_id: Number Date Number (FK) Revenue. Recognition Id: amount: date: c_id: Product Id: Number name: String type: String Number Date Number (FK)

TM: Example - Modules Contract Revenue. Recognition Insert(cid, revenue, prod_id, date) calculate. Recognitions(c_id) Insert(c_id,

TM: Example - Modules Contract Revenue. Recognition Insert(cid, revenue, prod_id, date) calculate. Recognitions(c_id) Insert(c_id, amount, date) recognized. Revenue(c_id, date) Product get. Product. Type(prod_id) DB

TM: Sequence Diagram: calc. Recognitions() : Tester : Revenue. Recognitio n : Contract :

TM: Sequence Diagram: calc. Recognitions() : Tester : Revenue. Recognitio n : Contract : Product calc. Recognitions(cid) get. Contract(id) contract: Result. S et DB SELECT get. Product. ID() get. Product. Type(pid) SELECT get. Revenue() get. Date. Signed() return result insert(cid, revenue/3, date) INSERT insert(cid, revenue/3, date+60) INSERT insert(cid, revenue/3 date+90) INSERT

TM: Sequence Diagram: recognized. Revenue() : Tester : Revenue. Recognitio n : Contract recognized.

TM: Sequence Diagram: recognized. Revenue() : Tester : Revenue. Recognitio n : Contract recognized. Revenue(c_id, date) get. Recognitions(c_id, date) recognitions: Result. S et get. Amount() return result DB SELECT

Service Layer Defines an application’s boundary with a layer of services that establishes a

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

TM: Example - Modules Data Loader Integration Gateways Service Layer Domain Model DB User

TM: Example - Modules Data Loader Integration Gateways Service Layer Domain Model DB User Interfaces

SL: Architecture Domain logic: Domain model layer Application logic: Service layer: Operation Scripts –

SL: Architecture Domain logic: Domain model layer Application logic: 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 Subject. Service.

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

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

SL: When to Use It When there are many different kinds of clients When

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

SL: Example Revenue Recognition New requirements: once revenue recognitions are calculated, it must �Email

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

SL: Example Application. Service get. Email. Gateway(): Email. Gateway get. Integration. Gateway(): Integration. Gateway

SL: Example Application. Service get. Email. Gateway(): Email. Gateway get. Integration. Gateway(): Integration. Gateway Email. Gateway Integration. Gateway send. Email(to. Addr, subj, body) publish. Revenue. Recogs(contract) Recognition. Service calc. Revenue. Recogs(contr#) recognized. Revenue(contr#, date) Domain Model Contract Revenue. Recognition Product

SL: Example class Recognition. Service extends Application. Service { public void calc. Revenue. Recogs(contract.

SL: Example class Recognition. Service extends Application. Service { public void calc. Revenue. Recogs(contract. No) { Transaction trans = Transaction. get. New. Transaction(); trans. begin(); // delegate to domain objects Contract contract = Contract. get. Contract(contract. No); contract. calc. Recognitions(); Contract c 2 = new Contract(calc, 24000, today); // interact with transactional sources get. Email. Gateway(). send. Email(contract. get. Admin. Email(), “RE: contract revenue recognitions”, contract. get. Id() +”Recognitions calculated”); get. Integration. Gateway(). publish. Revenue. Recogs(contract); trans. commit(); } }

Domain Logic: Summary Transaction Script One script per user request/action Good for simple, no-overlapping

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