|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
OOP Best Practices Part 2I read Sloans post in my last thread but I did not quite understand it.
I have written my own custom object BASED around sloans object that he posted. Can anyone answer the questions at http://thedogsatonthemat.com/viewtopic.php?t=21 ? (I put it in my forum so the code is cleaner. You can reply here instead of on the forum). I also have a question regarding static vs intiated DALS. <vze1r***@verizon.net> wrote in message
Show quote news:1148389412.021084.239150@y43g2000cwc.googlegroups.com... Yes. Seperation of concerns militates for seperating them. UserManager >I read Sloans post in my last thread but I did not quite understand it. > > I have written my own custom object BASED around sloans object that he > posted. > > Can anyone answer the questions at > http://thedogsatonthemat.com/viewtopic.php?t=21 ? > (I put it in my forum so the code is cleaner. You can reply here > instead of on the forum). > > > I also have a question regarding static vs intiated DALS. > >Couple of questions about this OOP design: > >1) Is it really neccessary to have UserManager? Could I not integrate >UserManager methods/properties in the User >class or UserCollection class >(UsersForCar would probably go in class Car right?)? Would doing that ruin >proper OOP >design? Performance? contains all your grungy database code, and squarely in the "back end" of your application. User and UserCollection are used across all tiers of your application. >2) How about performance? When you get a Car's users, you hit the DB twice. Managing performance is a challenge in this design, and it's another point >Once to get the User IDs for a car, >then the second to load each user. How >ever....I could instead load the user object and its properties directly > >inside the GetUsersForCar method which results in only one DB hit. The bad >thing is....if I wanted to load One User >object only..then I would have to >write LoadData logic for the User object. in favor of a consolidated data access layer (UserManager). In UserManager you have the option of retrieving and updating related tables in optimized ways, instead of always sending a single database query for each entity on load an update. >3) Is this design good? It implements lazy load design for the Cars Users You have to manage these tradeoffs based on the use cases for your different >property because it only loads if needed. >Would this be bad performance >wise vs SQL returning multiple result sets for multiple collection loading >(etc >UserCollection for cars) objects. >4) When does these methods go?? Like should GetUsersForCar be in the Implemented in UserManager, invoked from Car perhaps.>UserManager object or Car object??? >5) Is there some parts I could centralize?? I don't understand what you mean.>6) Should ID (like User ID) be Id or ID? I know silly question and I know Personal preference.>the answer is Id...but I feel like using >ID. Bad Naming convention? >I really like this idea of True OOP binding instead of DataTables/DataSets First, the typed DataSet avoids late binding, and has the integrated >but I'm really worried about performance >overall. The SQL Server will >prolly get hit bad if say 25 users were to load the car object and query >the Users >property (thats 25 x 2 = 50 hits compared to 25 hits with >DataTable) but I hate binding with the DataTable. TableAdapter framework, so it's quite attractive. But there's no reason why your approach should suffer poor performance. The DataSet will have to issue multiple SELECT's for multiple DataTables too. IMO one of the most attractive features of your approach is that you can use nullable types in your entities, and have excelent type-fidelity between your entities and database tables. David
Show quote
"David Browne" <davidbaxterbrowne no potted m***@hotmail.com> wrote in I agree - basically what Dave is saying is that Users and UserCollections news:#LzquwmfGHA.4172@TK2MSFTNGP04.phx.gbl: >>Couple of questions about this OOP design: >> >>1) Is it really neccessary to have UserManager? Could I not integrate >>UserManager methods/properties in the User >class or UserCollection >>class (UsersForCar would probably go in class Car right?)? Would doing >>that ruin proper OOP >design? Performance? > > Yes. Seperation of concerns militates for seperating them. > UserManager contains all your grungy database code, and squarely in > the "back end" of your application. User and UserCollection are used > across all tiers of your application. maybe sent across a network to different locations. i.e. a web service /remoting might return a UserCollection thus you don't want to put any DB logic into the UserCollection object since it may not have access to the DB. Furthermore, centralizing your logic into a manager class allows you to check for access security in one spot rather than across all your objects (if you don't have access, you can't call getUsers) ; ) Your User object and your UserCollection object are the objects which should
be able to be passed around.... You don't want the baggage of the database code following that around. Thus the use of the UserManager class. You should be able to create User's and UserCollection's without any dependance upon the database. It just so happens that one primary way to create them and use them it via database access. But this isn't always the only way. Thus the seperation of this code into its own class. ......... //quote Is it really neccessary to have UserManager? // end quote I have the same arguments with people I work with all the time. Objects are a collection of properties/methods and sometimes Events. The code which creates them from the db, does not need to be in the objects themselves. You're making a bad decision at the beginning of your design process if you do so. ... //quote When you get a Car's users, you hit the DB twice. //end quote You shouln't need to hit the db twice. You need to write a stored procedure to bring back all germane data in one procedure. Your issue is that you're using inline sql. Look at my post about a multi-recordset stored procedure, and NextResult(). //quote static class UserManager { public static UserCollection GetUsers() { UserCollection collection = new UserCollection(); string sql = "SELECT * FROM Users"; SqlDataReader reader = _dal.ExecuteReader(sql); while(reader.Read()) { User user = new User( Conversions.DBToInt(reader["userID"]) ); collection.Add(user); } return collection; } public static UserCollection GetUsersForCar() { //implement logic for Car's Users. Just like above. } } //end quote You have your datalayer and biz layer intertwined. _dal is NOT your datalayer. It is a HELPER class, which you datalayer should take advantage of, but it does NOT substitute for a DataLayer object. You need to relook at my examples. You're making a common mistake of intertwining biz and datalayer code. There should be some object Data.UserData and all this thing does is return IDataReaders and DataSets. THAT's ALL IT SHOULD DO. It can use your helper class , _dal, but it is its own object. The biz layer will instantiate, can call some method on the UserData object, to get a IDataReader. Then your .SerializeUsers (IDataReader idr) code will be called to create a collection. ... You keep taking the advice people are giving you , and then you try to abbreviate it, take shortcuts. We can lead you to water, but we can't make you drink. .............. Fyi, I call strongly typed datasets, the "poor mans business objects". You can use them, they're good, but it depends on what your building. When I build a good sized architectural solution, I always prefer strong objects and collectionbases over typed datasets. The performance of using a IDataReader (to populate a custom collection) over a dataset (typed or untyped) has always favored the IDataReader approach in my tests. Again, for good sized architecture solutions, this is a 'up front' decision which pays dividends down the road. If you ever have to go to remoting, you're already got well designed classes/collectionbases to work from. Thanks David, "Spam Catcher", and/or Bruno for your followup responses. ... Show quote "Spam Catcher" <spamhoneypot@rogers.com> wrote in message news:Xns97CC6AD942CBEusenethoneypotrogers@127.0.0.1... > "David Browne" <davidbaxterbrowne no potted m***@hotmail.com> wrote in > news:#LzquwmfGHA.4172@TK2MSFTNGP04.phx.gbl: > > >>Couple of questions about this OOP design: > >> > >>1) Is it really neccessary to have UserManager? Could I not integrate > >>UserManager methods/properties in the User >class or UserCollection > >>class (UsersForCar would probably go in class Car right?)? Would doing > >>that ruin proper OOP >design? Performance? > > > > Yes. Seperation of concerns militates for seperating them. > > UserManager contains all your grungy database code, and squarely in > > the "back end" of your application. User and UserCollection are used > > across all tiers of your application. > > I agree - basically what Dave is saying is that Users and UserCollections > maybe sent across a network to different locations. i.e. a web service > /remoting might return a UserCollection thus you don't want to put any DB > logic into the UserCollection object since it may not have access to the > DB. > > Furthermore, centralizing your logic into a manager class allows you to > check for access security in one spot rather than across all your objects > (if you don't have access, you can't call getUsers) ; ) I'm not sure I still get it.
Could you provide a full example that is related to my example? User/Car etc. I really appreciat your help. I will work up a NorthWind example over the next 2 days, and post it at my
blog (and the link here if I can find the post). Check with me after 3 days. if its not there. ... <vze1r***@verizon.net> wrote in message Show quote news:1148412354.928826.240040@38g2000cwa.googlegroups.com... > I'm not sure I still get it. > > Could you provide a full example that is related to my example? > User/Car etc. > > I really appreciat your help. > Ok thanks a bunch...just dont use the pubstitle metholody...its so
confusing. I think a better would be UserCollection etc
http://spaces.msn.com/sholliday/ 5/24/2006 entry
a "PubsTitle" is simply a title in the pubs database. Basically, select * from pubs.dbo.titles .. each row from that query is a "PubsTitle" And there was a PubsTitleCollection. Yeah, it wasn't the best naming convention, but it wasn't ~that far fetched. email me for my paypal account name, so you know where to put my consultant fee (ha ha). ... <vze1r***@verizon.net> wrote in message Show quote news:1148419508.040351.222910@y43g2000cwc.googlegroups.com... > Ok thanks a bunch...just dont use the pubstitle metholody...its so > confusing. > > I think a better would be UserCollection etc > <vze1r***@verizon.net> wrote in message
news:1148389412.021084.239150@y43g2000cwc.googlegroups.com... Regarding the UserManager question:>I read Sloans post in my last thread but I did not quite understand it. > > I have written my own custom object BASED around sloans object that he > posted. > > Can anyone answer the questions at > http://thedogsatonthemat.com/viewtopic.php?t=21 ? > (I put it in my forum so the code is cleaner. You can reply here > instead of on the forum). I would move the GetXXX functions into the corresponding classes. There's also a question whether there isn't a Singleton hiding in there from the SQL query it looks like there's only one user collection. Or are there more tables or DBs? In that case perhaps a class that contains the DB access is more appropriate. Here's a link to part of the old Taligent C++/OO documentation ("Managers are not objects"). I've never convinced myself that all managers are bad objects but the fact that you already have doubts about the validity of the UserManager you might get some ideas out of it: http://www.cubik.org/mirrors/taligent/Docs/books/WM/WM_47.html#HEADING61 Also, the fact that your UserManger has only static methods indicates that it is a namespace in disguise. But where does the _dal variable come from, looks like a member but it is in a static function of a static class? Andrew |
|||||||||||||||||||||||