Wrox Programmer Forums
|
BOOK: Professional Refactoring in C# & ASP.NET
This is the forum to discuss the Wrox book Professional Refactoring in C# & ASP.NET by Danijel Arsenovski; ISBN: 9780470434529
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Professional Refactoring in C# & ASP.NET section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old September 25th, 2009, 02:27 PM
Lee Dumond's Avatar
Wrox Author
 
Join Date: Jan 2008
Posts: 923
Thanks: 12
Thanked 166 Times in 162 Posts
Default AbstractDataObjectsProvider

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.
__________________
Visit my blog at http://leedumond.com
Follow me on Twitter: http://twitter.com/LeeDumond

Code:
if (this.PostHelpedYou)
{
   ClickThanksButton(); 
}
 
Old September 28th, 2009, 06:23 PM
Wrox Author
 
Join Date: Apr 2008
Posts: 13
Thanks: 1
Thanked 1 Time in 1 Post
Default AbstractDataObjectProvider does serve a purpose

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 View Post
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.
__________________
http://blog.refactoringin.net
"Empowering your team for agile transition"
The Following User Says Thank You to Danijel For This Useful Post:
Lee Dumond (October 1st, 2009)
 
Old September 28th, 2009, 07:06 PM
Lee Dumond's Avatar
Wrox Author
 
Join Date: Jan 2008
Posts: 923
Thanks: 12
Thanked 166 Times in 162 Posts
Default

Thanks for your response Danijel,

I have just finished Chapter 11 and I'm still seeing some smells... a fair amount of duplication, classes with no behavior (in the business layer), etc. But I am holding out until after finishing Chapters 12 and 13 until I pass judgement on these. ;)

The failure to fully implement the provider you introduced in Chapter 10 still bothers me a little, but I can kind of see the rationale behind it now that you've explained it.

The other thing that really sticks out to me is that the way the application is "layered", namely, the dependency between the GUI and the Data parts. Having the GUI talking directly to the Data layer bothers me. ;) I would have considered including behaviors in the business classes that call into the Data layer, and then let the GUI talk to the business layer only. For example, have Delete, Insert, Update, etc. methods in Branch.cs that call corresponding methods in BranchData. That way, you remove the dependency between GUI and Data, and GUI and Data.Implementation; and you make Business depend on Data.Implementation instead of the other way around.

But again, I need to make more progress in the book before I can really offer an informed opinion.

P.S. One other thing I would point out is that it's farily standard practice to start Generic parameters with the letter T (like <TPersisted> or <TMaintained>) and I notice you don't do that, which was slightly confusing at first. ;)
__________________
Visit my blog at http://leedumond.com
Follow me on Twitter: http://twitter.com/LeeDumond

Code:
if (this.PostHelpedYou)
{
   ClickThanksButton(); 
}









Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.