The conception, birth, and first steps of an application named Charlie

Subscribe: Atom or RSS

Building Object Applications That Work

by Alister Jones (SomeNewKid)

In my plan to go back to basics and learn about objects, I purchased The Object Primer and Building Object Applications That Work at the same time from Amazon. While The Object Primer was a disappointment, the second book proved much more useful. Building Object Applications That Work still shoves UML down its reader’s throat, but it has the redeeming quality of also discussing objects and applications. In this weblog entry I will touch on the parts of the book that have helped to shape Charlie.

The first interesting idea is that of Persistence. The definition from the book is that “persistence describes the issue of how to save objects to permanent storage.” Broadly speaking, there are two types of objects: transient objects and persistent objects. A transient object is created, used, and then discarded. An ASP.NET example of a transient object would a DataGrid. We create a DataGrid object, use it on a webpage to display data, and then discard it. Once it has been discarded, we cannot get it back—no way, no how. A persistent object, on the other hand, is created, used, and then stored. An ASP.NET example of a persistent object would be the Profile of the user. We create a profile for a new user, use it to customize the webpage for that user, and then store the profile before the request is finished. ASP.NET automatically takes care of the storage, but the point is that the object is stored. Once the Profile object has been discarded, we can get it back. Strictly speaking, it is usually the data that we store and get back, not the object itself, but let’s not split hairs. (I don't have enough hairs for that.)

Anyway, if one tends to stick to articles about .NET, very little is written about the concept of persistence. Instead, there is lots of talk about databases (SQL Server), disconnected data (DataSets), and data access layers. This focus is the result of Microsoft pushing rapid application development ahead of solid application architecture. .NET is fully able to realize solid application architecture, but there is simply very little said on the topic.

So the first interesting idea is to think in terms of persistence (the why), and not in terms of data access (the how). This is an important idea that lead to Charlie having a persistence layer, and not a data access layer. But I’ll come back to that when I talk about Charlie’s final architecture.

The second interesting idea is that of a Five-Layer Class-Type Architecture. Most developers will be familiar with the following architectural diagram:

What this architecture does not do is separate the application from the underlying operating system. If the application needs to write a file to disk, it must make use of the operating system’s API to do so. The result is that the application will end up with lots of operating system-specific code entwined with its application code. This means that the application would be hard to port to another operating system, and would be fragile to any changes to the underlying operating system. The solution to this problem is to introduce a fourth layer that controls access to the operating system and its resources. The three traditional layers then talk only to this fourth layer, and never directly to the operating system. Like this:

When talking about a .NET application, we automatically have this new fourth layer, as it is the .NET Framework Class Library. Even so, the concept of a fourth layer can still be used, where it provides services and resources to the three traditional layers. Hence, in Charlie, this layer has been called the Services layer.

The fifth layer to be added to the standard architectural diagram is what Scott Ambler describes as “the most important component of any system architecture, namely the people who use the application.” The resulting five-layer class-type architecture therefore looks like this:

This five-layer architectural diagram is much more “real world” and usable than the academic three-layer architectural diagram. The System layer, reworked as a Services layer, provides an answer to my earlier “where does it go?” question concerning components that do not belong in the Interface, Business, or Persistence layers, but that provide services to these layers. Just as good, the inclusion of users in the diagram underscores the reality that most applications are part of a larger business process, and this should be reflected in its architecture. The above diagram may not be a shattering revelation, but it did help me to arrive at Charlie’s final architecture.

The third interesting idea is the Law of Demeter. The formal description of this law can be read at that Wikipedia link. Informally, this is understood as “don’t talk to strangers,” meaning that an object should talk only to itself, its parents (its base classes), and its close friends (objects passed to it, or created by it). While this law sounds good and makes sense, it seems to be very difficult, if not impossible, to consistently adhere to this law. In the context of an ASP.NET application, our code must often “reach out” to the System.Web.HttpContext.Current object (a stranger to our objects), and retrieve the current Request, Response, Cache, Server, Session, User, or Profile objects (which are even more distant strangers). This reaching out violates the Law of Demeter, yet the HttpContext.Current object is so darn handy that it seems senseless to introduce the complexity necessary to adhere to the law. So, yet again abiding by the principle that simple is better than complicated, I have decided that while I will be cognisant of this law, I am not going to worry too much when I break it.

The final interesting idea is to design the business objects first, and the database tables second. This makes perfect sense to me. The data in a database is meaningless until it is brought into play in the context of a business object. A value of 1,294 in a database field is meaningless until it is used to populate the Amount property of a BankAccount business object, or to populate the FloorSpace property of a RetailShop business object, or to populate the Length property of a Ship business object. It makes sense then that the database tables are subservient to the business objects, and should be designed only after the more important business objects have been designed. For this reason, I have decided to concentrate on getting Charlie’s business objects right, and not worry too much about the database tables that allow those business objects to be persisted.

In the end, Building Object Applications That Work was an interesting book, but I would not recommend it to others. Scott Ambler is such a nerd that his descriptions would only make sense to those who already understand what he’s on about. If a reader did not already have a solid understanding of object-oriented programming, he or she is not going to understand OOP after reading this book. At best, the book will be a refresher for some. At worst, the book will confuse the crap out of others.

The next book that I will comment on is better, and the final book I will comment on is simply brilliant. Stay tuned.

by Alister Jones | Next up: Applying UML and Patterns

0 comments

----