Design Question: two libraries or one?

Design Question: two libraries or one?

Old forum URL: forums.lhotka.net/forums/t/1335.aspx


longbridge posted on Tuesday, September 26, 2006

Hi, I am developing a windows application using CSLA.NET2.0 and VS.Net2005.

 

It has two versions. One version stores/retrieves the data from remote Data Portal based on MSSQL Server, the other only use the local file as its storage.  The behaviors of business objects for these two versions are almost same. The differences only exist in the data access codes and criteria parts. So I am trying to unify them together into one library to make the high level data binding more convenient. I know I can use bunch of "if..else" to do it, but it is not a good design and will mess up the codes a lot. I also tried to use interfaces to abstract the behaviors of business object, but it seems the static factory functions can not be put into the interface directly. I am totally stucked there. Did anybody deal with similar problem before? Is there a good design pattern to sovle this? Thanks a lot.

Brian Criswell replied on Tuesday, September 26, 2006

I think what you want to look at is a Data Access layer (maybe NHibernate?).  One of the members who has used one or two data access layers will probably pipe in by tomorrow.  In essence, you want your business objects to call a single method to do a CRUD operation, and the data access layer should determine which data source you are currently targeting and perform the operation as appropriate.

RockfordLhotka replied on Tuesday, September 26, 2006

Or roll your own data access layer.

In that case, I'll look at an approach using data transfer objects (DTOs), with an interface-based API defining the DAL itself. So in a typical DataPortal_Fetch(...) you'd do something like this (for a Person class as an example):

Private Overloads Sub DataPortal_Fetch(ByVal criteria As Criteria)
  Dim dal As IDal = DalFactory.GetDal()
  Dim dto As PersonData = dal.GetPerson(criteria.Id)
  With dto
    _id = .Id
    _name = .Name
    _city = .City
    ' ...
  End With
End Sub

The DalFactory class would then be responsible for determining whether you should be using a local database or SQL Server (or whatever), and returning the appropriate type of IDal object.

Obviously there are variations on this theme, and I'm intentionally being overly simplistic here to illustrate the basic concept.

In the end, you'd probably have three assemblies:
  1. Business library
  2. DTO library
  3. DAL
Both the business library and DAL reference the DTO library. And the business library references the DAL as well.

The DAL assembly can be implemented in a couple ways. Either way, that assembly has IDal defined, along with the DalFactory class.

The DAL assembly might include both implementations of IDal, probably in two different namespaces. The DalFactory simply chooses the correct one to use.

Or the DAL assembly might only include IDal and DalFactory. You may have other assemblies for each actual DAL implementation - in which case those assemblies would reference the DAL assembly, and the DalFactory class would use dynamic assembly loading (provider pattern) to load the correct one.

BBM replied on Tuesday, September 26, 2006

Hi Rocky,

I have a similar problem, and your approach looks interesting.  However, I'm having trouble connecting the dots.  Could you expound some more on what the IDAL interface would look like and how a DTO works, or could you point me to some additional information?

Thanks.

BBM

longbridge replied on Wednesday, September 27, 2006

Thanks. Rocky. 

 In your design, does the DTO class only contain the data members of corresponding Business Object? And Each Business Object should have its own corresponding DTO class. Do I understand this right? Thanks.

longbridge replied on Wednesday, September 27, 2006

Hi, malloc1024. Through the link your gave, I found Plugin pattern might fit.

http://www.martinfowler.com/eaaCatalog/plugin.html

RockfordLhotka replied on Wednesday, September 27, 2006

longbridge:

Thanks. Rocky. 

 In your design, does the DTO class only contain the data members of corresponding Business Object? And Each Business Object should have its own corresponding DTO class. Do I understand this right? Thanks.



As I noted in my post, there are many variations on this theme, and I was describing the "simplest" in order to keep the discussion at a conceptual level.

While you can have one DTO per business object, you can also think of the DAL methods as being stored procedures, with the DTOs being the data set returned from the procedure. In that case, you could construct your DAL as an abstract data model - and in that case you might reuse a DTO across business objects, much like you might reuse a stored procedure across business objects if you are using ADO.NET directly.

Of course doing so would directly impose a level of coupling between the multiple business objects and their common DAL method/DTO definition - and that can lead to code that is harder to maintain.

It is a trade-off between writing more code vs writing less code, and increasing maintainability vs increasing coupling.

malloc1024 replied on Tuesday, September 26, 2006

Another option besides using DTO’s would be to use the Separated Interface pattern to create your DAL.  http://www.martinfowler.com/eaaCatalog/separatedInterface.html

Copyright (c) Marimer LLC