Show Menu
Cheatography

Good architecture and solution structure Cheat Sheet (DRAFT) by

Cheat sheet with checklist for good architecture and sound solution structure

This is a draft cheat sheet. It is a work in progress and is not finished yet.

DATABASE

Create tables with good names (singular and often similar to domain model class names)
Use good column names (singular, with only standard abbrev­iations in the names
Normalize DB to 3rd normal form
Add foreign key and unique constr­aints
Use IDENTITY (autog­ene­rated keys) on surrogate key columns
Implement robust cascading update­/delete choices on foreign key constr­aints for refere­ntial integrity
Add good denorm­ali­zation choices for speeding up working with the DB

DATA ACCESS LAYER

Add a DAO interface per database table with the CRUD actions needed
Add a concrete implem­ent­ation of each DAO interface (prefe­rably in a packag­e/n­ame­space that designates the persis­tence layer brand, i.e. MSSQL, MySQL, Oracle)
Add a DAO factory which can provide instances of the DAO classes for the contro­llers through static methods (e.g.
public static Custom­erDao getCus­tom­erDao()
)
Add a Dataco­ntext class with a static method which can provide a Connection object (e.g.
getObj­ect()
method) for use by the DAO classes
Add a unique database login (prefe­rable Active Directory account for Windows authen­tic­ation or non-SA for SQL logins) with only minimal permis­sions necessary (e.g. dbread­er/­dbw­riter) on the relevant DB/tables
 

MODEL LAYER

Mimic the database tables' structure with regards to naming and data types (often one model class per table)
Add a good toString() method to your model classes for debugg­ing­/vi­sua­lizing object state
Use good encaps­ulation (espec­ially of collec­tions) so you can change the underlying data structure without changing the interface
Code good constr­uctors which ensure you can't instan­tiate objects in an invalid state

DAO CLASSES SHOULD HAVE

a helper method for converting a single row in a ResultSet to an object
a helper method which converts an entire ResultSet to a List of objects reusing the above method
the 5 basic CRUD methods
 
getAll()
 
getByI­d(int id)
(or other name for key column,
getByS­SN(ssn)
, etc.)
 
insert­(model object)
 
update­(model object)
 
delete­(model object)
the extra "­cru­d" methods
 
`delet­eBy­Id(int id) (or other name for key column: delete­ByA­cco­unt­Number, etc.) - findBy­Par­tOf­Nam­e(S­tring partOf­Name) (or other searchable attribute)
 
findBy­Par­tOf­Nam­e(S­tring partOf­Name)
(or other searchable attribute)
transa­ctions wherever you need to do two or more operations as a unit: e.g.
 
read inventory count and place order if product is available
 
move assets (e.g. funds from one account to another)
 
update denorm­alized values (e.g. a number­OfLikes column, which stores the number of likes in the like table for fast access)
Proper transa­ction structure with a
 
beginT­ran­sac­tion()
(C#)/
setAut­oCo­mmi­t(f­alse)
(Java)
 
commit()
at the end of the "­try..."­ which contains the CRUD code
 
a
rollback()
in the "­cat­ch..."
 
any cleaning up (Conne­cti­on.s­et­Aut­oCo­mmi­t(f­alse), etc.) in the "­fin­all­y..."
Check for the number of rows affected on updates (UPDATE, INSERT, DELETE) and throw an Exception if necessary with a good exception message (e.g. "­Unknown error. Account number 354 was not delete­d.").
try-catch code which rethrows any exceptions that happen while intera­cting with the database, with a message about what was attempted when the exception happened plus the original exception.