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

Subscribe: Atom or RSS

The Architecture - Part 2

by Alister Jones (SomeNewKid)

I am still bringing the story of Charlie up to date. At this point, it is the start of the new year. Before Charlie’s hiatus, I had created an elevator pitch, a feature set, a broad architecture, and a software specification. After Charlie’s hiatus, I had worked through Cuyahoga, and used that experience to determine the final elements of research that I needed to undertake before commencing Charlie. As you will see from the preceding book reviews, I researched both object-oriented programming and design patterns.

At the start of this year, I was ready to go. Because I am a visual thinker, I wanted to start with a picture. I fired up Photoshop and created the following diagram (you may click each diagram to see a larger version):

This simple diagram included four main things. First, it showed the users of Charlie. By users, I don’t mean Jim and Joe and Josephine. I mean a visitor, a member, a webmaster, a content author, a developer, and so on. Second, the diagram showed the devices used by the users, such as a web browser, a PDA, a speech synthesizer, and so on. Additionally, the diagram included a few devices without a user, such as an RSS aggregator and the Google spider. Third, it showed the external resources that Charlie would use, including databases, files, and web services. Finally, Charlie is shown as being a “black box” which accepts a request from a device, and sends a response back to the device. That is all Charlie does: accept web requests and provide web responses.

I then added the layers that I envisaged Charlie would need. The diagram now looked like this:

Starting from the bottom, the Foundation layer represents the underlying technology that I will not create, but upon which I will rely. The Foundation layer will be the .NET Framework (which comprises ASP.NET), but at this stage the diagram is meant to represent logical separations, not specific technologies.

The Services layer will be those components that provides services to the layers above. Services will include database access, graphics, logging, messaging, and so on. These components may be custom, may be open-source, or may be commercial.

The Persistence layer will provide the mechanism by which the business objects in the Business layer above can save and retrieve data from the external resources such as databases, files, and web services. In other words, the Persistence layer provides the “mapping” between the object-oriented stuff in the Business layer above, and the non-object-oriented stuff below. This means that the business objects will never know where their data is stored, and the external resources below will never know how their data is used. Charlie therefores provides a separation of concerns, which is the whole purpose of an architectural diagram.

The Business layer provides, well, the business objects. For anyone who does not know what a business object is, it is an programming object that represents a real-world thing. As Charlie’s purpose is to serve webpages to users, Charlie's business objects will include a User object (representing the real-world user) and a Webpage object (representing the real-world webpage). While that is a very limited view of what a business object is, it is a useful starting point to understand the purpose of a Business layer.

The Controller layer will provide the mechanism by which the business objects in the Business layer below can present themselves in the Interface layer above. If the Persistence layer provides the “mapping” between the business objects above and the external resources below, then the Controller layer provides the “mapping” between the business objects below and the interface above. Like the Persistence layer, it is a contrived layer that helps the business objects stay pure, to prevent data access or interface stuff from creeping into the business objects.

The Interface layer will provide the mechanism by which Charlie presents stuff to the user and interprets actions from the user (such as the user clicking a button or a hyperlink). Some books suggest that for web-based applications, a separate Presentation layer should be included. The Interface layer executes on the server, and the Presentation layer executes on the client. Because they are physically separate machines, they should be represented by logically separated layers. While true, I consider that the Devices shown in the diagram comprise the Presentation layer. Moveover, Charlie has no responsibility in the Presentation layer (it’s done what it can in the Interface layer), so to add the Presentation layer is just needless complexity. Say it with me now: simple is better than complicated.

The Runtime layer provides the mechanism by which Charlie starts running and then keeps running. This is the layer that accepts the incoming web request, assembles all of the components needed to handle that request, facilitates the interaction of these components, and ultimately sends a web response to the user. If the other layers are seen as the workers, this layer is the manager who tells everyone what to do, and when to do it.

In Scott Ambler’s five-layer architecture, he shows the System layer being placed to the side of the Persistence, Business, and Interface layers. Strictly speaking, my Services layer and the Foundation layer should “wrap” around the other layers. While that presentation would more accurately describe which layers can talk to which other layers, it makes the diagram more complex than it needs to be. So I have stayed with the simpler, stratified diagram.

With the layers finalized, I revisited my earlier architectural diagrams. The main thing I had determined from that earlier exercise was how a plugin module could provide interface, business, and data access elements. While the result might be comically obvious to a trained developer, this self-taught developer had to go through the thinking process needed to arrive at the obvious solution. So I added the modules to the new diagram. By this time, however, I had decided not to use the term module. That term already has a specific meaning in ASP.NET, so I decided to use Plugin instead. Here is the final diagram with the plugins added.

I printed a copy of the above diagram, had a laugh at how long it took me to arrive at such a simple architecture, and then pressed on.

by Alister Jones | Next up: The Simplicity of Casting

0 comments

----

Design Patterns in C#

by Alister Jones (SomeNewKid)

This is the last weblog entry that concerns my research for Charlie. Next up, I will talk about Charlie’s final architecture and its first classes.

In the previous weblog entry I described just how great is the book, Head First Design Patterns. After reading it I was so inspired that I promptly purchased Design Patterns in C#, hoping to round out my knowledge of patterns. If the Head First Design Patterns book is one of the best programming books ever written, Design Patterns in C# is one of the worst. It is truly, truly awful.

The first line of the book reads, “This book is for developers who know C# and want to improve their skills as designers.” Then, after having established that the book is for developers who already know C#, the first chapter says, “it’s worthwhile ensuring that you are comfortable with how C# features work,” and launches into a needless review of C#. That would be excusable if it were not the worst review imaginable. It is so poorly written that I wondered whether the author actually understands C# himself. In introducing interfaces, the first line reads, “C# interfaces can specify that implementers must provide indexers or properties.” If that is a good way of introducing interfaces to someone who may be fuzzy on the concept, I will sell my soul on eBay. The author also tries to explain the concept of delegates. While I have never seen a good explanation of delegates, this must be close to the worst attempted explanation.

The first line introducing design patterns reads, “A design pattern is a pattern—a way of pursuing an intent—that uses classes and their methods in an object-oriented language.” If you think the author then expands on that nebulous description, you’d be wrong. That description is provided in the introduction, before the first chapter provides the needless review of C#. The second chapter then delves right into the Adapter pattern. No more explanation of design patterns is provided. And, unless I mistaken, that description is rather inaccurate.

Can I pick on the analogies too? Please let me.

To explain the Decorator pattern, the wonderful Head First Design Patterns book chooses the analogy of ordering coffee. A customer might order a coffee. Or the customer might order a coffee with cream. Or the customer might order a coffee with cream and sugar. Or the customer might order a coffee with cream and sugar and a cinnamon stick. Now, even if you don’t know what the Decorator pattern is, the progressively “added to” nature of this short description would give you a clue to what the Decorator pattern does.

To explain the Decorator pattern, the horrible Design Patterns in C# book chooses the example of streamwriters. Never mind that a developer who is learning design patterns is surely unfamiliar with the concept of streamwriters, even those who do know what a streamwriter is may have a hard time visualising how one stream can wrap another. I know it’s a common analogy, but it’s a dumb one.

The ongoing analogy in Head First Design Patterns is that of a diner. So we have coffee to illustrate the Decorator pattern, pizza to illustrate the Factory pattern, and a menu to illustrate the Iterator pattern. Every developer in the world, no matter how inexperienced, knows about coffee, pizza, and menus. A good choice for analogies then, wouldn’t you say?

