Search code examples
.netarchitecturebusiness-logicapplication-server

How to split a data layer and business object layer, what are the appropriate duties of each?


If there was a line of business application layered like this, would this be an appropriate division of labor :

Data Access

  • Invokes only stored procedures, maps properties of DTOs to a hash tablse which are used to populate ADO.NET command's parameter collections.

  • Only assembly with reference to SqlDataClient.

  • Significant logic dealing with what means blank, null, and empty in the mapping code, but other wise no validation or other domain specific logic.

So-Called Business Logic

  • splits multiple result sets into individual DataTables, e.g.

    public void ReturnNthRecordSetFromStoredProcFoo()

  • pass through to data access for datasets, e.g.

    public void ReturnDataSet(string name){ return (new PersonController).GetAnotherDataSet(name);}

  • maps one row of a DataTable to one DTOs

  • Significant logic dealing with what means blank, null, and empty in the mapping code.
  • Holds transaction object, although it is used exclusively to wrap single stored procedure calls.
  • Doesn't have a reference to SqlDataClient, so it can't use SqlDataReaders to fill DTOs
  • No reference to System.Web.UI
  • Authorization rules, but otherwise no domain specific logic.

UI

  • 2 way data binding of DTOs to ASP.NET forms.
  • Validation of properties of controls- generally no validation directly against DTOs
  • "Collections" are navigated by binding DataSets to grids. In fact attempting to do anything with collections requires the UI to iterate over DataRows in DataTables and know what the appropriate column names are (which are generally only kind-of-similar to the DTOs)

So the question, finally-- with this application, should the Data Access Layer assume the the duties of the so-called business layer be merged? Isn't this already a two layer, (almost one!) application except for the inconvenience of an extra assembly?

Additional info: Ok, I already know that the application server will be one machine, probably forever, since it is an low-user-count intranet app. So I know not to design for physically separate application tiers. Also, it will probably only support one UI and be entirely scrapped if it ever need to support something other than ASP.NET-- another oft quoted reason for tiers/layers.


Solution

  • It sounds to me that the responsibility between tiers is a little muddled. The data layer sounds fairly standard. The ("so-called") business layer is the place where things get muddled.

    Some thoughts on the Business Layer:

    • There seems to be a lot of data representations. You mention DataTables, DataSets, Data Transfer Objects. A standard approach across the entire application would be better.

    • Business layer methods with names like ReturnNthRecordSetFromStoredProcFoo and ReturnDataSet are not meaningful and do not provide an appropriate level of abstraction for business services. (Maybe those were just poorly chosen examples not from the application?)

    • Typically a business layer would provide more than a DataSet pass through. Instead of dealing with mappings, nulls etc. the business layer should focus on validation, business rules, security, and maybe even auditing (although some prefer to do that in the database).

    • Even though the business layer is only invoking a single stored procedure, I have no problem with the transaction control in the business layer. Business layer should control the transaction so that multiple data objects can all participate in the same transaction (it could even be across different databases). Even though there is only one call now, if you ever need to add more calls in the future this will be easy and will not result in retrofitting transaction control into your application.

    • I think the dependencies are OK -- no reference to the Web.UI or SQLClient from the business layer.

    • Authorization rules are also OK. I would expand to include Security and not just authorization. Also, I don't see any business logic anywhere -- just curious if the business logic is in the stored procedures? If I was going to guess, I would say yes given that each business method invokes only one stored procedure. If so, then that is a big no no for me.


    I would not combine the business and data layers. I prefer to keep the business logic layer and the data access layer separate. Given a choice between combining them and trying to separate the responsibilities a little more I would lean toward the latter.

    However, seeing as though this is an existing application with issues I would take a more pragmatic point of view. Everything comes with a cost and it is important to determine what changes are being made, what is the effort and risk of the changes, what is the real benefit of the changes, and how the changes will impact on the testing cycle.

    Some other questions to think about are: what are the main issues you want to address? Are they functional (e.g. bugs, lack of stability)? Or performance related? Or is it architectural? Or perhaps related to maintainability -- do you need to add new functionality but are finding it difficult? Do you have a time frame or a budget? If you can answer some of those questions it might help guide you.