For the design problem, I've reached two diverging paths. In one path, we use data access objects. There is a top level data access object which implements database read and write functions, (so select, insert, update, and delete). Then specific DAOs would extend this abstract DAO and override the r/w call with reference to the specific table. Ex: DataAccessObject has an update method, which takes table name, update parameters, and a where query to match the update with. Then CustomerDAO extends DataAccessObject and it's update function returns the super's update function with proper parameters filled in
public function update(params:Object):Promise {
return super.update("customer", params, "customer_id=:id", {id:uid});
}
This assumes every DAO has a uid property which references its SQL primary key. If we keep all database operations in the DatabaseProxy, then we have to write cases for every VO/DAO pair we will be working with. Finally the DatabaseProxy would be tasked with responding to the promises and updating the corresponding vo in memory.The second path, which I am leaning more towards, is not to implement a DAO pattern, but rather have the DatabaseProxy act as the top level DAO with abstract read/write functions. Then specific proxies would extend the DatabaseProxy with specific behavior. Does this violate the idea of isolating all DB interaction to the DatabaseProxy? This design seems better to me, because it still isolates the database dependency to the DatabaseProxy. Changing to a different style of database would require only rewriting the r/w functions in the DatabaseProxy. It also allows me to take advantage of a Proxy's data property. As an example if we had a database of books and publishers, these would likely be two different SQL tables. There would be a BooksProxy and a PublishersProxy. When the BooksProxy is instantiated, it would retrieve all books in the table and store them as an Array or ArrayCollection in the data property. Similarly for the PublishersProxy. Then adds, updates, and deletes would be saved to the DB and tracked in memory. This makes passing data to the view with a mediator much easier.
There's probably no right or wrong way to do this, but I appreciate all the input!