Choosing Data Containers, Part 5
- A Step Toward Realism
- New Architecture Code Examples
- The Usual Type of Client-Side Code
- A Couple of Tweaks that Help Performance
- Collapsed Objects
- Statuses in One Single Byte
- Object Vector
- Using "Dumb" Collections
- Another Struggle with Guids
- Oops, Maintainability Must Be Lost!
- And a Few Tweaks Not Applied Yet
- A New Test Application
- Results of the Throughput Tests
The previous article in this series discussed custom classes and what good performance they showed in the tests. But performance isn't everything, and the custom classes I used in the examples were very simple. (For example, they helped a lot less than optimally in maintainability in that incarnation.)
In this fifth and last article in the series, I discuss how the new architecture that I currently work on behaves when it comes to data container characteristics. The new architecture is also based on custom classes or the Domain Model pattern if we use the de-facto pattern name for it. (See Martin Fowler, Patterns of Enterprise Application Architecture. Addison-Wesley, 2002, ISBN: 0-321-12742-0.)
Will my new architecture, which has a lot more functionality, lose tremendously compared to the results in Part 4? And what tweaks have been used to get decent performance? These are the main issues dealt with here.
What happened to the plan? I was going to discuss a lot of different things that I mentioned in Parts 14. When I started writing this fifth article, I decided instead to not cover a lot of ground in a shallow way, but to "dig one single hole a little more deeply."
A Step Toward Realism
As I said, my new architecture is based on custom classes. It is, in my opinion, a lot more realistically usable than the code for custom classes that I discussed last time. The new architecture is ongoing work, but at the moment still more realistic...
You can read more about my work with the new architecture in another article series (A Pure Object Oriented Domain Model by a DB-GuyPart 1: Introduction, Part 2: One Base Class, Part 3: The Consumer Perspective, Part 4: The Application Layer Perspective, and Part 6: The Persistence Access Layer Perspective.) I also discuss my work in my blog. So I will give you only a brief overview here.
Don't worry: I'll also talk about several things that I haven't discussed before. All these things are related to serialization, but before that, some basics about the architecture.
First, I have a base class called EntityBase that entity classes such as Order and OrderLine typically inherit from. The EntityBase class is an implementation of the Layer Supertype pattern (See Martin Fowler. Patterns of Enterprise Application Architecture. Addison-Wesley, 2002. ISBN 0-321-12742-0.) In Figure 1, you see a UML diagram describing this relationship between the classes.
Figure 1 UML diagram for the custom classes example.
As shown in Figure 1, Order and OrderLine (but here called NewArchOrder and NewArchOrderLine) are very similar to what was shown in the previous article. The main difference here is that they inherit from EntityBase, and therefore get a lot of functionality for free.
Some of the functionalities that EntityBase provides are the following:
Collapse/Expand: You can start to work with an object in collapsed mode. Then, you can expand it explicitly, by calling Expand(); or implicitly, by touching one of the properties that is enabled only when the object is in expanded mode.
IsValid: You can ask the object if it is valid. The object then checks itself and also all its subobjects.
IsDirty: The object keeps track of whether it is dirty or not.
Cancel: If you don't like the changes you made to an object, you can call Cancel() and get the "original" values back (without touching the database).
Helpers for different tasks, such as setters/getters: EntityBase provides a lot of methods to generalize code.
Persistence help: And perhaps the most important functionality: EntityBase helps with persistence.
EntityBase is actually only a productivity booster. Everything regarding persistence, for example, can be done by just implementing a couple of custom interfaces instead. In this article, however, we assume that EntityBase is used (and that the interfaces mentioned therefore are implemented by EntityBase).