The ongoing analogy in Design Patterns in C# is that of a company that produces rockets. For some reason, the company is named Oozinoz. I have flipped open to a random diagram using this analogy. It shows a Firework inheriting from a Rocket, and then asks, “What’s wrong with this picture?” Well, given that I’ve never gotten too close to a rocket or a firework, I can’t exactly say. (In Australia, we don’t mess around with fireworks. The only person I knew who did, put the thing in his pants pocket, and now he is called “char bar.” True story.) On another page, we see a diagram with a ShowBallistics class (no idea what that is), a PlotPanel class (nope, no idea), and a TrackBar (dunno that one, either). I think someone needs to tell the author that an analogy needs to be both simpler and more familiar than the concept it is trying to represent.

Figuring that the design patterns themselves might be the saving grace of the book, I attempted to look up how to apply the Model-View-Controller pattern to a .NET application. Nope, Design Patterns in C# made only passing mention to this oh-so-common pattern. So I went back to the Head First Design Patterns book. Sure enough, it provided good coverage of the MVC pattern using the analogy of an MP3 player. Even more impressive, the book discusses how this pattern is altered to work in the context of a web-based application, where it is known simply as Model 2 in the Java world.

Okay, I have provided a harsh review of this book. This is partly because I feel cheated out of $60. It is also partly to ensure that any C# developer who wants to learn design patterns (and who somehow stumbles upon this weblog entry) will give this book a miss, even if it is the only book with both Design Patterns and C# in its title. If you’re a C# developer and you want to learn about design patterns, then Head First Design Patterns is the book to buy.

by Alister Jones | Next up: The Architecture - Part 2

0 comments

----

Head First Design Patterns

by Alister Jones (SomeNewKid)

This is it. This is the best programming book yet written. It has the dorkiest cover possible for a programming book, and if you were to flip through it in a bookstore you’d put it back on the shelf. This book looks different. This book is different—it is better than everything else out there.

Even in its introduction, the authors admit, “We know what you’re thinking. How can this be a serious programming book? What’s with all the graphics? Can I actually learn it this way?” The answer is an emphatic yes. In my last weblog entry, I said that I remember virtually everything I read in this book, even though I read it over six months ago. This is because the book teaches you about software design patterns, when other books merely tell you about design patterns.

In the middle of last year, I didn’t really understand software design patterns. The phrase came up so often that I kind of absorbed a weak understanding of what patterns were about. But I didn’t truly understand them, and I certainly never applied them. Then, as a birthday present, a book arrived in the mail. In the card, the sender said that I liked programming and I had a soft spot for pretty ladies, so a computer book with a blonde babe on the cover seemed to be the perfect present for me. She was right. It was the perfect present, because it is the perfect book: Head First Design Patterns.

I read this book from cover to cover. How many programming books are so interesting and so easy to read that you can actually make it the whole way through? I have 29 programming books on my shelf beside me, and there may be a couple more in my bedroom. But only two of these books were so well written that I read the entire book. (The other was Designing with Web Standards.)

Anyway, I think you get the picture. This is an excellent book! If you want to learn about design patterns, buy this book. If you want to improve your programming, buy this book. If you want to see how a computer book should be written, buy this book.

My only disappointment is that it uses Java as its language for code samples. My disappointment is not because I happen to use C#, but because the other books in the Head First series look at Java specifically. Oh, how I would love for the Head First team to write some .NET books. I have twelve books about .NET, and I feel sure that I don’t understand .NET half as well as I would understand Java if I read just those three Head First Java books. I will say it again, the Head First approach is to teach you the topic, not to merely tell you about it. And that means you actually learn the topic, and not merely know about the topic.

Charlie’s final design uses a number of design patterns, thanks solely to the Head First team.

by Alister Jones | Next up: Design Patterns in C#

0 comments

----

Applying UML and Patterns

by Alister Jones (SomeNewKid)

After reading The Object Primer and Building Object Applications That Work, I still felt that I was not truly understanding object-oriented programming. My last shot was to read Applying UML and Patterns. This book is a lot better than the first two, but it still makes what I believe is a fundamental mistake in its approach. Its mistaken approach is to tell me what to do, when the right approach is to teach me what to do. This mistake is made by most programming books, so it may seem unfair to criticise Craig Larman. However, the next book I will talk about takes the right approach, and the difference between the two books is huge.

As I write this, I have both books at my side. Because I am writing a number of blog entries in order to bring the story of Charlie up to date, I have been flipping through these books to remember what precisely I learned from them. As I flipped through Applying UML and Patterns just now, I thought to myself, “I don't remember any of this. Did I really read it?” Well, I did read it, and only about six weeks ago! I then picked up the other book, which I will talk about in my next weblog entry. As I flipped through it, I thought to myself, “I remember all of this! Was it really six months ago that I read it?”

I have been thinking about why I remember virtually everything in a book I read six months ago, and virtually nothing from a book I read six weeks ago. They both cover the concept of design patterns, so the difference is not in the material. The difference is in the approach. Larman’s book tells me what to do. The other book teaches me what to do.

But in fairness to Craig Larman, I did get some ideas out of Applying UML and Patterns, just as I got some ideas out of Scott Amber’s two books.

First, the book provides a helpful overview of the technique suggested by Russell Abbott regarding how to identify objects. If we look at a written description of the use of our software, the nouns in that description are candidates for the software’s business objects. By way of example, here is a description of how a web surfer may use a Charlie website:

“The user can view an article and leave a comment.”

Pretty simple, huh? However, if we highlight the nouns in that description, we have very good candidates for business objects:

“The user can view an article and leave a comment.”

While I already knew about this approach, the approach is so simple yet so helpful that it represents one of the highlights of the book.

The real strength of the book however is its categorisation of design patterns.

It has been said that there are only three original stories in the world. (In truth, I cannot remember the precise number, but it was a very small number.) Every story ever told is a variation on one of these three original stories. (For example, every crime story is a variation of the “good versus evil” story, and every romance story is a variation of the “love versus adversity” story.)

The insight provided by Craig Larman in his book is that there are nine basic software design patterns (what he calls the nine GRASP patterns). All design patterns are a variation on one or more of these nine basic design patterns, just like all stories are a variation on one of the three basic stories. By distilling the plethora design patterns down to just nine, Craig has brought order and meaning to the ever-expanding topic of software patterns.

Even better, Craig focuses on why these patterns exist. Understanding why patterns exist is crucial to applying patterns. If a developer applies the Model-View-Controller pattern because all the cool kids seem to be doing it, then he has misused the pattern. Conversely, if another developer understands why the MVC pattern exists, then she may come up with a unique twist to the pattern that is precisely right for her application. A pattern is not meant to be cookie-cutter answer to a software problem. A pattern is meant to be kneaded, rolled, and massaged until it produces an appropriate solution to a specific problem.

I should point out that even though the book talks about a number of well-known design patterns, this is not the right book by which to learn design patterns. If a developer already knows about patterns, then the categorisation of all patterns into the nine basic GRASP patterns will be helpful. But if a developer does not already know about patterns, I doubt he or she will be much the wiser after reading this book.

