|
From: Mikeon on 6 Feb 2007 05:54 > Software engineering isn't about 'apply this pattern' or 'apply that > pattern', it's about solving problems. The thing you have to do is > solve a problem, not apply a pattern or two. If you don't understand > the pattern, don't apply it, it's as simple as that. You then go back > to your original problem and think of another solution. Actually I know what specification pattern is. In my opinion it is very good way to express a set of rules for filtering purposes. According to Jimmy Nilsson's book it should be possible to use "Yet another approach for querying is to use the Specification pattern " Next he writes: "Even those Specification classes could very well spit out IQuery ". IQuery is basically a Query Object. Question is how to spit the IQuery. And I mean implementation and not a 1000 meters abstract overview of what can or should or shouldn't be done. I appreciate your approach of trying to point me in a more generic way of thinking, but that I have already behind me on few projects. Now I'm focused on answering this "simple" question. Till now I have always used Query objects which I can translate to queries, but I have found Specification pattern to be more elegant way. > What's 'the specification pattern'? I now write professional software > for over 13 years, but I never heard of the specification patten until > this thread. Actually if you don't know what specification pattern is, you cannot answer my question in a way I need it :-( Don't get me wrong here, I don't know most of the other patterns, but I have read that it should be fairly "simple" to use Specifications as a query mechanism so I wonder how. And once again, I'm not trying to offend you, despite what you might think from my style of writing. I'm trying to emphasize my goal here. -- Michal
From: Mikeon on 6 Feb 2007 07:01 > Why would you want to use this, an o/r mapper has this build in > already, so just write the code in a repository if you want to and swap > repositories IF you ever want to swap o/r mappers. Because o/r mapper has its own way of expressing queries - mostly it is some kind of Query Object. I don't want to pollute my domain code with Query Objects since they are usually not strongly typed and reassemble the underlying datasource more or less. Currently I have 2 choices, either to go with MS SQL server and some kind of o/r mapper or use an object database: db4o. Db4o handles my problem natively i.e. they can analyze my code, get the usages specifications (native queries as they call them) and make more database friendly queries out of them. Non of the other o/r mappers I know of can do it automatically. I don't know which way I will go now. Until very late in the development I don't want to deal with persistance layer in any form. I abstract access to persistance in repositories. I use specifications to filter the results of queries. I won't decide on the persistance until very late in the project. Do you know of a better way to do it other than what I have described above? > Frankly, not a lot of people swap o/r mappers. Like there aren't many > people writing their code in such a way that they can swap out a > complete UI widget library on the spot, because 'you'll never know!'... I won't swap it either. It's just that I don't even want to chose one right now. > > > I'm aware that in .NET there are new features comming: expression > > trees in particular, that will solve my problem: i.e.: I know how to > > write SQL given expression tree. > > No, that won't solve your problem, because parsing that expression > tree is very complicated and unnecessary. Actually that would solve my concrete problem in a not efficient and not generic way. That is exactly why I'm asking my question in the first place. -- Michal
From: Frans Bouma on 7 Feb 2007 05:13 Mikeon wrote: > > Why would you want to use this, an o/r mapper has this > > build in already, so just write the code in a repository if you > > want to and swap repositories IF you ever want to swap o/r mappers. > > Because o/r mapper has its own way of expressing queries - mostly it > is some kind of Query Object. > I don't want to pollute my domain code with Query Objects since they > are usually not strongly typed and reassemble the underlying > datasource more or less. yes, though so does your code. A repository method GetCustomer, gets a .... customer, and likely it's mapped to some sort of table which represents the same abstract entity definition. People often don't understand that the work they spend on abstracting it all away is really moot because they're the ones working with the code anyway, and second of all, the code they end up with is more complex due to the abstraction layers and STILL polluted with the concepts of which entities they're using. I'm not saying everything should be crammed into a single routine/class, on the contrary, though finding the right balance between what to abstract and FOR WHAT REASON, is key to have a successful project. Too many times people simply abstract away because someone told them it's better, while there are no real reasons to abstract it away. > Currently I have 2 choices, either to go with MS SQL server and some > kind of o/r mapper or use an object database: db4o. > Db4o handles my problem natively i.e. they can analyze my code, get > the usages specifications (native queries as they call them) and make > more database friendly queries out of them. Non of the other o/r > mappers I know of can do it automatically. Use more efficient queries ? Why not? Most o/r mappers offer span-prefetchpath fetches, update only the fields which are changed etc. > I don't know which way I will go now. Until very late in the > development I don't want to deal with persistance layer in any form. I > abstract access to persistance in repositories. I use specifications > to filter the results of queries. > I won't decide on the persistance until very late in the project. Do > you know of a better way to do it other than what I have described > above? So, just because you postpone this decision, which you eventually HAVE TO MAKE, you are stuck with a problem and a complex conversion layer. Don't you see, that after you've made the decision, the application is polluted with an abstraction layer that's unnecessary? So, because you have to make the decision sooner or later, why not make the decision NOW, and forget about this complex problem? Because it's not only the specifications you have to convert, also probably the data. Entities need change tracking for example, how are you going to handle that? Do the entities track themselves, or does your persistence solution does that for you? If the latter, not every persistence solution is able to detect if an entity is 'new' or just 'updated', because it could be the entity isn't created by that same session object. (often a problem in distributed applications or even webapps) Abstractions are sometimes necessary, though this abstraction is simply unnecessary as it's not serving the project, you HAVE TO make the decision anyway, so the abstraction layer will end up in the software for no apparent reason as after the project has been completed, the layer is there but there's no rational reasoning for it. > > Frankly, not a lot of people swap o/r mappers. Like there > > aren't many people writing their code in such a way that they can > > swap out a complete UI widget library on the spot, because 'you'll > > never know!'... > > I won't swap it either. It's just that I don't even want to chose one > right now. Not wanting to choose now is a decision you've made. Decisions have consequences. Because you don't want to choose now, you have to deal with the consequence of having to write a large stack (because don't underestimate this) of code to convert specifications in format A to format B, plus likely convert entities in format A to format B and back, while at the same time miss the features a solid persistence framework offers you, like full entity management, support for validation etc. etc. So, if I were you, I'd bite the bullet, choose a persistence solution, and start writing code for your APPLICATION, instead of writing layer upon layer of plumbing because you postponed a decision (which you have to make anyway, it's unavoidable) FB -- ------------------------------------------------------------------------ Lead developer of LLBLGen Pro, the productive O/R mapper for .NET LLBLGen Pro website: http://www.llblgen.com My .NET blog: http://weblogs.asp.net/fbouma Microsoft MVP (C#) ------------------------------------------------------------------------
From: Mikeon on 7 Feb 2007 10:33 > yes, though so does your code. A repository method GetCustomer, gets a > ... customer, and likely it's mapped to some sort of table which > represents the same abstract entity definition. > > People often don't understand that the work they spend on abstracting > it all away is really moot because they're the ones working with the > code anyway, and second of all, the code they end up with is more > complex due to the abstraction layers and STILL polluted with the > concepts of which entities they're using. I agree with you on this. But there is a small thing that makes this project different than all others: it is a personal, hobby dirven project, which doesn't have to be completed on a fixed date. It doesn't even has to be completed at all! The goal is to learn something new. I have already tried the approach with data mapper. I have even created my own mapper with its own Query Objects (or Criteria as I called them) by which you could fetch object from the database. It worked very well so I know what you mean about unnecessary abstracting. > Too many times people simply abstract away because > someone told them it's better, while there are no real reasons to > abstract it away. I want to do it because it is different. > > Currently I have 2 choices, either to go with MS SQL server and some > > kind of o/r mapper or use an object database: db4o. > > Db4o handles my problem natively i.e. they can analyze my code, get > > the usages specifications (native queries as they call them) and make > > more database friendly queries out of them. Non of the other o/r > > mappers I know of can do it automatically. > > Use more efficient queries ? Why not? Most o/r mappers offer > span-prefetchpath fetches, update only the fields which are changed etc. None of the mappers I have seen can do a performant query out of this: repository.Get(delegate(User usr) { return usr.Name == "John"; }); I have to admint though that I haven't made a research in this scope so maybe there are some that can. LINQ makes this easier of course. I suppose mappers usually use some kind of "hack" i.e. code generation to do it. > So, just because you postpone this decision, which you eventually HAVE > TO MAKE, you are stuck with a problem and a complex conversion layer. > > Don't you see, that after you've made the decision, the application is > polluted with an abstraction layer that's unnecessary? > > So, because you have to make the decision sooner or later, why not > make the decision NOW, and forget about this complex problem? Because > it's not only the specifications you have to convert, also probably the > data. My goal is to come out with a generic repository that I can use in any project, and only pass it its data access implementation via IoC. So Making the decision now would impact my future decisions. I want to be independant as much as I can. > Entities need change tracking for example, how are you going to > handle that? Do the entities track themselves, or does your persistence > solution does that for you? If the latter, not every persistence > solution is able to detect if an entity is 'new' or just 'updated', > because it could be the entity isn't created by that same session > object. (often a problem in distributed applications or even webapps) That one I have already solved using unit of work pattern which I pass to a repository. I can send you my code if you wish, please contact me via email. You will see then where my problem lies. > Abstractions are sometimes necessary, though this abstraction is > simply unnecessary as it's not serving the project, you HAVE TO make > the decision anyway, so the abstraction layer will end up in the > software for no apparent reason as after the project has been > completed, the layer is there but there's no rational reasoning for it. Reason described above. I want to get a reusable repository. > Not wanting to choose now is a decision you've made. Decisions have > consequences. Because you don't want to choose now, you have to deal > with the consequence of having to write a large stack (because don't > underestimate this) of code to convert specifications in format A to > format B, plus likely convert entities in format A to format B and > back, while at the same time miss the features a solid persistence > framework offers you, like full entity management, support for > validation etc. etc. I am perfectly aware of the consequences. Moreover, my original question is just that: how to convert Specfication objects (via Specification Pattern) to Query Objects (via Query Object pattern). Former is a domain level concept (via Domain Driven Design) the later is more of a data access component dependant concept. > So, if I were you, I'd bite the bullet, choose a persistence solution, > and start writing code for your APPLICATION, instead of writing layer > upon layer of plumbing because you postponed a decision (which you have > to make anyway, it's unavoidable) By now, knowing that the main goal is to learn I'm sure you would not chose the persistence and kept researching the problem :-) -- Michal
From: Frans Bouma on 8 Feb 2007 05:32 Mikeon wrote: > > Too many times people simply abstract away because > > someone told them it's better, while there are no real reasons to > > abstract it away. > > I want to do it because it is different. ok, though unnecessary actions don't learn you anything unless you realize the abstraction was unnecessary. > > > Currently I have 2 choices, either to go with MS SQL server and > > > some kind of o/r mapper or use an object database: db4o. > > > Db4o handles my problem natively i.e. they can analyze my code, > > > get the usages specifications (native queries as they call them) > > > and make more database friendly queries out of them. Non of the > > > other o/r mappers I know of can do it automatically. > > > > Use more efficient queries ? Why not? Most o/r mappers offer > > span-prefetchpath fetches, update only the fields which are changed > > etc. > > None of the mappers I have seen can do a performant query out of this: > > repository.Get(delegate(User usr) { return usr.Name == "John"; }); err, isn't that simply resulting in SELECT ... FROM User WHERE Name = @name so @name = "John" ? > I have to admint though that I haven't made a research in this scope > so maybe there are some that can. any o/r mapper will issue a select with a where in that case, unless you meant something different. > LINQ makes this easier of course. I suppose mappers usually use some > kind of "hack" i.e. code generation to do it. Linq is a way to formulate queries, so just a different way of formulating the query than you would in the o/r mapper's native query language. > > So, just because you postpone this decision, which you > > eventually HAVE TO MAKE, you are stuck with a problem and a complex > > conversion layer. > > > > Don't you see, that after you've made the decision, the > > application is polluted with an abstraction layer that's > > unnecessary? > > > > So, because you have to make the decision sooner or later, > > why not make the decision NOW, and forget about this complex > > problem? Because it's not only the specifications you have to > > convert, also probably the data. > > My goal is to come out with a generic repository that I can use in any > project, and only pass it its data access implementation via IoC. So > Making the decision now would impact my future decisions. I want to be > independant as much as I can. So you're more looking for a generic wrapper for all o/r mappers out there? Good luck ;) FB -- ------------------------------------------------------------------------ Lead developer of LLBLGen Pro, the productive O/R mapper for .NET LLBLGen Pro website: http://www.llblgen.com My .NET blog: http://weblogs.asp.net/fbouma Microsoft MVP (C#) ------------------------------------------------------------------------
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 Prev: UML Activity Diagram - 1 Activity across 2 or more swimlanes Next: "OOP is Dead" article |