问题
I am in the middle of a "discussion" with a colleague about the best way to implement the data layer in a new application.
One viewpoint is that the data layer should be aware of business objects (our own classes that represent an entity), and be able to work with that object natively.
The opposing viewpoint is that the data layer should be object-agnostic, and purely handle simple data types (strings, bools, dates, etc.)
I can see that both approaches may be valid, but my own viewpoint is that I prefer the former. That way, if the data storage medium changes, the business layer doesn't (necessarily) have to change to accommodate the new data layer. It would therefore be a trivial thing to change from a SQL data store to a serialized xml filesystem store.
My colleague's point of view is that the data layer shouldn't have to know about object definitions, and that as long as the data is passed about appropriately, that is enough.
Now, I know that this is one of those questions that has the potential to start a religious war, but I'd appreciate any feedback from the community on how you approach such things.
TIA
回答1:
It really depends on your view of the world - I used to be in the uncoupled camp. The DAL was only there to supply data to the BAL - end of story.
With emerging technologies such as Linq to SQL and Entity Framework becoming a bit more popular, then the line between DAL and BAL have been blurred a bit. In L2S especially your DAL is quite tightly coupled to the Business objects as the object model has a 1-1 mapping to your database field.
Like anything in software development there is no right or wrong answer. You need to understand your requirements and future requirments and work from there. I would no more use a Ferrari on the Dakhar rally as I would a Range Rover on a track day.
回答2:
You can have both. Let data layer not know of your bussiness objects and make it capable of working with more than one type of data sources. If you supply a common interface (or an abstract class) for interacting with data, you can have different implementations for each type of data source. Factory pattern goes well here.
回答3:
An excellent book I have, which covers this topic, is Data Access Patterns, by Clifton Nock. It has got many good explanations and good ideas on how to decouple your business layer from the persistence layer. You really should give it a try. It's one of my favorite books.
回答4:
Jeffrey Palermo wrote a good post about this. He called it Onion Architecture.
回答5:
One trick I've found handy is to have my data layer be "collection agnostic". That is, whenever I want to return a list of objects from my data layer, I get the caller to pass in the list. So instead of this:
public IList<Foo> GetFoosById(int id) { ... }
I do this:
public void GetFoosById(IList<Foo> foos, int id) { ... }
This lets me pass in a plain old List if that's all I need, or a more intelligent implementation of IList<T> (like ObservableCollection<T>) if I plan to bind to it from the UI. This technique also lets me return stuff from the method like a ValidationResult containing an error message if one occurred.
This still means that my data layer knows about my object definitions, but it gives me one extra degree of flexibility.
回答6:
Check out Linq to SQL, if I were creating a new application right now I would consider relying on an entirely Linq based data layer.
Other than that I think it's good practise to de-couple data and logic as much as possible, but that isn't always practical. A pure separation between logic and data access makes joins and optimisations difficult, which is what makes Linq so powerful.
回答7:
In applications wherein we use NHibernate, the answer becomes "somewhere in between", in that, while the XML mapping definitions (they specify which table belongs to which object and which columns belong to which field, etc) are clearly in the business object tier.
They are passed to a generic data session manager which is not aware of any of the business objects; the only requirement is that the business objects passed to it for CRUD have to have a mapping file.
回答8:
Old post but searching for similar information I came across this which explains it nicely.
来源:https://stackoverflow.com/questions/10860/data-layer-best-practices