Finally, a warning. This book is even more forceful in its promotion of UML and the Agile development process than the books by Scott Ambler. I guess that’s excusable, since UML is in the book's title. But if these authors are trying to promote UML and Agile development, they are doing a poor job of it. They make UML and Agile development out to be monstrously complex. In a Peanuts comic, Charlie Brown says that the secret to life is to replace one worry with another. That seems to be an apt description of UML. Take the worry of software design, and replace it with the worry of UML. No thanks, and please stop trying to sell me on the idea.

by Alister Jones | Next up: Head First Design Patterns

0 comments

----

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

----

The Object Primer

by Alister Jones (SomeNewKid)

In my last weblog entry, I explained that I had decided to go back to basics and learn the true fundamentals of object-oriented programming.

The first book I purchased was The Object Primer, by Scott Ambler. As you will see from its list of contents, this book would have been more aptly named The Agile Primer. Or maybe, Yet Another Sales Pitch for UML.

Maybe I don’t understand book publishing (after all, I’m not in that industry), but if someone writes a book titled The Object Primer, you’d kind of hope that it talks mainly about the objects of object-oriented programming. If I wanted to learn about Agile development or UML, I’d have bought a book with a different title. The argument could be made that object-oriented programming and UML go hand-in-hand. I disagree: they can, and should, be separated in a book that purports to be a primer on objects. If a book were to explain the cells that make up blood (a reasonable analogy to the objects that make up OOP), then it can and should talk about cells and blood, and not about the Petrie dishes and microscopes that allow us to see the cells (the “tools” of blood, just as UML is a tool of OOP).

So The Object Primer provided a bit of a refresher on the topic of objects, but certainly did not explain anything that I did not already know. If anyone else is hoping to learn the true fundamentals of object-oriented programming, I would not recommend this book.

by Alister Jones | Next up: Building Object Applications That Work

0 comments

----

Will Charlie be Open-Source?

by Alister Jones (SomeNewKid)

Yesterday I wrote a weblog entry entitled, Charlie Takes Inspiration from Cuyahoga. Today the creator of Cuyahoga, Martijn Boland, sent me an email wherein he explained why he switched from using a handwritten Data Access Layer to using NHibernate. His goal with Cuyahoga is to support multiple platforms (Cuyahoga runs on .NET on Windows and Mono on Linux) and to support multiple databases. Martijn explained that the original plan to write multiple data providers that all implemented the same interface was, quite simply, a mistake. In Martijn’s own words, “For multiple database support, the provider pattern just doesn’t work.” The addition of NHibernate to Cuyahoga allowed him to achieve his goal of supporting multiple databases.

I have decided to use this example of NHibernate and Cuyahoga to answer the question, “Will Charlie be open-source?”

My first instinct was that yes, Charlie would be open-source. I have learned so much from the open-source projects contributed to the community by Martijn and similarly-smart jellybeans that I would love to give something back to the same community. If somebody could use Charlie to make a client happy, then that would be great.

But I have a few very real concerns about what would happen if I take the open-source approach. At the crux of each concern is that I plan to adhere to the advice from an aarvark that simple is better than complicated.

My first concern is that genericity leads immediately to complexity. If Charlie is provided as an open-source solution that multiple developers can use, then it needs to have some genericity built-in. Cuyahoga, for example, supports mutliple developers by supporting multiple databases. To achieve this goal required that the original handwritten Data Access Layer be replaced by NHibernate. The original handwritten DAL was so simple that even I could understand it and work with it—and believe me, my SQL skills are laughable. The transition to NHiberate was right for Cuyahoga and its goals, but is at odds with Charlie’s guiding principle that simple is better than complicated.

My second concern is that making Charlie open-source would limit (prohibit?) the use of commercial components. I have available a licence for telerik’s RadControls product and for ComponentArt’s WebUI product. If Charlie is provided as an open-source solution, it cannot use these best-of-breed components, and must instead use open-source components. Typically, commercial components are not only better than open-source options, but also much simpler to use. In this regard too, making Charlie open-source would mean that Charlie is at odds with its own principle that simple is better than complicated.

My third concern is that most developers like gimmicks, and I do not. (I am a designer first, a programmer second.) DotNetNuke for example uses the SolPart menu system whose fades and flips and farts appease developers, but horrify designers. Having crap like that added to Charlie would be to ignore the guiding principle that simple is better than complicated.

My final concern is that even if Charlie were open-source, no-one would use it. That would mean I had forced Charlie to endure the complexity of genericity, and to ignore best-of-breed commercial components, and for nothing. After all, there are many open-source website frameworks available for ASP.NET. Why add another one to the mix?

My current resolution is that if anyone wants to see the source of Charlie, I will send it to him or her. If that person wants to look at it, learn from it, play with it, or laugh at it, he or she can have it. If Charlie ultimately remains closed-source, it will not be the result of selfishness or competitiveness. Rather, it will be the result of my holding the principle of simplicity even higher than the principle of open-source.

If anyone reading this weblog entry truly understands open-source philosophy (which I do not purport to understand), and knows that I have made a logical error above, then please feel free to correct me.

by Alister Jones | Next up: The Object Primer

1 comments

----

Back to Basics

by Alister Jones (SomeNewKid)

I am an active participant in the ASP.NET Forums. One of the things I have noticed is that there is a huge difference between developers who understand the underlying technologies such as HTTP, HTML, JavaScript, and CSS, and those who do not. Those developers who do understand these basic technologies are able to pull their head out of the ASP.NET sand, and look around to find the simplest solution to a given problem. Conversely, those developers who do not understand these basic technologies are held hostage to Visual Studio or whatever program they use. They will peek and poke about in the IDE, hoping to find a command that looks vaguely promising.

It can be argued that an ASP.NET developer should not need to know these underlying technologies, just as a Windows Forms developer should not need to know how what a pointer is. But this argument does not hold due to the Law of Leaky Abstractions. Sometimes the right answer to a problem lies in these underlying technologies. But the IDE is working so hard to hide these underlying technologies that it ends up hiding the answer, too.

One of the lessons I learned from Cuyahoga is that developers can also be split between those who understand the fundamentals of object-orientation, and those who do not. Once again, Visual Studio and similar programs tend to hide the details. We tell Visual Studio to create a new class, and one appears. We then spend many minutes, or even hours, putting code into that empty class. Because the class appears instantly, and our code takes a long time to create, we can be mislead into believing that our code is all-important, and the class is merely a container for the code.

By way of example, an ASP.NET developer can tell Visual Studio to create a new .aspx web form, and one instantly appears. We type some code into its Page_Load method, and it all magically works when we request that page in a web browser. Visual Studio is hiding the fact that the .aspx web form inherits from System.Web.UI.Page, implements System.Web.IHttpHandler, and responds to the Control.Load event through its Page_Load delegate. That is, Visual Studio is hiding inheritance, an interface, an event, and a delegate—some of the most fundamental aspects of object-oriented programming in .NET.

Once again it can be argued that an ASP.NET developer should not need to know about all this background stuff. If the developer is creating a website to report on his Half-Life clan, what does he care if the .aspx page inherits its behaviour from System.Web.UI.Page or from Paris Hilton? (If you scour the internet, you can learn of the behaviour of each.) Once again though, sometimes the right answer to a problem lies in these underlying constructs. But the IDE is working so hard to hide these underlying constructs that it ends up hiding the answer, too.

I should note at this time that I am not blaming Visual Studio—it does its job very well. What I am saying is that it is vitally important for developers to know when to put Visual Studio to one side, and look at the fundamental technologies and constructs that Visual Studio hides from view.

