Hi Lee,
First of all, thanks for your excellent comments!
Regarding your AbstractDataObjectProvider comment, there are a few things I wish I made a bit more explicit in my book. I think you are quite right in suggesting Provider property could be accessed from concrete Datas.
Iâm introducing refactorings gradually in the book. In Chapter 10 I mostly discuss inheritance, genericity, polymorphism and apply those to Rent-a-Wheels at the end of the chapter. I continue to evolve Rent-a-Wheels in future chapters, so what you have seen is not final version of Rent-a-Wheels.
I go over the provider model again in Chapter 12. In Chapter 12 I talk about design patterns and I thought it appropriate to use the data provider example in the context of Abstract Factory design pattern.
Even so, there is raison dâêtre for AbstractDataObjectProvider in Chapter 10 and in context of design offered in that chapter. As I mention, using the AbstractDataObjectProvider I am able to remove the dependency of AbstractData from any specific provider. As a result, if I need to write any concrete Data using some other provider, I will still be able to inherit AbstractData. Had I left dependency on MsSql data provider in AbstractData, I would not be able to reuse(inherit) AbstractData when writing OracleBranchData for example.
I think your comment on making the Provider property in AbstractData public (or protected) is spot on. That way, I would remove the duplicated code instantiating different provider objects from concrete datas. I am not so sure about removing dependency of concrete Datas on specific provider.
Concrete Datas, like BranchData for example, still depend on specific provider but it is so "by design". In the design I demonstrate in Chapter 10, you access other databases by implementing specific Datas, for example OracleBranchData, OracleCategoriesData etc. This is in a way a brute-force approach, but sometimes it can be more appropriate than trying to make your SQL code db-agnostic. If you take a look at BranchData and other concrete Datas code, you will see that bulk of the code is embedded SQL. While you use embedded SQL (opposed to ORM for example), I think this approach is a valid option. As is trying to make your SQL code db-agnostic. As long as your SQL is very simple (as is in Rent-a-Wheels) you might be more productive by making your concrete Datas db-agnostic. When embedded SQL starts to be more complex, making SQL db-agnostic becomes quite tedious⦠In chapter 13 I use ORM to replace the whole roll-your-own data layer.
Thanks again for your feedback, and please keep them coming!
Danijel
Quote:
Originally Posted by Lee Dumond
I am somewhat disappointed in how the author demonstrates implementing the data provider model at the end of Chapter 10.
If you aren't going to use an instance of the provider in the concrete implementations, why bother? What exactly is the point?
Yes, you've made the base class database agnostic, but you haven't made the implementations agnostic at all. All of the concrete classes (BranchData, CategoryData, etc.) still contain references to SqlClient and still have MS-SQL objects all over the place. This isn't how a data provider model is supposed to work.
Making the Provider property public in AbstractData<Persisted> lets the inheriting classes create an instance of it in the constructor parameter, and then use that instance's methods to create connections, commands, adapters, etc... instead of using the SqlClient objects. Unless you do that, seems to me that creating the provider in the first place is a completely pointless exercise.
|