Monday, May 22, 2006
Now... I am not going to say that using stored procedures is wrong... and I am not going to say that the only correct way of solving software problems is using object orientation... ( I do prefer to use object orientation, I a do prefer to use an object relational mapper instead of a stored procedures, specially for OLTP applications, I think application built that way are more maintainable, more portable between database, can be built faster, scale better, etc,etc)
But for batch processing, stored procedures have a clear advantage, and in my experience many business problems are solved by using an OLTP application, and a short but very important list of batch process... (of course the problem here is that if you built you application using an ORM, probably you have a lot of you business logic already implemented in a presentation-independent form, and, depending on the size of you database, you could program you batch process using your business objects... that has its disadvantages (slower performance that stored procedures) and its advantages (reutilization)... I believe reutilization and maintenance are more important that performance... specially because it is possible to worry about performance in the wrong way: for example Premature Optimization )
But the main point of this post, is that, first, I didn't think that using stored procedures was object oriented programming... it was "procedural programming"... or perhaps even "relational programming" but certainly not object oriented programming (where is the inheritance? where is the polymorphism?) but... after giving it some more thought... I realized that while it could not be "object oriented" it could be "object based"... stored procedures can encapsulate your tables (one of the major advantages of stored procedures) and you can see them as methods to a your "database" object...
So... now... your (OLTP?) system is a thin presentation layer on top of the "database object"... now... is there something in favor... or against that in object oriented design theory?.... mmm.... it achieves Presentation/Business Logic separation... and that is good... but I still feel there is something that doesn't feel right...
OMG! Well, it turns out there is! : Now the database is a God Object.
From Wikipedia: A God object is an object that knows too much or does too much. The God object is an example of an anti-pattern, it goes against divide & conquer ... using a God object is analogue of failing to use subroutines in procedural programming languages, because so much code references it, it makes maintenance difficult...
So... the next time someone tells you that using stored procedures is good object oriented programming... you could answer him or her: Oh My God (Object)! (You could think of it as object based, but, form an object oriented point if view.. it is a recommended solution? couldn't it be seen as an anti-pattern? I am not saying it is wrong, I am just saying that from an object oriented point of view, it might not be the best way to solve the problem... of course, using object orientation might not be the right way to solve this particular problem, after all, object orientation is not a Silver Bullet)
Tuesday, May 16, 2006
After wasting several hours, it turns out that, before installing a WindowsForms for .NET 2.0 application that requires CrystalReports, one needs to install CRRedist2005_x86.msi from C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\CrystalReports it should be easier to find...
In that folder there is also a product.xml that could be for bootstrapping the CRRedist2005_x86.msi with you own .msi so that you can install everything in one step (well, I think it is for that) I have to do more research...
Monday, May 15, 2006
Frederik Gheysels' weblog
It was almost as if I heard myself complaining about the bad design most RAD tools promote... what I wonder is.. why couldn't RAD tools promote doing it in "the right way" with proper MVC separation and everything....
It is like the new Java Studio Creator for Sun, the first version copied the DataSet idea from VS.NET and copied it IMHO in the worst possible may (by assuming incorrectly that .NET databinding only worked for the DataSet and not for any .NET object... it is true that it seems like that on the first look, but if you analyze the API closer, you can see it is biased to make it easier for the DataSet, but it does allows for pure object databinding... and what do the Sun guys do? they make it only work for tables! without object support! (they tried to fix it for Java Studio Creator 2, but the object-view has a bug that makes it unusable... I just cant believe it, how could they make such a mistake having really good ORM tools like Hibernate, EOF, Castor o Cayenne, I was expecting full object databinding from them... but, until now, there is nothing close to .NET databinding in the Java world)
Sunday, May 14, 2006
I am happy I found this blog entry, I have been looking for a disscusion about Ad Hoc SQL vs Stored Procedures it is important to know both sides of the discussion, so that the next time it is necesary to choose, one can provide the best possible solution.
Saturday, May 13, 2006
Today I was reading: Why can't Hibernate just load objects on demand?
I find some of its affirmations interesting (I realize this is kind of a sensitive topic, but I just don't feel that the information there is convincing enough, specially if you have used other ORM that do have distributed non-transactional lazy loading:
If Hibernate would, hidden from the developer and outside of any transaction demarcation, start random database connections and transactions, why have transaction demarcation at all?
That really is a very good question, what exactly it is so good about having transaction demarcation? (wouldn't it be better to have "automatic transactional demarcation"?) like this:
Customer newCustomer = new Customer(EcoSpace);
newCustomer.Name = "Air Software Ltd";
newCustomer.Telephone = "+44 (0)121 243 6689";
TelephoneNumber alternateTelephoneNumber = new TelephoneNumber(EcoSpace);
alternateTelephoneNumber.Name := "Home number";
alternateTelephoneNumber.Number = "+44 (0)121 999 9999";
Wouldn't it be better, if, as we have the Session, and the transactions...we could have an equivalent to ECO's EcoSpace?
(Important Note: I am NOT saying ECO is better than NHibernate, in fact I had to choose between the two for a project, and IMO NHibernate was a better choice, because its mapping capabilities for legacy databases are far superior, and its lower level session/transaction base API gave me more control, and HQL is IMO more powerful than OCL... but not all projects need that level of control, and... specially for new projects that do not need to interoperate with legacy apps, or that will have full control of the database ECO could be a much better alternative because of its easier to use API with automatic transactional demarcation and non-transactional lazy loading)
What happens when Hibernate opens a new database connection to load a collection, but the owning entity has been deleted meanwhile?
I guess in that case it should throw an exception... but I don't see this a justification for transaction demarcation... IMHO the same problem can happen with regular "manual session opening an closing"
|(Note that this problem does not appear with the two-transaction strategy as described above [in the question Can I use two transactions in one Session?] - the single Session provides repeatable reads for entities.)|
Yes, but that also means I need to have a session and transaction open during user think time...
|Why even have a service layer when every object can be retrieved by simply navigating to it? |
That is really a problematic question... in fact... the question is my point exactly... why should I bother having a service layer if every object can be retrieved by simply navigating to it? IMHO not having to build a service layer sound like a good thing... doesn't it?
|All of this leads to no solution, because Hibernate is a service for online transaction processing (and certain kinds of batch operations) and not a "streaming objects from some persistent data store in undefined units of work"-service. Also, in addition to the n+1 selects problem, do we really need an n+1 transaction and connection problem? |
So... that means... that if we want distributed non-transactional lazy loading we should build a streaming objects from some persistent data store in undefined units of work service? is that what other ORMs (like Borland ECO or Apple's EOF are? who draws the line? I know that the owners of Hibernate are free to choose, but is this decision theoretically supported? I'd like to know how...)
|The solution for this issue is of course proper unit of work demarcation and design, supported by possibly an interception technique as shown in the pattern here, and/or the correct fetch technique so that all required information for a particular unit of work can be retrieved with minimum impact, best performance, and scalability. |
Yes, but OpenSessionInView is only a good idea if you are building a web application.. and if you want only one transaction per request/response cycle... if you UI deviates from that... then it is no longer such a good idea...
|Note: Some people still believe that this pattern creates a dependency between the presentation layer and Hibernate. It does not...|
Well, then, why OpenSessionInView isn't a good idea for interactive UIs in smartclients? isn't changing form ASP.NET to WindowsForms a change on the presentation layer? so.. If i built my application to share its business logic between a WindowsForms and an ASP.NET presentation and I am going to have problems... then that means I am tied to a particular presentation layer... isn't it?
In my opinion the best two are Hibernate and EOF, I think a mix between them could create "the ultimate" Object Relational Mapper... or the ultimate Business Entity Manager...?
EOF (the best BEM?)
An interesting topic for analysis could be the limits between an Object Relational Mapper and an Business Entity Manager. Some people think that Hibernate shouldn't evolve to become more like EOF, because it should aim to do one and only one thing (be the best ORM) and other people think that it would be nice to have the services that an Business Entity Manager gives you:
- automatic connection handling
- automatic transactions handling
- multiple undo levels
- real nested transactions
- client and server objects
- distributed non-transactional lazy loading
There are also some people that think that a Business Entity Manager is more closer to the MDA "objective", so I think it is important to take a look at (Using Borland's ECO to develop model-powered applications for .NET) an many related articles, the specially interesting thing for me about ECO is its OCL support (that can be used, for example to configure constraints that help ensuring that only consistent data is saved into the database... it is kind of a Design by Contract for the domain model)
IMO the Active Record pattern is getting too much popularity (perhaps thanks to Ruby , but I think it leads to an anemic domain model ) and Domain Model based in Business Entity Managers is not as popular (thanks to the problems in EJB1 and EJB2) but it is important to remember that EJB is not the only way to build an Business Entity Manager, there are ways to build Business Entity Managers that are a lot more lightweight and user friendly than EJB, (just investigate more about EOF and ECO)
Monday, May 08, 2006
This releases has several minor bug fixes, the majority of them because I have upgraded the UnitTests for UIPAB 2.0 and that allowed me to test all the changes the UIP has suffered in my hands. This will make it easier to add new features without the fear of finding I broke something important.
The majority of the bugs fixed were related to the difference between the HybridDictionary and the new generic Dictionary<K,V> with an HybridDictionary it as right to ask for an unknown key:
//The SomeUnknonwKey is not in the HybridDictionary
But in .NET 2.0, that code throws a "Key not found" exception and I have to:
//The SomeUnknownKey is not in the Generic Dictionary
The other problem was WindowsFormViewManager.GetCurrentViews(taskId) I am sure that my choice for return type was the correct one (IDictionary<string, IList<WindowsFormView>>) but it seems to be consistent with my interpretation of the internal workings of the UIPAB
So, in the test, where it said:
Hashtable views = WindowsFormViewManager.GetCurrentViews(taskId);
IDictionary<string, IList<WindowsFormView>> views;
views = WindowsFormViewManager.GetCurrentViews(taskId);
And, where it said:
it now says:
But I am not that convinced about the usability of this structure... perhaps I should simplify it in the next release. (The previous code IMO seems to handle this in an inconsistent way... some code assumes that the view is a dictionary strings and WindowsFormViews, and other code assumes that the key is a string, but the value is an IList... I guess i need to analyze this more thoughtfully
Sunday, May 07, 2006
While looking for information to "backup my personal research" on UI Design (and its relation with the underlying object graph an persistence mechanisms) I found this page "A Summary of User Interface Design Principles". And I got particularly interested in the 8th principle The principle of grammar: A user interface is a kind of language -- know what the rules are.
That principle says that the two most common grammars are known as "Action -> Object" and "Object -> Action". In Action->Object, the operation (or tool) is selected first (Similar to Edit then List?) and in "Object -> Action" the object is selected first and persists from one operation to the next (Similar to List then Edit?).
On the other hand this two "most common grammars" are IMHO not exactly "data manipulation oriented (DMO)", because the principle states that in "Action -> Object": When a subsequent object is chosen, the tool immediately operates upon the object. The selection of the tool persists from one operation to the next, so that many objects can be operated on one by one without having to re-select the tool. And in a typical DMO you do not choose the "edit" tool and then apply it to an list of different objects... so this grammar seems to apply more to a typical "tools for editing documents" kind of UI. But Object -> Actions matches better with List (You have to select an object) then Edit (The action).... I will have to look more in to this...
Another principle that is related to my doubts in UI Design is the 10th (and it is specially related to UI Design: When do you save?) is "The principle of safety: Let the user develop confidence by providing a safety net" according to this principle, the UI should provide a safety net for new users, but provide the option to "work in unsafe mode" for the advanced users. I think that the most important feature a program should provide is a "a safe cancel button that really cancels" and an "undo mechanisms" (because, as much as we would like the user to pay attention to our message box, the truth is that both novice and advanced users dismiss them without to much care, and after that, only "Undo" can save them)
The principle of context -- Limit user activity to one well-defined context unless there's a good reason not to (11th) IMO is more related to the modality of an UI that the 8th... perhaps because in general I tend to use modal windows when I want the user focused in a particular context, and I don't want him to "click around" and do possible conflicting actions (like trying to delete the record he is currently editing)
I also liked the 14th principle: "The principle of humility -- Listen to what ordinary people have to say" it reminded my that I have to pay attention to the user (A single designer's intuition about what is good and bad in an application is insufficient. Program creators are a small, and not terribly representative, subset of the general computing population.), but that the user is not the owner of all the answers: "One must be true to one's vision. A product built entirely from customer feedback is doomed to mediocrity, because what users want most are the features that they cannot anticipate."The only thing I didn't liked about this principles were the examples, they were all about the typical "document editing UIs" like Word processors, Painting programs, etc, and not about data manipulating applications(applications built on top of CRUD and transaction principles) Mmmmm, perhaps I should write my own examples and post them here... If you have an example, please, share it with me...
Friday, May 05, 2006
How do developers save?? I know I know, after reading some of the comments on UI Design: Edit then List vs List then Edit I learned that most developers believe that the UI Design is a user concern, not a developer concern (build the UI as the User wants it, not as the developer wants it)... I have been wondering...
- Do the users really know what they want?
- Do the users really appreciate some of the internal behaviors the UI provides?
- Do all software projects have enough budget and type to make real usability test?
- Do all customers pay an amount of money for a project that justifies the extra effort of building a well designed UI?
- Do you as a developer have a framework that make all this issues moot and for you is so extremely easy to build a good UI that you always built it in the absolute best way?
Lets take, for example the "Save" or "Cancel" button in a typical CRUD application, and lets say the UI is build following List then Edit:
- The user search all customers named "John"
- The user selects the first one from the list
- The user clicks the edit button on the tool-bar (in the List window)
- The Edit window appears, the user modifies everything (from some fields, to complex to many, to one, many to many and many to many relationships) and then...
- The user clicks "save" because he is happy with his changes
- The user clicks "cancel" because he is not happy with his changes.
Now... a well behaved system, shouldn't write anything into the database until the "save" button is clicked (regardless of the complexity of the "edit customers" UI) and a well designed persistence API should make it as easy as "editingContext.Rollback()" to achieve that effect... and, if we weren't editing an customer, and from a performance perspective, if as a result of the editing of customer we created new "detail" objects(or rows) and we decided to cancel the operation, the server shouldn't even be aware that we created those objects, and then "roll-backed" its existence.
But the questions now is:
- Do we all always check that nothing is written on the database until we click "save"? and "Does the user care?"
I know I always try to check that if and only if the save button is clicked I save... but I have met lots of other developers that do not care... if for example, they have to add new addresses to the customer they write the new addresses into the database the moment they create them (from inside the edit customer ui!) and after the "cancel" button is clicked, this to many relationship is not rollbacked... they just don't care...
Now... I have to admit that I have done this sometimes (when in a extreme hurry to deliver a new form) , and "i feel" like it is enough if I add a message box warning (of those the user never reads) saying "if you add a new address all your changes will be committed to the database" ... the user, as always, just dismisses the warning and proceeds to add addresses... and perhaps click cancel later... nevertheless as soon as I have time, I fix the form so that it only saves when the save button is clicked... (and sometimes, with complex nested UIs that is a pretty hard job)
But... the thing is that I have seen lots of systems built with the idea "if you write it on the screen, and you do as much as click any button your changes will be saved" I have seen it specially in web based systems, but also in smartclients... and I have had the opportunity to hear all kinds of complains of this systems, and I have even replaced some of them with "only if you click save you save" systems... but I have never heard a single user saying "it is nice that the cancel button really works now" or "i hated the previous system because I clicked cancel and it saved my changes" but... strangely I have heard some of them complaining "I added 50 addresses to a customer, and then by mistake i clicked cancel, and then by mistake again I answered "yes" to the question "Are you sure you want to cancel your changes" and my changes were lost!!!!
But that has been my experience... maybe you do know a user that appreciates a consistent behavior in the "save" and "cancel" buttons...
How do you decide the transactional UI boundaries of your system? Do you really ask the user "do you want the cancel button" to really work? Do you always have the time to build 2 o 3 different UI prototypes and really test usability? Do your users really appreciate the extra 2 o 3 days that may take you to build a transactionally consistent UI? or the they prefer an UI that is built faster and if they made any mistakes, they "edit again" and rollback the mistakes manually (and they are happy with that behavior)? have you ever received a complain from a user saying "i want a cancel button that really works"? Do you implement cancel by calling an API similar to "editingContext.Rollback()" or do you cancel in "a custom way" (by explicitly deleting changes already made to the database) ? do you offer real "save" and "cancel" buttons even in your web based applications?
Monday, May 01, 2006
In Windows forms, if you want to set the current user, all you have to write is:
Thread.CurrentPrincipal = new CustomPrincipal(new CustomIdentity("login", "password"));
But in ASP.NET you can not ask the current thread for the user, because you will get the same thread on every request... so.. where should you store this information? It seems that the place is in the HttpContext.User Property as described on devx
I think I should look more into this...
I have added support for the ObjectBuilder in 2 places:
- Inside the GenericFactory (so that everything that was created by it can now enjoy the benefits of creation by the ObjectBuilder)
- Inside the "FactoriesFactory" so, now the factories that create the controllers, the viewmanager, the state, etc, are singleton (thanks to SingletonPolicy)
The FactoriesFactory acts as a "central" registry for other factories (or perhaps services in my next release) and it is a property of the Navigators base class (that way it is available everywhere in the internal API) but currently the contents of this registry are fixed, I am not sure where should I add code to customize the initialization...
You can "get" a factory with the following code:
Notice that we ask for an interface (the Factories are registered in the object builder using an ITypeMappingPolicy to achieve that effect).
I was thinking about adding and event or virtual method it in the UIPManager to allow for customization of the factories list... but i forgot that in webmode the Navigators are created at the WebFormView... and I would really like to have an "unified" place to do this... any suggestions?
I am almost ready to release Alpha 2 of the unofficial User Interface Process Application Block, I made several changes, here is a list with some of them:
- No more non-generic ArrayLists (they have all been converted to Lists with generics)
- No more HybridDictionary (they have all been converted to Dictionaries with generics)
- the UIPManager is now a singleton (first step in to a plug-in architecture)
- The StateCache is now a singleton an implements a new interface IStateCache (first step in to a plug-in architecture)
- The factories are also coordinated by a singleton FactoriesFactory that now implements the interface IFactoriesFactory
- Instead of calling the FactoriesFactory singleton everywhere, now it is a parameter of the Navigator base class (first step in to a plug-in architecture)
- Factories now receive as a parameter in their constructor the IGenericFactory they will use internally to create objects.
I am not sure if I will release it as it is right now... or wait until I add support for the ObjectBuilder, I am also deciding if I should call the ObjectBuilder from inside of the GenericFactory, or if a I should create a "ServiceCollection" to manage all the factories, similar to the one available in the CompositeUI