Cuyahoga’s clever use of the basic principles of object-orientated programming made me realize that I did not have a professional’s grasp of these basic principles. Cuyahoga’s creator, Martijn Boland, was able to solve, in a simple yet flexible way, problems that I would have been hard-pressed to solve, simply because he demonstrated a solid grasp of the basic principles of object-oriented programming. I decided then that the final research step before commencing Charlie would be to truly understand object-oriented programming, by going back to basics.

by Alister Jones | Next up: Will Charlie be Open-Source?

0 comments

----

Charlie Takes Inspiration from Cuyahoga

by Alister Jones (SomeNewKid)

Four years ago, I had no programming experience beyond creating a handful of scripts for Lotus 1-2-3 many years earlier. The design company I worked for decided that it needed a website. Because I was the resident “computer nerd,” the task fell to me to create the website. With HTML 4 for Dummies at my side, I created the REB Design website. Feeling proud of myself, I went on to create the website for Modular Shades & Shutters.

As many of REB’s clients were retailers, I suspected that we’d soon be asked to create a website with a shopping cart. I telephoned our ISP and asked them what we needed to do in order to have a shopping cart on a website. “Learn CGI,” I was told. In my bookshelf to my left, the cover of Learn Perl in a Weekend glistens, its spine barely broken. Our networking contractor happened to see me messing about with Perl, and recommended that I learn ASP instead. A few weeks later, another computer contractor happened to see me messing about with ASP, and recommended that I learn ASP.NET instead. (I suspect that if another computer contractor had walked in around that same time, I might be using Java today.)

I worked through ASP.NET for Dummies, and then ASP.NET Unleashed. Feeling that I had a grasp of the basics, I felt it was time to learn how to put all the pieces together to create a full ASP.NET website. I downloaded the IBuySpy Portal starter kit and then, .vb file by .vb file, re-created the starter kit from scratch. If I came across some code that I did not understand, I would research the topic until I understood what that code was doing. Only then would I add it to my re-created portal website. I did not re-create the entire starter kit, but enough for me to understand how it did its thing.

This is a little bit of background that will explain the next stage in the life of Charlie.

In late November, after Charlie’s hiatus, I had finished reading through Coder to Developer and Code Complete. I had created my Feature Set, Software Specification, and broad Architecture. But I still did not know how to start. As you will see from my background, my only “development” experience has been to download the IBuySpy Portal, pull it apart, and put it back together. I decided to do the same thing again, just to see how someone else had gone about developing a website framework.

I looked at a number of open-source website frameworks, and decided upon Cuyahoga. I contacted its author, Martijn Boland, and asked whether he had an archived version of Cuyahoga 0.1. I explained to him that I wanted to re-build it from scratch, to learn how he had started Cuyahoga. Martijn provided a link to the first version of Cuyahoga and, like any inquisitive kid, I immediately pulled it apart to see how it worked. Then, I re-created it from scratch. Rather than re-creating it line-for-line, which I did with IBuySpy Portal, this time I added my own twists.

I learned four main things from re-building Cuyahoga version 0.1, which have had a substantial impact on the way Charlie has since developed.

First, I learned the value of Reflection. To a self-taught developer, it can be hard to understand the benefit of Reflection. After all, we code these classes, we know their methods and properties, so why on earth would we need to use Reflection to learn what we already know? Well, the answer is that we use Reflection when an application does not already know about a class and its methods and properties. This would be the case when we plug a new component into an existing application. The application can then use Reflection to inspect the plugged-in component and make use of that component. Put another way, Reflection means that once we have created the main application, we can create plug-in components without having to go back into the main application and change its code.

Second, I learned the value of Interfaces. I already knew what an interface was and why we use them, but I had never truly known when to use an interface. Like Reflection, the answer is we use an Interface when we do not already know what specific class we will be using. Reflection and Interfaces work hand-in-hand to allow an application to make use of plugged-in components. When we plug in a new component, Reflection allows an application to find any new class and create an instance of that class, and its Interface allows the application to use that new class. For anyone who would like an introduction to interfaces, I wrote what I hope is a neat little example on the ASP.NET Forums: Why does the .Net Pet Shop 4.0 use so many interfaces?

Third, I learned the value of Composition. Again, I already knew what composition was about, but I had not really known when to use it. Textbooks tell us that we use inheritance when one class “is a” type of another class (a Car “is a” type of Vehicle), and use composition when one class “has a” type of another class (a Car “has a” type of Engine). That’s fine for textbooks which use real-world objects. But when the code is dealing with fabricated objects (objects that do not exist in the real world), it is much harder to know when to use composition over inheritance. Cuyahoga’s business objects used composition in a way that was easy to follow and easy to appreciate.

Fourth, I learned the value of O/R Mappers. Here though, I decided that the value of an O/R Mapper was nil. Version 0.1 of Cuyahoga provided a typical Data Access Layer that used the familiar Command.ExecuteReader method to retrieve data and put that data into business objects. But version 0.2 and later of Cuyahoga uses NHibernate. The simple Data Access Layer Component was banished, to be replaced by dozens of XML files in amongst the business layer objects, and lots of code to support NHibernate and its sessions. Frankly, I cannot see the benefit. Database access code may be boring to write, but it leads to code that is very simple, and provides a single point at which we can tweak data access (such as minimising the number of trips to the database). One piece of advice from the Aardvark is that simple is better than complicated. I agree, so I decided that Charlie would eschew O/R Mappers and instead use a simple, handwritten Data Access Layer.

Having re-created version 0.1 of Cuyahoga, I felt that I had a much better understanding of how Charlie would be designed. A number of ideas had started forming, and I decided that with just a little more research, I would be truly ready to embark on creating Charlie. I’ll talk about that research in my next post.

Let me close by expressing my true gratitude to Martijn Boland for contributing Cuyahoga to the open-source community. I learned an enormous amount by working through its code. Thank you, Martijn.

by Alister Jones | Next up: Back to Basics

0 comments

----

Charlie’s Hiatus

by Alister Jones (SomeNewKid)

It has been many months since I last updated this blog.

I have been quite undecided as to whether to explain the reason why Charlie was put aside for a while. It has all the makings of a fun story: alcohol, nudity, deception, and betrayal. However, one of the principals of the story would be humiliated (no, no, not me; I’d be the protagonist of the story). While this person is someone I now despise for her duplicity, deliberately embarrassing her would mean that I have no more principles than she does. And anything less than the truth is, to my mind, a lie. I do not want to lie.

I can only say then that Charlie slept from September through November last year.

Starting with my next post, I will resume the story of Charlie.

by Alister Jones | Next up: Charlie Takes Inspiration from Cuyahoga

0 comments

----

Advice from an Aardvark

by Alister Jones (SomeNewKid)

Charlie has not progressed during the last two weeks, due to illness (my illness, not Charlie’s). However, during this period I received notice that one of my favourite writers on software, Joel Spolsky, had kindly made available the software specification for a project he codenamed Aardvark. Inspired, I wrote a software specification for Charlie, which you may download.

While I have never before seen a software specification, the process of writing one crystallised a few goals that I had for Charlie, the most important of which I unashamedly copied from the Aardvark:

“Simple is better than complicated.”

What is most helpful about this principle is that it helped define non-goals for Charlie. For every feature of Charlie, I will need to decide between a complicated yet swish implementation and a simple yet rough implementation.

