Wednesday, December 7, 2011

It's okay for your UI to know some business process

It annoys me when people make arguments that the UI should have absolutely no connection whatsoever to the business processes of a system. To me, this is a far too crippling restraint. Is your UI also not supposed to know that a given process is going to update your orders, to look for a new one? Should you then implement some sort of back-and-forth chaining of events that ensure your UI is up-to-date, but have it take 10 minutes to get through the chain of commands, rather than happen instantly because it knows that adding an order will...add an order?

This kind of active UI - one that knows something of the business processes - is not the death of maintainability. WPF has made it somewhat easier to manage by implementing binding so effectively, but that also has its own problems. I would rather have my business commands handle the UI updates directly, but this can be quite a mess; better is to just have the UI, when it gets some signal from the user (or from anywhere) do the update itself, before or after sending the command to the business processes. You might send to the business processes before updating the UI, and have the command catch a response from the business process telling you if you should update the UI (maybe there's some problem that the UI cannot and should not be able to validate); conversely, it's also reasonable to just update the UI and send to an async business process if you know for a fact that the updating is valid, say because of all validation that has already taken place.

What you definitely should not do, however, is have your UI implement all of your business processes. This is not only not maintainable, it's simply downright pug-fugly.

Tuesday, November 15, 2011

Writing stable code

Lately, I've been a tad obsessed with only writing stable code. Oh, sure, it'll be unstable until I realize how to fix
it, but I wanted to write a little bit about how I stabilize the code I'm writing, cause there are a few tricks that are convenient. The following represent refactoring techniques that can increase encapsulation, and decrease the number of times you have to change a given piece of code. Use wisely.
  1. Argument lists --> Class

    This first refactoring involves taking a long argument list for a function and wrapping the list in a class. A long argument list implies (to me) that there is some entire concept stored in that list, and that it would be better represented by some class with an appropriate name. Furthermore, if this is a public function that may be consumed by a customer, it would be very wise to do this so that if they have overwritten the function, when you change the class representing the argument list, they will not likely have a terrible break in their implementations of that class or interface.
  2. Generic lists --> Class

    The second refactoring takes long strings of generics and turns them into a single generic. For example:
    Func<Father, Mother, IEnumerable<Children>, IEnumerable<KeyValuePair<Food, Money>>, Cost> PurchaseFoodStuffs;

    Could be rewritten as:
    Func<Family, GroceryStore, Cost> PurchaseFoodStuffs;

    This Func takes a family to the grocery store and returns the cost of the food purchased. From the previous iteration, you would have no idea that that's what it's trying to do, however. You can imagine if you had to buy food for special occasions and what not that the argument list would get longer and longer and longer, but with the second one, if you're (say) adding an aunt and uncle that needs to be accounted for, you just add that to your Family class and you're almost done. There may need to be some more tinkering, but at least you don't have to go change a long generics list to match it all over the place. This also has the advantage that if you publish the above Func to a customer, you can change the underlying classes more easily than the argument list, and expect fewer breaks in customer code, similar to the first refactoring.

  3. Func/Action --> Class

    Are you noticing a trend? I prefer not to use Func/Action in my code unless it's particularly useful or necessary. I've found over time that using a naked Func or Action does not seem to really indicate the intent of a given piece of code very well. This is just my experience with code in the real world, but may not represent others' experiences. I just find that whenever I have a Func or Action that is even moderately complicated, I would have preferred to pass much of the data into a constructor and acted upon that data however I wanted, and passed around a class that can have functionality be overwritten, rather than a naked Func or Action which will likely require that you add a new condition in an if-statement. A good trick is to encapsulate the functionality into an actual class, and then make a derivative of that class that accepts a Func/Action into its constructor. This will give you the ability to rely purely on the class interface, while still being able to write simple code within a Func/Action, and you will not be coding yourself into a corner if the class functionality needs to change in the future, but the Func/Action code does not (necessarily) have to.

    A good example of this in the real world is simply the ICommand interface and DelegateCommand<T> class in the WPF Commanding stack: It does a little bit of work for you, but allows you to either completely write a new implementation by implementing ICommand, or pass a delegate into the constructor and let the DelegateCommand do the majority of the heavy lifting.

I hope that these are useful to you in some way, even if the above seem very simple to the vast majority of you.

Tuesday, August 16, 2011

Koans of Programming: Interface are for me, not for you

"Do not define interfaces to tell the consumer of your system how to use your objects. Define interfaces to tell the consumer of your system how your system will use their objects."

This little gem of wisdom came to me one day some time ago, and remains true today. When you are defining an interface, remember that they are for *you* to use inside your framework, and should be clean, stable, and simple. They should not have to be implemented by someone using your framework, unless those people need to actually override the functionality provided by said interface. When there is no discernible reason for having an interface because implementing it does not change any functionality, then you are more likely trying to tell your user how they should use your classes, which is much better done with a class - in that way, you can put some kind of restraints on how things are used, and you can still, if needed, provide points of extensibility.

Tuesday, May 31, 2011

Virtual properties - they're just dumb

Have you ever seen code of the form:

// Make it virtual so that implementers can provide their own version for them to use
public virtual IManager Manager { get; set; }


Code like this just angers me. For one, why didn't they pass it into the constructor? This is much clearer. For two, why does a *base* class need to define what classes the derived classes need to use in order to accomplish their tasks? This is ludicrous. That particular property isn't even used in the base class anywhere - and that's the main problem with it.

When you put something like this on your base classes, it's implying to the deriver that there's some reason that the base class needs it, so the deriver should provide their own implementation that doesn't break the invariants that the IManager interface is bound to. However, since it's not actually used in the base class (notice the comment? It very clearly states that the implementers will be required to use the class, not the base class), the base class shouldn't even have a reference to the IManager type.

The codebase that I was looking at was a real joke, and the original implementers had no idea what OOP means. Without any real depth of knowledge, OOP can quickly turn into POOP.

Thursday, May 26, 2011

Implementation hiding - it's important

I've decided to do away with the annoying naming scheme.

For this post, I'd like to talk about something that's very near and dear to me - implementation hiding. This is the concept in object-oriented design that allows a class' implementation to change without affecting the public interface of that class. It also allows things like schemas to change without requiring massive changes all throughout an application - if you hide the information and implementations of things, then no one can rely on those data and end up getting screwed when the schema has to change. This is important.

It's so important that the majority of the object-oriented design principles are focused purely on it. Most design patterns also encapsulate some form or another of implementation hiding in such a way that it makes it easier to change the code if needed, as well as at the level that's needed. Being able to change code efficiently and quickly - it's important.

An area that I really like to use implementation hiding is around legacy code. Let's say you have a COM library that you call into in order to generate some bitmaps of graphs for a scientific application. But let's also say you want to be able to make your class testable - to test it, you really don't want to pull in the COM library, initialize it, and so on; that's not just a lot of work, that's dangerous in a unit-testing scenario. So, instead of having just a class that calls directly into the COM library, have an interface that that class can implement that represents all of your code. In this way, a unit-test can create a mock of the interface and you can focus on test-driving it much more easily. Later on, when you're doing integration testing, you can test the class that calls the COM library directly, but this should always be done very carefully, and perhaps only on a CI server, in order to save developer time and effort (integration testing can take quite a long time; hence, I prefer to run it on a server instead). This is important.

Another way in which implementation hiding can be effective is on a codebase that uses a lot of static functions and such. It is often the case that as a developer, you'll get put onto a project that someone from a long time ago started coding and were only vaguely aware, if at all, of the principles we have these days, and because of that, they make it a very ugly solution. Your job is to clean it up where you can, and introduce new features. In order to integrate new features, though, a lot of stuff may have to change, and hiding these changes beneath an interface is an incredibly important way of cleaning up the codebase and making it safer for other developers to delve into.

Consider for example a codebase in which static classes and functions are the primary way the original developer worked. I think we've pretty much all seen this. None of it is testable at all, though. Sure, you can make calls to static classes in your unit tests, but that is possibly worse than not unit testing at all, because if the static class has to change, it now breaks both in the consuming system code and in the tests. Better would be to put an interface around it to wrap calls to the static classes, and replacing the calls to these in the consuming system code with calls to the interface. It sounds unimportant, but believe me, slowly removing static classes from your codebase over time is going to help you in the long-run, and not just with unit testing. It's very important.

Insulate change. Hide implementations. Winning.

Friday, March 4, 2011

Stardate 2011.63.1: Design stenches - Rigidity

A lot of people are aware of what others call design smells. I hate using the term smell, so I use the term stenches, but they amount to the same thing: Something that reeks up the place somethin' fierce. I'm going to be writing a series of posts with my experiences on projects that feature plenty of malodorous designs, and show how I would have improved them and why they are better. I hope to keep these relatively short, as I tend to go too long, but if you have questions, I can answer them in follow-up posts.

From Agile Principles, Patterns, and Practices by Robert C. Martin, rigidity of design is defined as:
"Rigidity is the tendency for software to be difficult to change, even in simple ways. A design is rigid if a single change causes a cascade of subsequent changes in dependent modules. The more modules that must be changed, the more rigid the design."

From my personal experience, this happens most often when people are more worried about data than they are about functionality. For example, for a simple property bag, if you make an interface for it and make more than one implementation, what happens when you change the interface because it turns out it didn't have all the data you needed, or the datatype on one of the properties needed to change? Did you have control over all the implementors, and did you just publish an unnecessary breaking change? For this reason, I do not support having many properties on an interface - 2-3 tops, preferably none.

In any case, when you change the interface, it completely screws the app. *Every* place that uses that interface now may have to change, depending on the type of change. Does this mean we shouldn't use interfaces? No! We should only use them when they are appropriate, and ensure that they encapsulate a responsibility, rather than represent a piece of data.

To fix this, I would only put the appropriate functionality for a given class on the interface. More importantly, I try to ensure that the interface is truly stable. Without stability, interfaces are actually less useful than standard classes.

Wednesday, February 2, 2011

Stardate 2011.31.1: Why Me(ssage Brokers)?

Boarding the Enterprise (architecture)

Enterprise-level application development is often much different from non-enterprise application development. It requires a lot more discipline, and a lot better understanding of the design of the application by all of the people on the project. The reasons why are fairly simple: If the architecture supports modularization, a strong probability, and at the lowest level the developers have glued dependencies between all of the modules through the use of static classes or through plain and simple data sharing, then what was the point of having modules in the first place? Modules are intended to have separate, clearly delineated boundaries between each area of the application, so if there are dependencies between each and every module, then there's something disturbingly wrong.

How does one typically fix this? There are three ways, usually: A message broker, an enterprise service bus, or a simple service locator/inversion of control container, depending on the requirements of the system. I'd like to discuss all three here today, but I don't know enough about service buses to write anything intelligible about them. On the other hand, I've used service locators and message brokers out the yin-yang, so I'll write about those. For more info on service buses, I highly recommend Udi Dahan's blog, wherein he talks about them most of the time. :)

An IoC container/service locator is a simple construct that allows you to grab a reference to an interface without having to know how it was instantiated, nor what the concrete implementation of that interface is. This allows a very clean, simple architecture, although I tend to use an IoC container rather than a service locator simply for the all-powerful constructor injection, which requires an explicit declaration of dependency on the interface in question.

A message broker is most often used to communicate between processes or programs. They typically support a Publish/Subscribe model, where a programmer can send messages to a host of programs easily by publishing a single message on the broker. This can also be used for inter-module communication, however, and cleanly supports future integration with other applications.

How are these two similar, and what is the motivation for using them in the first place?

A clean architecture may have explicit dependencies between each module, but it does so in the form of interfaces. These interfaces can be stored in an intermediate project so that everyone has access to them. While this leads to a high afferent coupling, the coupling is to an interface, so it's less likely to break something if the implementing class has to change how it satisfies the interface. When you rely directly on the implementing class (instead of the interface), you get into trouble when that implementation class has to change substantially, mainly because the code that used it may need to change as well. If it was dependent only upon the interface, i.e. the core functionality that the class provides, it's less likely that the interface will have to change, because the implementation class can change much more easily to meet the needs of the interface, so you save in two ways.

A service locator or IoC tool can be used to mitigate the complexity of the construction of an object, as well as the inherent coupling to the concrete implementation class. Whereas before you might have had:

IUsageTrackingService tracker = new SqlUsageService(connectionString, other_bs);

Now, you would have the rather simpler:

IUsageTrackingService tracker = ServiceLocator.Resolve<IUsageTrackingService>();

Instead of having whatever class needs access to the usage tracking service newing it up itself, it is pulled in through a static service locator here and the using-class doesn't need to know the connection string or anything else about the usage tracker in order to get a reference to one. You can see how useful this is if you ever need to unit-test the usage tracker: Do you want to have it crush a database, or simply output the usage into a string which can be inspected way more easily? And unit-testing the class that uses the usage tracker? FUHGEDABODIT! (Pass an interface reference into the constructor of the using-class, and just mock it.)

A message broker works in a strangely similar fashion. What the service locator/IoC tool did through inherent reliance on the interface (in this case IUsageTrackingService), a message broker goes one step further and says, "I don't even know who is going to be getting this, but here's some indication that something is happening! AAAAAAGGHHHHH!" Here's how I think of a message broker: When you need something to happen (let's say we're still on usage tracking) but there's absolutely no reason whatsoever for a class to care who or what is responding to its clicking of an advertisement in the application, then a message broker can very, very cleanly implement that. In this case, you just have the class fire off a message such as:

broker.Publish(new AdvertisementClicked(module: Modules.Comedy, user: user.ID, advertisement: ad.ID); // Only using named arguments for clarity

Now, anyone who might want to catch that event can simply be subscribed to it upon instantiation of the message broker, and that leads to much, much cleaner code. Consider also that if the message broker were to just push the message into a queue, this could be processed completely outside of the main application somewhere and you'd take no performance hit whatsoever.

The key here is that the message broker removed dependency even upon the interface itself, so now the interface that you've created can change, if required, without the using-class having to change its code to handle it. It can be argued that in this case, you may not even need the interface at all, but I'll leave it as-is for now.


There are several downsides to each of these methods. I'll discuss those now briefly because they are pretty self-explanatory, in my opinion.

ServiceLocator/IoC container - With a static ServiceLocator, you get the added lack of bonus of relying on a static singleton, which isn't great for testability. At the same time, the IoC container can hinder testing as well. With the ServiceLocator pattern, you tend to run into problems when someone wants to use a class, but doesn't realize it has some dependency upon some interface - since the interface dependency isn't explicitly defined in the constructor of the class, it's not nearly as easy for the user to know that they have to register that dependency before using said class. With an IoC container, this is less of a problem because they typically have constructor injection, which allows the class to explicitly define the interface in its constructor. Both of these methods have somewhat of a complex learning curve due to the fact that you never technically know which implementation is being used, unless you're in the place where that implementation is being registered as the interface. You may very well *not* have access to that; for instance, if you were working in a module and the registering of the implementations all happens in the bootstrapper, and the bootstrapper is part of a totally different project, then you may not have access to it. At the same time, it lends itself to very simple programming, where you just get the reference and call functions on it - dirt simple.

With a message broker, the learning curve is much, much steeper. In addition to not knowing which particular class that you care about is processing the message, there could be tons of classes other classes processing the message as well, which can interfere. If you don't have access to all of them, then it could be one of those other classes that has a problem with the message. For this reason, it is a standard of mine that, when a class is processing a message, I log it. That way, when it fails, it is at least logged and I can go back and see exactly where it failed, if not specifically what failed.

The message broker also requires some knowledge of threading typically, as well as weak references. When you have an event that is being published, it could happen on the main thread or on a background thread. This can vastly change the programming model, and is a bit harder for most developers to wrap their heads around. Similarly, the pub/sub model that is usually used is somehow difficult for some developers to understand and compute. Some programmers also seem to struggle with weak references.

Both of these methods are more complicated, but save you time and money in the long run - it's a matter of how much extra complexity you're willing to take on up-front, in exchange for safety and clean code down the line.


I hope this post was useful to you in some way, and helped you to understand the very basics of how to use a message broker in an enterprise application. It's very high-level, but if you have low-level questions, feel free to post them in the comments and I'll see what I can do to answer them in future posts!

Wednesday, January 19, 2011

Stardate 2011.19.1: Domain Events - Powerful, Stupidly Named

Today, I thought I'd point out something that is terrifically obvious: Domain events may be the strongest concept to come to domain-driven programming since the ubiquitous language. I almost always have an object of type DomainEvents these days because they're just so useful. They become a kind of repository for the different things that can happen in the domain that really have no other place - see Udi Dahan's website for more information about the concept of domain events.

Also, this is probably the worst name for a type in the history of mankind, and might be a mistake to have the object at all. The reason for this is that, like my rant against Commons projects, it often becomes a kind of repository for trash that just needs to be maintained over time. There are sometimes Action<T>s in it, which is a mistake, but also it is often a static class that just has the different possible domain events in it that can be raised statically. This makes it difficult to test, but there's also something more obvious: There's virtually no ubiquitous language which contains the concept of an explicit DomainEvents object in it. 

This is pretty obvious, however, and does not take away at all from the usefulness of the concept. Often, we require a place in the domain where we can just do different things that aren't necessarily part of the normal flow of execution of the business domain. For example, when filing a legislative bill, there are a crapton of things that can happen before the bill even gets into the first committee. However, there's no explicit, "Here's what's going to happen every time!" You can't necessarily model it effectively as a function that follows another function, e.g. if you have a SendToCommittee function, you can't necessarily prefix it with all of the functions that may happen before it goes to committee - there are just too many possibilities!

So how do you handle it? The best way (in my opinion) is basically with an event. There are many different ways to implement events in most programming languages. Since I'm a .NET developer exclusively, I'm going to talk about developing domain events in .NET, and C# in particular. I have no fuss with VB development, nor VB developers, but I'm just not familiar enough with it to be able to talk about it intelligently.

The standard DDD way of handling domain events in .NET uses the weak-eventing pattern. This is a pattern where you have a list of WeakReferences to actions. These actions get executed if they're valid references, or are skipped if they are not. That then becomes your domain event. It has to be a list of WeakReferences due to technical issues with subscribing causing a hard reference to stick around when it probably shouldn't - perhaps because the objects that have hooked up to the event would otherwise have gone out of scope.

My next post will have more useful content. I just wanted to point out that having an explicit type called DomainEvents is probably not the right way to go. In the next post, I'll discuss how I typically handle it, and why I think it's stronger and better OO design.

Friday, January 14, 2011

Stardate 2011.14.1: Friday's Book

I like to read. Heck, I love reading. Reading is also incredibly important. As such, I'd like to start a kind of Friday book club, where I review a book I've read or am reading and make recommendations based on it.

The first book is what should be largely considered to be the Bible of Software Design. It is Agile Principles, Patterns, and Practices, by Uncle Bob Martin. The link to the book links to the C# version of the book, but I actually found the C++ book to be a bit better.

The work produced by Robert Martin in this book is quite prolific. It is built upon a solid foundation of scientific thinking about programming and I really appreciate that aspect of it. It is reminiscent of the good old days of C++ programming with Scott Meyers and Herb Sutter. Here are some


Solid SOLID discussion: This book was the first one to completely and clearly define all of the SOLID principles, to my knowledge. These include all of the principles that I've talked about before. They are incredibly useful and can almost be used to create a quantifiable design metric that tells you the quality of a given system. There are a lot of resources on the web about the SOLID principles, including Robert Martin's own blog, so I'll leave it up to you to research them.

Surprising project design discussion: When I first read the book, I hadn't really encountered much in terms of setting up physical project solutions. This book goes into great detail about the various principles that can be used to set up the projects in your solutions and it works incredibly well for the book, despite more of a focus on patterns and principles for the real code and not just the structure of the projects.

Practical pattern discussion: Whenever I see that someone has written a blog post or a new book on patterns, I die a little on the inside. 99% of these efforts are garbage, and half of the remaining percent are written without including any real code or practical examples. On the other hand, Robert Martin's books never lack for code and it's code that makes sense. It's not always enterprise-level code, but it can easily be analyzed and taken and used on enterprise-level code.


BYOBB? That's a typo: While I like the book in general, my near-OCD for proper spelling, grammar, and punctuation makes most of Robert Martin's books somewhat difficult to read. I'm not sure who the editor for them is, but most of the time, a problem text can be figured out with a little thought. At the same time, they're not really significantly worse than other programming books.

Diagram it!: There's a huge, huge focus on diagrams and things like this. I find this to be incredibly tedious. It may be quite, let's say, youthful of me, but I find diagrams to be quite distracting. They summarize the information somewhat well, but following them can lead to a significant disconnect with the actual code and I find this to be dangerous. At the same time, diagrams themselves often don't completely or accurately reflect the evolution of the code over time, so it's another piece of waste that ends up being generated, and very few people will ever look at it, preferring rather to just dive right into the code.

Thursday, January 13, 2011

Stardate 2011.13.1: Interfeces - Property-only Interfaces

When it comes to abstraction, I always try to be very careful. The abstraction should not dictate the types that the implementing classes should contain. This is very dangerous, and is one of the reasons that inheritance can be very dangerous. Even having a base class for a piece of data that is common to all derivatives of the base is not that wise in most instances - it is more likely that the derivative is going to either need to manage that piece of data in some way, and if it doesn't, then why have it in the base class and not in its own class that isn't in the inheritance hierarchy?

Sometimes, properties on the interfaces are somewhat useful. For instance, Ayende once mentioned to me that something like SupportsRollbacks, a boolean, is perfectly valid on an interface defining an object that can have data rolled back. However, having property-only interfaces should be a design stench in any system. I have found two ways to this same conclusion, so I think it's justified.

The first path is that, if you have an interface that is only properties, then it doesn't really manage its own data: Some other class must obviously be managing the changing of the values and so forth. When looked at this way, it's obvious that encapsulation is pantsed.

The second way is much more general in that interfaces are intended to represent some functional unit, or some specific responsibility in terms of functions. While properties in .NET are technically functions in that, when you get or set them, you have a point that you can insert code, in terms of the public-facing interface, you can't tell if it's a property or just a public variable. Of course, Visual Studio allows you to know if it is or not, but I'm talking from a purely practical standpoint here. How many times did your teacher back in CS tell you not to use public variables?

Anyway, since properties give no indication as to any functionality that they actually contain, since they often represent nouns in the system and not verbs, having interfaces that are only properties is like having a base class with only public variables.

It gets worse if the properties are custom types. What if the custom type is abstract in some way? Then you're in a real pickle (especially since those abstract types are probably just pure properties!). These are all things that I've seen on projects, and it really points out just how bad this type of system is to work with, and especially to maintain.

Wednesday, January 12, 2011

Stardate 2011.12.1: Hasty Decisions

I recently stumbled upon the blog of GM Mark Bluvshtein. He's a relatively new Canadian grand master (I think) of chess who is terrifically pragmatic. It occurred to me that most good chess players *are* pragmatic, because you have to be: You have to know how to do the least amount of mental work but still get the most out of your moves - otherwise you can run out of steam midway through the game, or through the tournament. More importantly than conserving on energy, however, Mark seems to be hypercritical of his own play. This is another trait that I've noticed on the highest-level chess players, and is something I think we need in programming more.

In programming, I've noticed a lot of architect astronauts thinking that it's more important to define up-front an architecture which encompasses every aspect of the project, and that architecture must be strictly adhered to, no matter the consequences. If a lowly dev comes up with a reason why it won't work? Then they're wrong, just because they're not an architect!

You can see I have no fondness for these kinds of developers who think they know everything, and aren't afraid of pushing their ideas onto you. At the same time, I have problems with it myself. As such, I've taken my natural hypercritical chess (and general life) approach and begun applying it to my coding. I can't tell you just how important this has been to my personal development in chess, in life, and especially in my programming.

When I first started studying chess, back in 2002 or 2003, I was a pretty big nub. I mostly played blitz, of course, but even in my tournament games, despite the fact that I was not bad at all at the club level, I rarely reviewed them. While I'd do the occasional analysis after the game with the person I played against, more often I'd go play blitz games with the others who were done and just relax. Blitz games are incredibly relaxing, although they also make us develop bad thinking habits, such as assuming that the thing we're planning to do is not that bad, and we don't need to do too deep of an analysis because we need to get stuff done quickly.

This is terrible thinking. Just because we have to get something done quickly in programming, that doesn't mean we should not analyze it as deeply as we can. We need to be very critical of our own ideas so that we can weed out the moves that are shoddy, and only proceed when we have concrete, realistic goals. For architectures, this is perhaps the most important thing to have: If we do only a shallow analysis and define by fiat a series of "Shalls" and "Shall nots" without dogfooding, then the project is likely going to die an early death when the requirements start to change even a little bit. We have to create an atmosphere of questioning every decision when it comes to the architecture, because it's going to affect the *entire* project. If it is only shallowly analyzed, then it's way more likely that the project will fail, in my opinion.

Have you ever made any hasty decisions on a project that ended up hurting the overall quality of the project? Let me know in the comments!

Tuesday, January 11, 2011

Stardate 2011.11.1: Interface Segregation Principle vs Common Sense

The Interface Segregation Principle is an incredibly useful and powerful principle of software design. The ISP basically says that you should keep relatively lightweight interfaces so that when a person implements them in order to hook into your system, they do not need to implement tons of methods that aren't relevant to their class. I usually try to have no more than five functions on an interface - that's just a rule of thumb, but I find it to be a useful one.

But it's also very important to remember that, like all principles, it can be taken too far and make your life a living hell.

In particular, the interfaces should still be large enough to define the appropriate functionality that is being replaced. If you go further than that, putting each function and/or property into its own interface, then you have the opposite problem from the ISP occurring: Implementers who want to change how your system works will likely not be able to tell which interfaces have to be implemented in order to provide a given functionality. This is especially true if you've shunned type-safety and used object/dynamic throughout your system.

Some people try to solve the above problem by building up their interfaces into one unified interface that has all of the functions/properties required. This leads to other problems, though. When I decide to use an interface, I always ask myself this question: Do I have some way in the system (at all) to change where/how that interface is instantiated, and do I have a reference explicitly to that interface anywhere that would make switching the underlying implementation useful? If that point of extensibility doesn't exist, then having an interface around it is actually not really that good of an idea. With that in mind, if you have no way to actually change which underlying implementation is used, or if you don't even have any references to an interface except in an inheritance chain, I think we can safely say that that interface is likely unnecessary.

What do you think? Do you agree? Leave some feedback.

Monday, January 10, 2011

Stardate 2011.10.1: Revenge of the Commons

In my day, I've seen a lot of shoddy architectures. From a COM system that read data as strings from the user-interface, converted it to its inherent datatypes, then turned it back into a string and sent it from the client to the server, then read it as a string and turned it into its datatypes, did work on it and sent it back, the entire program of which was written in about 200 3,000-line switch cases (copy-pasted to the server and the client), to a project that only had a few successful continuous-integration builds for the entirety of its lifespan due to such a low-quality codebase, and such immature developers.

Today, I'd like to discuss the Commons; not Boston Commons, but rather Commons projects. These are typically defined to be a series of interfaces, classes, and user controls that didn't seem to have an obvious spot in the domain. They often represent purely technical concerns that have little to do with any real business functionality, such as a combo-box that automatically formats its input in various ways: There's no obvious place that that really fits into the domain, so why not throw it into the junk drawer?

Wait, junk drawer? Is that really all Commons projects are? It seems so. While I understand the utility of having a Big Ball of Mud for things like this, they really do tend to cause significant issues later on down the road. The reason they do this is because they tend to have insanely high afferent coupling. In other words, there are a lot of projects which depend on some or all the classes in the Commons project, and so when another project needs a special version of the class in Commons, and they decide to change that class directly because it fits in the other places that they're aware of, it breaks all the places that work with that class because they didn't realize they had to fix it, and didn't bother to check it (whether because they didn't know they needed to, or because their test-cases weren't well-defined).

A very high afferent coupling doesn't necessarily mean it's a terrible architecture, though - it just means that it's very likely to have problems when those classes need to be changed or fixed, and so the overall design quality is likely lower. The main reason for this is that Commons projects tend to be highly unstable. Consider, for example, Core projects - projects which are decided to be core either to the domain or to the architecture. These projects are usually extremely abstract and tend to be more stable than any Commons projects, because the Core projects define the interfaces and abstract classes which are in-turn implemented specifically in the modules. Since they are abstract, there is a kind of implicit understanding that they should be stable within the domain, i.e. they aren't going to be changing much for any reason that the business people might offer, and at the same time should be relatively stable within the architecture.

Does that mean we should make the Commons projects more stable and abstract? I would say we should certainly make them stabler, but it would be incredibly difficult to make them abstract. Often-times, they actually have abstract components buried in them, but those abstractions are not at all stable. I think better is to avoid, if at all possible, Commons projects altogether, and instead look for ways to embed these pieces into the modules themselves. I would even go so far as to say it's "OK" to have copies of each class that seems to be common distributed throughout the modules. Whoa whoa whoa - what about the DRY principle - don't repeat yourself? Well as it turns out, when DRY could potentially cause you a lot more work due to one class handling several different use-case scenarios, DRY should take a back-seat to the SRP - the single responsibility principle. In that case, the SRP allows each of the different classes to serve their respective modules without breaking the other modules' implementations when bug-fixes/domain changes/architecture changes are required in those particular modules.

I certainly understand that that leaves a kind of gritty after-taste in your brain when you have to do it, but in my experience, it is simply much, much easier to work with/maintain this kind of system than it is one with multiple Commons projects that serve every module individually. "Find and replace" is still better than "Make one class dangerously handle every responsibility."

Friday, January 7, 2011

Stardate 2011.7.1: Netbooks

I recently purchased a netbook for my wife. They're amazingly useful, but also pretty fun and cute. I use it largely to watch Hulu while I'm exercising on the elliptical. What experiences have you had with netbooks? Which do you recommend? Which weren't so good?

Thursday, January 6, 2011

Stardate 2011.6.2: Capptain's Law

Brooks' Law states that adding people to an already late project will make the project later. I think there's a similar law that I pose here for the first time (to my knowledge, please correct me in the comments if I'm wrong):

Adding developers beyond one to the bug-fixing effort on an app will increase the number of bugs.

I find this to be very appealing and very close to Brooks' Law, especially when working on a Death March project. I believe this applies even if the developers that are added are incredibly good developers. This doesn't require a badly-written app. This happens regardless of the quality of the app.

I do not have a real proof for the law, which, as a mathematician, annoys me to no end. It is one of those things that to me and my experience, it seems really intuitive. Basically, no developer you add will know all of the requirements and previous/current bugs that need to be fixed/implemented, so adding them increases the possibility of them adding a new bug. With each new person, that probability increases exponentially because they may now step on everyone else in the group's toes/bugs in some way. At the same time, when there are multiple stakeholders (which is almost always true), it's guaranteed that nothing is ever going to get fixed properly and completely.

What do you think? Agree/disagree? Let me know in the comments.

Stardate 2011.6: Interesting Exercises

Lately, I've been delving a lot into DDD, or domain-driven design. I find it to be the single most elegant way to tackle really complicated systems. Some people say it's a lot of work, especially just for small apps, but I find it to be completely natural. For example, on a previous job, the users needed a batch publishing system that would loop over a set of Word documents, convert them to HTML, and then save them to a directory which already had publishing features turned on, so that when HTML files were put into it, they'd be served appropriately up to the web. I didn't have time to write more than the bare necessities, but since every class and functional piece of code was named in such a way that the business user understood the meaning of the pieces (for example, I used an IFilingCabinet interface for the documents, which they used all the time of course) and they were able to take it and add to it so that even though they started with the barest essentials, they ended up with something really powerful.

I think it would be interesting for a book on DDD to propose exercises. These could be considered to be a kind of kata for DDD. As such, I'm going to begin publishing exercises that I've thought of, from the very simple kinds of things you might find useful around the house, to complicated, industry-standard systems that are extraordinarily painful and convoluted.

The first kata I propose for DDD is rather childish, but comes from a joke I made in an email the other day.

Name: Mouse Trap Simulation
Description: The idea behind this kata is to write a simple simulation for how a mouse trap should work. There are many variants of mouse traps.

  1. The standard spring-loaded bar mouse trap (with cheese)
  2. Glue paper
  3. Poisonous foods
Let's just consider those three. What are the pieces that make up every mouse trap? How can you write the code so that a mouse trap entrepreneur could come in and extend your system without having to change the original code? What does your test harness look like - does it have a human setting the trap, a random mouse encounter?

One thing to note about it is that the requirements are not well-defined. Feel free to ask questions in the comments!

Goal: The goal of this exercise is to develop a simulated home/work environment where rats may be an issue. The code should be structured in such a way that when a normal person reads it, they can have some idea of how the system works. They shouldn't need to be programmers - for example, they might just be business analysts who dislike rats. The key to this exercise is creating a truly decoupled design that allows every mouse trap to do their own work, without making it difficult for an extender of the system to implement that work. If your base classes/interfaces make it difficult to extend them, then You're Doing It All Wrong ®.

Bonus points: For extra points, design your *test harness* to be extensible as well, because what if a trap can't truly be tested in the same way that other traps can be?