June 2003 - Posts
I was at a MSFT event for the last 2 days on future VS.NET / .NET FX stuff (I'll avoid the pre-MSFT-Scoble-esque Longhorn-rocks-but-I-can't-talk-about-it-because-it's-NDA posts). I ran into a bunch of Software Legends who all knew me.
[via DevHawk]
I was there too, but most of the Software Legends did not know me ;). I had a good time and met Chris, Ingo, Jon, Erik and Doug, but reading the badges it seemed that almost every .NET guru was there.
I'll be doing a WebCast about DeKlarit on July 11th :
Agile Development with Visual Basic .NET: Applying DeKlarit
As the title suggest, it will be focused in Rapid Development using VB.NET.
See you there.
There is an article in July's MSDN Magazine that even if it talks about Fiefdoms, it discusses the issues I've been talking about on how to map Entities to DataSets.
Start reading in the 3rd paragraph under the 'XML-based Web Services' subject ;).
In some previous posts I was trying to explain why I think is better to use a message-based approach for developing n-layer applications instead of using a domain model. In some posts I've focused on the DataSet, but its not really about the DataSet but about the way of exchanging data between layers (notice Im saying layers, not tiers). This time I'll try to explain myself better ;).
When I'm saying message what I mean is to gather the data you need for a specific task in a specific data structure. So, if I'm dealing with an Order and the order has master and detail, I want a data structure with 2 levels, even if an Order involves more than 2 classes or 2 tables. If you think a message is something different than this, please pretend you agree with me, it is not really important ;) in this context.
Lets think about an ASP.NET application that needs to display an Order that is stored in a relational database, with the following tables:
Order [Id (key), CustomerId]
OrderDetails [Id (key), OrderId, ProductId, Quantity]
Customer [Id (key), Name]
Product [Id (key), Price]
If I map this to an object model, and I want to use the resulting classes in my ASP.NET application, I'll probably write something like this (in pseudo c#):
Order.Id
Order.Customer.Id
foreach (OrderDetail detail in Order.Details)
{
detail.Product.Id
detail.Product.Price
detail.Quantity
}
Now, suppose I need to change my underlying schema. Instead of having one price for each product, I'll create Customers Categories, and I'll have a Product price for each Category. The tables will look like:
Order [Id (key), CustomerId]
OrderDetails [Id(key), OrderId, ProductId, Quantity]
Customer [Id(key), Name, CategoryId]
Category [Id(key), Name]
Product [Id (key)]
ProductCategory [ProductId(key), CategoryId(key), Price]
The usual way to hide this change in a multilayer application is to change the way I map my tables to my classes, so the signature of the classes will be the same and I won't have to change my ASP.NET code. In this case, the problem is that I cannot (or perhaps I can but I dont realize how ;). I'll need to change my code to something like:
Order.Id
Order.Customer.Id
foreach (OrderDetail detail in Order.Details)
{
detail.Product.Id
detail.GetProductPrice(Order.Customer.Category.Id)
detail.Quantity
}
This is because there is no way to obtain the price from the Product object, as it needs the Category, and the Category depends on the Invoices Customer.
If instead of using a domain model, I define a message with:
OrderId
CustomerId
OrderDetail[] lines
OrderDetail:
ProductId
ProductPrice
Quantity
Ill write:
OrderId
CustomerId
foreach (OrderDetail detail in Order.Details)
{
detail.ProductId
detail.ProductPrice
detail.Quantity
}
And this code will be valid with the first database schema and with the second one. I just need to change the SQL statement that loads the structure.
Why does this happen? Because if I use my domain model from a different layer, Im exposing it. We build applications in layers because we want to isolate one layer from the changes in the other layers, and exposing a domain model does not let me do it. Its usually known as a bad practice to expose the database schema to the UI layer of an application. Exposing the object model is better, but it's still bad idea.
On the other hand, think on how complex is for the ASP.NET developer to deal with each model. If he uses the object model, he needs to know how to traverse it to find the data he needs. Also, he does not really know how many roundtrips it takes to access the Order, and how many columns will be retrieved (i.e., all the fields from the accessed tables will be probably retrieved even if not needed).
With a data structure designed to work with the Orders, we are giving the external layer programmer a much better interface with our middle layer.
UPDATE: this post has been translated to French!
There seems to be some confusion between DataSets and the Table Module Fowler PoEAA's pattern.
Fowler says a Table Module organizes domain logic with one class per table. Then he says that "the primary distinction with Domain Model is that, if you have many orders, a Domain Model will have one order object per order, while a Table Module will have one object to handle all orders", and that a single instance of a class contains the various procedures that will act on the data.
Fowler suggests that you could use a DataSet (RecordSet in his book) when you are using a Table Module, but that does not mean that every time you use a DataSet you are using Table Module, or that if you use custom classes you are not using Table Module. A lot of O/R mappers use Table Module with custom classes.
Lets see how we use DataSets in DeKlarit:
- One DataSet has more than one DataTable, with relations between them. For example, a master-detail relation.
- One DataSet usually has a specific instance of the data, for example, one Order, with header and lines. You can also have all the Orders and use them the way Fowler suggests, but it is used in the same scenario where in a domain model you have a collection of instances (like a CustomerCollection).
- Each DataTable in the DataSet does not map to a database table. For example, in the Order header I can have the Customer Name, so it maps to a join between Orders and Customers. In the Order details I can have the Product Description, the Product Price, so it maps to a Join between Orders Details and Products. The mapping between the DataSet and the real database tables is done by DeKlarit, and if a databse schema change implies a change in the way it should map it, DeKlarit will regenerate the corresponding code.
- You can have a complex process model that uses each DataSet. You usually dont have all the methods in one class, even if in DeKlarit there is a lot of logic running in the adapter, as you can add adding declarative rules to your entity and those business rules are triggered by the adapter when you try to persist the changes,
This approach does not follow any of the Table Module rules. There isnt a table per class, not all the data is loaded in the DataSet, and the logic is wherever you want.
So, DataSet != Table Module. The DataSet is just a standard interface to represent data that provides, for free, most of the things you could want to do with data. You can use it in any way you want.
- MagicForm - .NET class that allows for runtime editing of your Windows Forms-based GUI.
[via Larkware News]
It's quite cool. Even if it still has some rough edges, it's a very good idea.
JavaOne was interesting but I really did not feel excited about it.
The conference focus was on cell-phones (they really seem to have better support than Microsoft in cell phones, as most cell-phone makers were there with Java-enabled phones), Java games, Ease of Development, and the fact that they are trying to make Java a consumer brand. None of this subjects is very attractive for me.
There were some good conferences and some good BOF sessions. Some of the stuff they are doing with the HotSpot VM is quite interesting (for example, the 5th or 6th time you call the same method using reflection you get the same performance as if you make a direct call). JDK 1.4.2 seems to be much faster than 1.4.1, and the JDK 1.5 language features (generics, attributes, etc) look nice, even if they are not very innovative ;). Borland's sessions on JBuilder/Together were quite good too.
I liked the BOF sessions with the product teams (Class libraries, hotspot, etc). It has some advantages over the 'Ask The Experts' approach in MS conferences, because you can just go and hear what they answer to other people's questions... On the other hand, Ask The Experts are probably better if you have a difficult question to ask.
Compared to TechEd, there were two main differences:
- No free food (actually, much less free food than in TechEd)
- No IBM (there were no IBM conferences and there was not an IBM booth).
I met with some Microsofties, some expected (like David Weller) and some unexpected (like Pablo Castro). I also enjoyed meeting Ted Neward, who is my hero.
You can find more coverage in:
TheServerSide
Cedric's weblog
Frans , Mats and Paul are blogging about O/R mappers.
The problem with OR mappers is that you are still coding your Data Access Layer, but instead of using SQL, you are using the OR syntax. If you use an OR mapper in your ASP.NET page, you'll be violating the 'do not add data access code to your ASP.NET page'. You are not building your applications in layers.
If you use DataSets and a class that knows how to load it, persist it, etc, you have a much better architecture. If you have a layered approach in that persistence layer, you can change the way your application talks with the data source without changing your application code.
For example, you can change your app from using a '2-tier' architecture and talk directly to the data source, to make it talk to a webservices layer. You can add a layer that provides online/offline support. You can host your data access components in Enterprise Services. You can provide caching. All without a single change in your application code.
You can acomplish that with OR mappers but you need the OR mapper provider to do it. If it does not support it, you are usually stuck.
With a OR mapper you are coupling your data with your architecture. With a message-based approach using DataSets, you are not. So, it's OK to use a OR mapper to load a DataSet ;).
Update:
OK, I think I should refine it ;).
If your entity objects are [Serializable] then you are probably OK if you use a O-R mapper, as you can find a way to be architecture-independent, even if it could require to think about it in advance. If your objects must extend from a MarshalByRefObject (or a subclass, i.e. ContextBoundObject) then chances are that you are in trouble.
It's a new IDE from Sun.
In JavaOne Sun has been talking about reaching 10 million of Java Developers (they say there are 3m right now). To make this possible they want to expand the number of 'corporate developers' that use Java, and with 'corporate developer' they mean the guys who use VB 6 (the same ones that Microsoft is trying to move to .NET ;).
Project Rave is a tool for those guys. It looks cool, and it's fast, as they built it with no extensibility hooks as other more ambitious IDEs (NetBeans, Eclipse). Right now it just supports Web applications, and it's not targeted to the EJB developer, it's for guys that want to access their database directly, with tools to do data binding directly from the database, etc. It targets the same people as ASP.NET Web Matrix.
More Posts
Next page »