Take for example the feature of Charlie to serve multiple websites from a single installation. How would I add a new website to an existing installation? The complicated yet swish implemenation would be to provide a web or desktop interface, through which I complete a few details and upload a few files. The simple yet rough implementation would be to manually add an entry to a site.xml configuration file, and manually FTP transfer a new folder into a directory named ‘sites’. I see no value in spending time creating a swish interface for the developer; that time should be spent making Charlie as simple as possible for the website owner (whom I have identified as the most important user of Charlie).

Take for a second example the feature of Charlie to style websites. How can I design Charlie so that two websites that are functionally similar will look completely different? The complicated yet switch implementation would be to introduce a system of themes and skins, configurable through an interface. The simple yet rough implementation would be to hand-craft some CSS stylesheets. Again, I see no value in creating a system of configurable themes and skins—a website owner will not care how his website is styled, but will care only that it looks good, works well, and reflects the corporate identity.

Simple is better than complicated.

The process of writing the specification for Charlie helped define its four main features. More accurately, perhaps, is that the process helped define those features that would be hard to add retrospectively and, hence, should be added to this first version of Charlie.

The first feature is that Charlie will be simple. I will have more to say on this topic in future weblog entries, so I will not say more about it now.

The second feature is that Charlie will be secure. This is a matter of necessity and responsibility. If Charlie is to serve multiple websites from a single installation, and allow website owners to maintain and edit their own websites, then Charlie must provide a secure environment for the website owner.

The third feature is that Charlie will be globalized. I have been approached previously to create a globalized website, but at the time I did not know how to create one. The next time I am asked, I want to be able to accept the job. Additionally, globalization would be hard to add retrospectively, so I’ll add this feature to Charlie from the start.

The final feature is that Charlie will be configurable. While Charlie is to serve multiple websites from a single installation, each website should be unique in its operation and its appearance. I also want for Charlie to be able to provide turnkey website solutions, such as Clikpic. While turnkey website solutions will not be implemented until a later version, the required configurability should be in place from the start.

Writing the specification for Charlie took very little time, yet it definitely helped define the goals and non-goals for Charlie. It was a valuable exercise, and I extend my thanks to Joel and his Aardvark.

by Alister Jones | Next up: Charlie’s Hiatus

0 comments

----

Getting Started by Getting Agile

by Alister Jones (SomeNewKid)

In an earlier weblog entry, I stated that I had become frustrated with Coder to Developer. I felt that the author breezed past areas that deserved attention, and slowed down and addressed areas that did not need attention. By way of example, the author writes, “There is a valuable discipline of software architecture, and for even small projects it remains a good starting point,” and then pulls from his hat an architectural diagram. Where did it come from? How did he arrive at it? To me, that is as useless as a cooking book that provides a list of ingredients on one page, a photograph of the finished dish on the following page, with no pages in between providing the cooking instructions.

I put Coder to Developer to one side, and started reading Code Complete by Steve McConnell. In the first two parts of the book, the author talks about the value of planning and the basic approach to application design. The operative word there is basic; this is not the how-to book that I yet hope to find. Still, any guide is better than no guide, so I again put pen to paper and started designing Charlie.

As my diagrams became more involved, I felt increasingly that I was not planning, but guessing. I felt that I simply do not have the experience necessary to know what designs would work, and what would not. I still believed that I could make Charlie a first-class application, but not by designing too much of it up-front.

Inertia set in.

A few days later I happened to purchase the Australian edition of International Developer magazine. In it was yet another article on Agile development. I scanned the article, and upon viewing two diagrams I had an “ah ha” moment. The diagrams were as follows.


Above: The Traditional Development Process


Above: The Agile Development Process

For two reasons, these diagrams spoke to me in a way that all prior articles on Agile development had not spoken to me. First, while I had understood the frequency of Agile’s iterations, I had not appreciated the changing scope of those iterations. Second, my own application had already stalled in the design phase, and I could not see how to move foward.

Agile development was offering a solution to my problem. The second diagram above whispered in my ear that it was okay to design only a part of Charlie, and then build it, test it, and deploy it. Having done so, I could increase the scope of Charlie's design, without having to guess at what more the design would need. This concept of iterative development of increasing scope was the motivational force I needed to overcome the inertia that had set in.

Now, I am not suggesting that I have decided upon an Agile development methodology. I still do not sufficiently understand it to suggest that I am applying it. But I am happy to prise from Agile a gem of an idea, and give it to Charlie.

by Alister Jones | Next up: Advice from an Aardvark

0 comments

----

Source Code Control for Dummies

by Alister Jones (SomeNewKid)

In a previous entry on source code control systems, I admitted that I was not smart enough to download CVS, to install SourceGear Vault, or to use Visual SourceSafe. I felt pretty dumb.

Fortunately, a reader suggested that I try Subversion with a TortoiseSVN interface. These two tools work together beautifully, and provide source code control for dummies like me (which is not to suggest that Subversion is somehow lightweight).

Get this, rather than presenting me with a download folder full of 102 files with cryptic names, like CVS, the Subversion home page actually told me which file I’d most likely need.

Get this too, rather than asking me annoying questions during the installation, like SourceGear Vault, the Subversion and TortoiseSVN installations made their own smart decisions.

Get this three, rather than providing brief and unhelpful instructions, like Visual SourceSafe, the TortoiseSVN client provides extremely easy to read, yet thorough, documentation.

So I now have in place a source code control system that is a joy to use. TortoiseSVN integrates with Windows Explorer so that it provides up-to-date visual feedback regarding the status of my files. It does this by overlaying status symbols upon file and folder icons.

Unlike Visual SourceSafe, Subversion does not work by locking files. I am free to create, edit, and delete files and folders in the same way that I have always done. Whereas Visual SourceSafe would force me to change my style of working, Subversion and TortoiseSVN stay out of the way until I call upon them. I am impressed by their power and pleased by their simplicity.

Thank you, Jeremy Miller, for the recommendation.

by Alister Jones | Next up: Getting Started by Getting Agile

0 comments

----

To Hell with Coder to Developer

by Alister Jones (SomeNewKid)

My intentions were good.

I needed to create a web-based application, and I resisted the temptation to fire up a code editor and get going. Instead, I purchased Coder to Developer with a view to starting off down the right path.

The book has not helped. The author skims over the aspects of software development that cause me the greatest concerns, and focuses on the aspects of development that Google will tell me for free. Skimming through the remaining chapters of the book, I see that it provides little more than a listing of tools and utilities, all of which I already know about thanks to free resources.

What a waste of money and time it has been.

by Alister Jones | Next up: Source Code Control for Dummies

0 comments

----

Source Code Control System

by Alister Jones (SomeNewKid)

The third chapter of Coder to Developer recommends the use of a source code control system. After hours of effort, it is evident that I am not smart enough to use a source code control system.

The first system I endeavoured to try was CVS. I followed the download link and came to a page listing 102 files. I had no idea whether I needed all of them, some of them, or one of them. I could find no documentation telling me what I needed to download. I figured that if the product was presented such that I could not even install it, I didn’t stand a chance of being able to use it.

The second system I endeavoured to try was SourceGear Vault. Even though its download page was not much better than that of CVS, I managed to download the installation file. I even managed to install the product, but it would not run. After a few efforts at reinstalling it with different settings, I gave up.

The third system I trialled was the Beta of Visual SourceSafe 2005. It installed without issue and ran without issue. However, after toying with it for an hour or so, I could not succeed in branching and then merging file versions. As I am a single developer, the main attraction of a source code control system was the ability to branch and then merge file versions.

Right now I am feeling pretty dumb. CVS is apparently in wide use, and I cannot even install it. VSS is apparently a simple source code control system, and I cannot even work with it.

Sigh...

by Alister Jones | Next up: To Hell with Coder to Developer

0 comments

----

Providing Charlie with an Extended Framework

by Alister Jones (SomeNewKid)

I am a self-taught developer. Because I have no formal training in programming, there are fundamental aspects of development that cause me great confusion. The greatest cause of confusion is the “where does it go” question that is the province of architecture and design.

Let me provide a simple example. Let’s say that I decide that I need to extend the ArrayList so that it supports automatic sorting of members (or use Peter Blum’s free AutoSortArrayList). Where does such a fundamental class go? It does not belong in the presentation, business, or data access layers. It is a utility class that could be used by any class in any layer. So where does it go?

Let me provide a different example. Let’s say that I have decided to use Paul Wilson’s ORMapper. As I am a subscriber to Paul’s WilsonDotNet.com website, I have the source code for the mapper. Where does the source code go? If I stick it within my own Data Access layer, then I am mixing my own code with third-party code. What happens if I decide that I’d rather use NHibernate? I need to rip out one set of third-party code and put in its place another set of third-party code, and then update all of my own code to make use of the new OR Mapper. This cannot be how seasoned developers work. So again, where does it go?

To solve this problem (or perhaps to avoid it altogether), I have decided to introduce a layer between the .NET Framework and my Charlie application. Any component that extends the .NET Framework in a generic way (not specific to Charlie) goes into this new layer. As the standard .NET Framework Class Library uses the System namespace, this extended class library will use the XSystem namespace.

Let’s return then to the example of the AutoSortArrayList. As the standard ArrayList is within the System.Collections namespace, I place the AutoSortArrayList within the XSystem.Collections namespace. What I would do is create a new AutoSortArrayList class that simply inherits from Peter Blum’s class. That way, I get the namespace I want, and I get the opportunity to extend his code if I care to.

Let’s return to the example of the ORMapper. As Paul’s component was based on the original design of .NET 2.0’s ObjectSpaces, I would elect to place it within the XSystem.Data.ObjectSpaces namespace. I then create a facade to Paul’s component. That way, I get the namespace I want, and I get the opportunity to extend his code if I care to. This also means that I can easily swap in a updated version of Paul’s component. I could also replace Paul’s component with NHibernate and change my facade class so that NHibernate works like Wilson ORMapper. This would minimise or eliminate any changes required in the Charlie application.

Another example is that I may find that I’d rather use Paul Wilson’s MasterPages component rather than the MasterPage class built into ASP.NET version 2.0. Charlie can simply switch from using the System.Web.UI.MasterPage class to using the XSystem.Web.UI.MasterPage class. What could be easier?

This is why, when designing Charlie, I will strive to distinguish those components that are application generic (they go into XSystem) from those components that are application specific (they go into Charlie).

by Alister Jones | Next up: Source Code Control System

0 comments

----

Why the Wonky Wheel?

by Alister Jones (SomeNewKid)

If you are new to this blog, here is what I plan for my application named Charlie:

“Charlie is a web-based application that simplifies the creation, maintenance, and use of websites. For a website developer, Charlie simplifies the process of creating and updating a website. For a website owner, Charlie simplifies the process of maintaining and editing a website. For a website user, Charlie simplifies the process of navigating and using a website.”

It is reasonable to ask why I have decided to build Charlie from scratch when there are existing solutions that purport to do the same thing. For ASP.NET, a popular open-source solution is DotNetNuke. Why am I not using DotNetNuke? Because I hate DotNetNuke.

First, I am a designer by trade, and I find DotNetNuke websites to be among the most sinfully ugly websites ever created. I have little interest in a framework that is trying to pull my websites in the direction of ugly, while I must use its skinning capability to pull the websites in the direction of beauty. The framework should be helping me, not playing a game of tug-a-war against me. Sorry, but DotNetNuke is just too damn ugly.

Second, I find DotNetNuke websites to be among the slowest websites anywhere. Far too many DotNetNuke websites time out. The HTML payload of DotNetNuke sites is comical. The Media Releases page for DotNetNuke weighs in at 35kb, of which only 8.5kb is viewable content (a 25% content to HTML ratio). If we include image, script, and stylesheet files, the media releases page for DotNetNuke weighs in at a staggering 177kb (a 5% content ratio). The CSS page for A List Apart weighs in at 13kb, of which 5.6kb is viewable content (a 44% content to HTML ratio). If we include image, script, and stylesheet files, the CSS page weighs in at 53kb (a 10% content ratio). So while the DotNetNuke page provides 50% more content than the A List Apart page, its uses 300% more HTML than the A List Apart page. Sorry, but DotNetNuke is just too damn bloated and too damn slow.

Third, DotNetNuke produces highly invalid HTML. The homepage for DotNetNuke produces 133 HTML errors, 62 CSS errors and 47 CSS warnings, and fails 508 and WCAG compliance. Sorry, but DotNetNuke is just too damn invalid.

Fourth, DotNetNuke is apparently very hard to use. I am a moderator of the forums on www.asp.net, and I have seen users struggle to get DotNetNuke to do the simplest of things. There are almost 20,000 threads in the DotNetNuke forums, most of them started by users who cannot get DotNetNuke to do what they need. Sorry, but DotNetNuke is just too damn hard to use.

There are other things too that I dislike about DotNetNuke; but I will not go on. The point of this blog entry is not to bash DotNetNuke—it is loved by many developers. The point of this blog entry is to state why it is that I am building what others may say has already been built.

by Alister Jones | Next up: Providing Charlie with an Extended Framework

1 comments

----

The Architecture - Part 1

by Alister Jones (SomeNewKid)

In the second chapter of Coder to Developer, Mike Gunderloy starts talking about architecture. I would have thought that in a book guiding coders to becoming developers, a significant portion of the book would be dedicated to architecture and design. After all, is that not one of the main distinctions between coders and developers? Apparently not, because the author dedicates only three pages to architecture, and then three pages to design (by way of patterns).

I have searched high and low for a book or website that walks a developer through the steps of creating a valid architecture. I have found no such resource. Is that an indication that there is no discernible approach to architecture and design? I cannot believe that that is the case.

The best resource I have found so far is a document provided by Microsoft’s Patterns & Practices team: Application Architecture for .NET: Designing Applications and Services. While it provides lots of great information, it is not the how-to guide that I have been hoping to find.

Having found no how-to guide for architecting and designing a software application, I decided that I would simply give it my best shot. I placed a pad of graph paper on my desk, and placed my list of features to its right (I’m left-handed).

The first decision I made was that there is nothing special about Charlie that warrants moving outside the traditional three-layer architecture. So I drew three horizontal lines across my page and titled the sections Presentation, Business, and Data Access. Then, referring back and forth to the feature set, I came up with the following first draft. Assets are business objects such as blog entries, articles, and photographs.

Having drawn the first diagram, I evaluated it.

To start with, I was not sure whether the OR Mapper was in the right place. Does an OR Mapper replace the Data Access Logic Components (DALCs)? Does an OR Mapper complement DALCs? Does one comprise the other? I had, and still have, no idea. So why is it there? Simply because I have one (Paul Wilson's ORMapper) and because I dislike SQL. Granted, they are not good reasons for an OR Mapper to be there, but I thought that if I put it in the diagram, it will mean that I later investigate its possible use in Charlie.

I was also concerned about the location of the modules in the Presentation layer. I see the modules working the same way as modules work in DotNetNuke, which I know to be based around the concept of ASP.NET User Controls. So, my initial thought was that my modules therefore belonged within the Presentation layer. But I knew this to be incorrect. A module such as a blog must coordinate presentation, business, and data access activities. I also wanted each module to be able to use its own data source. So, where do modules go?

I also noticed, with some embarrassment, that even though Charlie is to be a website framework, I had not included the websites themselves. They too need to span presentation, business, and data access concerns. So, where do the sites go?

To address the question of modules and sites, I came up with the following second draft.

Having drawn the second diagram, I evaluated it.

It was a poor design, and I knew it. Separating the application into three layers of separate concerns (presentation, business, and data access) is a proven technique. But separating the application along a second arbitrary axis (framework, sites, and modules) created a matrix that would complicate development, not simplify it.

Yet, I somehow had to come up with a way in which I can plug in new websites and new modules, all of which need to span all three layers of the application. How?

The first step towards answering this question involved recognising that plug-in modules and plug-in websites represent the same problem. That is, each plug-in type must span all three layers. Whatever design solved the problem for modules would solve the problem for websites, too. I need not address modules and websites separately.

I started drawing a new diagram that did not involve the horizontal split of framework, sites, and modules. I could see only one possible way of getting sites and modules into the architecture in such a way that they spanned all three layers, which I illustrated in the following diagram.

Having drawn the above diagram, I evaluated it. I’ll point out that the OR Maps are not necessarily the XML-based mapping rules common in OR Mappers. Rather, I saw them as likely being classes that took the properties of the assets of the module (such as the title, abstract, and body of an article asset) and created a DataTable or DataSet that could be passed to the Data Access Logic Components (DALCs). Admittedly, the above diagram does not include the DALCs, as I was concentrating on how the websites and modules could be incorporated into the architecture.

I felt that the above diagram was heading in the right direction. A module would comprise a presentation package of User Controls, images, stylesheets, and so on; a collection of assets and the logic that controls them; and classes that mapped back and forth between the object-oriented assets and data-centric DALCs. A website too would comprise a presentation package, a collection of assets and logic, and classes that mapped from the objects to the XML configuration files.

I then turned my attention to the security, logging, exception management, and messaging components. They looked somewhat ill-considered—just dumped into the business layer. It occurred to me that the security component would require its own collection of presentation pages (for the website owner to view and edit members and roles). Similarly, the exception management component would need its own collection of presentation pages (for the developer to view any problems). These components would also need to be able to store data. Clearly then, these components could be implemented in precisely the same way as the websites and modules.

Taking a new sheet of graph paper, I then drew the following diagram. I deliberately left out the DALCs, as I was not sure of where to place them. (Databases and data access are a real weakness in my developer skillset.)

Having drawn the above fourth diagram, I evaluated it.

I felt that I was really getting somewhere. It may yet become apparent that the above architecture is completely wrong, but having drawn it, I at least felt that it was taking shape.

I noticed that there was no difference between the modules and the components. In my mind I understood modules to be visible on the webpage (a blog module would show blog entries, a photo module would show photos), and components to have no visible aspect (except when in administration mode). But that distinction seemed a bit arbitrary, so I decided that all customizable components would be called modules.

I then attempted to add a bit more flexibility into the design, and came up with the following diagram.

Having drawn the fifth diagram, I realised that it was a mistake.

I had thought to add a bit more flexibility into the design by not requiring all modules to have a presentation package or to persist data. That was dumb. There is no point in module 3 exposing pages to accept user input if there is no way to store the choices made by the user. And there is little point in module 4 storing data that cannot then be seen.

I decided then that any component that could be customized would be called a module, and would include a presentation package and a persistence mechanism. Having made that decision, I flipped through Application Architecture for .NET: Designing Applications and Services to see whether it would help me to sort out the data access layer. This Patterns & Practices document did indeed help, and I arrived at the following design.

Having drawn the sixth diagram, I evaluated it.

I am fairly comfortable with this architecture. While it is not complete, it appears to provide a flexible system that will allow Charlie to achieve its feature set, which in turn will allow Charlie to meet its purpose, as stated in the elevator pitch.

The next step is to add detail to what is currently a very basic architectural view. Before I do that, I will use my next two blog entries to detail a couple of decisions that I have made along the way.

by Alister Jones | Next up: Why the Wonky Wheel?

0 comments

----

What about UML?

by Alister Jones (SomeNewKid)

When I first started developing little websites using ASP.NET, I had a nagging doubt that I was somehow doing it wrong because I did not first plan my classes with UML. I would visit bookstores and look through UML books and think to myself, “That’s just replacing one headache with another.” I could see UML’s value as a method of communication, but I could not see UML’s value as a method of design—particularly for a single developer.

I also wondered whether an inexperienced developer could even create legitimate UML diagrams. By way of explanation, let me tell you that I have never been to London and visited Stringfellows. It would be nonsensical then for me to try to draw a map of how to get there. (I sure hope my cabbie knows the way!) I have also never created a full application. So how could I possibly draw a map of how to get there?

I asked one of my heroes of development, Paul Wilson, whether he uses UML when designing his components. His reply was, “I do not use UML or any similarly ‘structured’ methodology--although I do at times communicate my designs with UML diagrams.”

When talking about UML in Coder to Developer, Mike Gunderloy says, “For small tools and utilities, I don’t find that the exercise of going through formal UML diagrams helps much.”

So, with confirmation from both Paul and Mike, I will give UML a miss.

by Alister Jones | Next up: The Architecture - Part 1

0 comments

----

Methodology - Finding the Right Path

by Alister Jones (SomeNewKid)

In Coder to Developer, Mike Gunderloy writes that he “almost decided not to mention methodologies at all.” I almost decided not to consider methodologies at all. However, I figure that any process is better than no process. So I read Mike’s brief review of the waterfall approach, the iterative approaches, and the agile approaches. I then read a few online documents that further described agile approaches.

I must admit that I do not understand any methodology other than the waterfall approach. I have read a number of articles about iterative and agile development; while I understand the words that I read, they do not form a picture in my mind. I cannot “see” the methodologies in a way that I can understand them, much less apply them.

So I have decided to go my own way. It is surely better to follow my own path that is clear to me, than to follow another’s path that is dark to me.

And what is my own way? While it is clear to me, I do not yet want to commit to it. I have not yet finished reading Coder to Developer or Code Complete, and those books may change the path I plan to take.

The answer then to the question of methodology is: to be determined.

by Alister Jones | Next up: What about UML?

0 comments

----

The Feature Set - Simplified

by Alister Jones (SomeNewKid)

In my last blog entry, I listed the features of Charlie.

After reading through it a couple of times, two thoughts occurred to me. First, some items are very specific while others are very general. This meant that the feature list is not consistent in its level of abstraction. Second, some items were a mere variation of another item. This too meant that the feature list is not consistent in its level of abstraction. This inconsistent level of abstraction concerned me.

The idea of application design is to start at a general level, and slowly move to increasingly specific levels. A rough example would be that we start by identifying the application itself, then move to identifying its layers, then move to identifying its components, then move to identifying its classes, then move to identifying its members, and finally move to coding those members.

I realised that if I want to follow this general-to-specific approach to application design, I must rework my feature list so that it attains a consistent and high level of abstraction. I started by asking myself, yet again, what it is that I want Charlie to do. The answer was that I want Charlie to provide a general website framework on top of which specific websites will be built.

That answer made me remember a design principle that is repeated throughout Head First Design Patterns:

“Identify the aspects of your application that vary and separate them from what stays the same.”

With that design principle in mind, I have reworked my feature list so that it identifies what must be allowed to vary from site to site, and what can be allowed to stay the same.

For all users, Charlie will:

  • Support multiple websites
    • allow for custom and turnkey websites
  • Support multiple content types
    • allow for custom and common modules
  • Support multiple response types
    • allow for different devices (browser, mobile, assistive, etc.)
    • allow for different document types (webpage, PDF, Word, RSS, etc.)
  • Support multiple asset types
    • allow for different ways of creation (manual, parse, scrape, conversion, etc.)
    • allow for different renditions (size, language, currency, etc.)
    • allow for different versions and status
  • Support multiple user types
    • allow for visitors and members and owners
  • Provide common services
    • reporting (hits, problems, performance, etc.)
    • site, page, and module CRUD
    • integrated help
    • security and user management
    • messaging (email, SMS, etc.)
    • high-level objects

I feel more comfortable with the above feature set. It maintains a fairly consistent and high level of abstraction. Its generalisation allows me to recognise the components that may be required, and even some patterns that may be applicable.

As tempted as I am to start sketching out my view of Charlie, I will resist the temptation. I promised that I would work through Coder to Developer, and I will keep my promise.

by Alister Jones | Next up: Methodology - Finding the Right Path

0 comments

----

The Feature Set

by Alister Jones (SomeNewKid)

This blog records the design and development of a web application named Charlie. The elevator pitch for Charlie is as follows:

“Charlie is a web-based application that simplifies the creation, maintenance, and use of websites. For a website developer, Charlie simplifies the process of creating and updating a website. For a website owner, Charlie simplifies the process of maintaining and editing a website. For a website user, Charlie simplifies the process of navigating and using a website.”

The next step recommended by Mike Gunderloy in Coder to Developer is to create a feature set. The feature set describes the functionality that Charlie will provide to each of the three users identified in the elevator pitch. A feature set sounds fixed and formal, but is actually a flexible and informal list of ideas. Mike recommends using mind-mapping software for this task. To me, that’s akin to using AutoCAD to create a sketch—a needless application of technology. Me, I used a pencil and paper, and came up with the following feature set:

For website developers, Charlie will:

  • support multiple websites from a single codebase (like DotNetNuke)
  • support the concept of content modules (like DotNetNuke)
  • support the concept of masterpages (like PowerPoint’s slide master)
  • support the concept of page templates (like PowerPoint’s slide templates)
  • ensure proper separation of structure (XHTML), style (CSS), and behaviour (ECMAScript)
  • allow for turnkey websites (like Clikpic)
  • provide high-level objects (like This.Request.Language)
  • facilitate highly-configurable websites (each site gets its own site.config)
  • automate backup of content

For website owners, Charlie will:

  • allow content to be edited (using RichText or MarkDown)
  • allow edits to be previewed before saving
  • provide content-sensitive help (extend to users)
  • ensure documents are checked out and in to ensure integrity
  • archives old content to allow for undo of edits
  • allows pages to be added, edited, and removed
  • allows sections (modules) to be added, edited, and removed
  • allow for automatic language translations
  • allow for automatic currency conversions
  • support multiple versions of content
  • support renditions of content (per Adobe XMP)
  • support status of content (draft, published, retired)
  • audit trail of changes (maybe)
  • website reports
  • keep simple sites simple, exposing only features necessary
  • generate images
  • generate Flash movies
  • allow for site searches
  • automate creation of site maps
  • allow for notification by email (and SMS?)
  • support multiple modes of content creation (manual, parse, translation, scrape, etc.)

For website users, Charlie will:

  • provide friendly URLs
  • allow for choice of language
  • allow for choice of text size
  • allow for choice of page style
  • make available print version of page
  • make available downloadable version of page (PDF, Zip)
  • make feeds available of content (RSS, Atom)
  • allow for multiple browsing devices (browsers, handheld, phone, assistive, etc.)
  • replaces missing images with an empty but valid spacer.gif
  • allow for login to member areas
  • provide accessible websites (no tables for presentation, keyboard navigable, etc.)

How did I come up with this list? By listening. I have listened to what users say about websites. I have listened to what website owners say about websites. I have listened to what developers say about websites. If Charlie can provide the features listed above, the goal set out in the elevator pitch will have been met.

I have more to say on the feature list, but I will do so in my next blog entry.

by Alister Jones | Next up: The Feature Set - Simplified

0 comments

----

Who is Charlie?

by Alister Jones (SomeNewKid)

Charlie is the name of my web application. The elevator pitch for Charlie is as follows:

“Charlie is a web-based application that simplifies the creation, maintenance, and use of websites. For a website developer, Charlie simplifies the process of creating and updating a website. For a website owner, Charlie simplifies the process of maintaining and editing a website. For a website user, Charlie simplifies the process of navigating and using a website.”

Why the name Charlie?

One of the best software analogies that I have read likened a software application to a traditional architect. The application gives life to a set of instructions in the same way that an architect gives life to a set of blueprints. The application coordinates various subsystems (such as display and communication) in the same way that an architect coordinates various specialists (such as plumbers and electricians). While the analogy extends further, I will not follow it here.

When I started thinking about creating a web application that would simplify the creation, maintenance, and use of websites, I started visualising the subsystems as specialists. I went so far as to give names to the subsystems. The navigation subsystem I named Sybil in honour of the greatest computer article I have ever read. The data subsystem I named Marcie in reference to the DataGridGirl. Being a typical guy, I visualised Sybil and Marcie as being kick-ass women. Who commands a team of kick-ass women? Charlie, of Charlie’s Angels.

Within a short while I stopped anthropomorphising the subsystems. I felt that such an approach might impose limits upon my application; whereas people are separate entities, subsystems may benefit from some blending. While I stopped naming the subsystems, I very much liked Charlie as an application name.

by Alister Jones | Next up: The Feature Set

0 comments

----

The Elevator Pitch

by Alister Jones (SomeNewKid)

I have on my desk Mike Gunderloy’s Coder to Developer. It is my hope that Mike’s book will get me started on the right path to creating a successful application. I plan to read this book from its front to its back, implementing all recommendations that I believe to be relevant to my web application.

The book suggests that the first step to creating a successful application is to write an elevator pitch: a short statement describing what the software will do, and why. I appreciate the benefits of this first step, so I will not skip it.

Here is my first attempt at the elevator pitch:

“Charlie is a web-based application that simplifies the creation, maintenance, and use of websites. For a website developer, Charlie simplifies the process of creating and updating a website. For a website owner, Charlie simplifies the process of maintaining and editing a website. For a website user, Charlie simplifies the process of navigating and using a website.”

Is the above elevator pitch any good? I have no idea.

While I feel sure that the statement will change, I believe that writing it was a very useful first exercise. The application is no longer an indefinite idea floating about my head. The application is now a definite statement of purpose.

The first step has been taken.

by Alister Jones | Next up: Who is Charlie?

0 comments

----