Showing posts with label patterns. Show all posts
Showing posts with label patterns. Show all posts

Monday, May 24, 2010

Rails has no place at the office

This is a milestone post for me! My first ever purposefully incendiary title!

I should probably run with it and try to get everybody super offended, to the point where you have no idea what my point is because all you can see is red. I guess I'll have to leave that for a future milestone...

Because, yeah, I'm not really serious. Rails has a place at the office. And no, this isn't going to be one of those "Is Rails ready for the Enterprise?" posts. Rails is perfectly ready for use in the Enterprise, but that's the wrong question.  As usual, the right question is much more complicated.

To start with, let me point out that this conversation has nothing to do with Ruby vs. C#. It doesn't really have anything to do with Rails vs ASP.NET MVC either. Instead I'm going to be talking about Active Record vs. Data Mapper, and View-Models vs. no View-Models, and this general concept of "the straight and narrow" vs. explicit abstraction and control. These are design patterns which apply to any language and appear in many different frameworks.

Rob Conery recently wrote a blog post in which he said,
For a lot of .NET/Java devs this will look "messy" - you shouldn't elevate "data concerns" into your model. This argument makes good sense for a large, complex site - that you're building in C# or Java. Typically Ruby focuses on the straight, narrow path and with that comes a dramatic turn towards "doing what you need to do... and no more". This resonates with me...
The part about Ruby/Rails focusing on "the straight and narrow path" really struck a chord for me.  Ruby, being a dynamic language, is very much on the "straight and narrow."  It dispenses with all kinds of things found in strongly typed languages like private, internal, protected, interfaces, etc.  These are things that are usually considered very important in a strongly typed language, and practices like DDD, but Ruby doesn't really bother with them.  Ruby favors documentation and convention over strict control.

Rails has a similar story.  It uses the Active Record pattern for its data access, which requires a 1-1 correspondence with your database.  Further, the models don't even really exist!  They're built dynamically from the schema of the database tables.

If you compare ASP.NET MVC to Rails one of the differences you'll quickly discover is this concept of a "View-Model". ASP.NET peeps seem to like these, whereas I haven't found a Rails sample anywhere that uses these.  Both Active Record and this lack of a View-Model are accomplishing the same thing: removing abstraction in favor of directness and simplicity.

Now lets step back from this for a second and ask a question.  Who in there right mind would want to have to deal with things like class and method visibility and extra layers of abstraction, which more often than not appear to be just duplication?  No one!  No one would want to deal with these things!  It's extra work!  I _hate_ extra work!

So why do we do it?  Why does DDD make a big deal out of private constructors and Factories?  Why does Fowler recommend the Data Mapper pattern over Active Record?  Why do we create View-Models to separate our Views from our Models?  Why do we do all these things that seem to just make life more complicated?  Why don't we all take the straight and narrow path on all of our projects all of the time?

Certainly it's not as simple as the language we're using.  Just because you're writing in C# and Java doesn't mean you can't use Active Record.  And it doesn't mean you can't pass your Model straight to your View.  There is also nothing about C# or Java that forces you to use interfaces, or follow the Dependency Inversion Principle.  That said, there's also no reason why you couldn't use the Data Mapper pattern in Ruby, or create View-Models.  The language certainly HELPS with some of these issues, but it's not the real difference.  These are just patterns, and they apply equally well to any language.

The reason why we introduce this complexity and divert from the straight and narrow path in our technical approach is actually due primarily to non-technical reasons.  Here are some of the reasons I think lead us to adopt these "enterprise" patterns:

  • There are more than two or three developers on the project
  • You have more than 6 entities in the domain
  • The project has a timeline longer than 3 months
  • The developers aren't intimately familiar with the domain
  • The project is likely to grow in fits and starts
  • The team members are more likely to come and go

These are not technical issues but they have technical IMPLICATIONS!

The practices prescribed by DDD are a big deal if you're working with a large complicated domain with lots of potential for change.  If you're not, then you don't need DDD.  Fowler's enterprise patterns are a big deal for the same reasons.  If you know things are complicated, likely to change, and not possible for everyone on the team to grok completely, then you need to build abstraction into your code.  And you need to try to be as explicit as you possibly can about what the code does and how it works.  And you need to look for opportunities to prevent error and misunderstanding before it happens.  These things will allow you to keep things clean, organized, and ultimately make your project successful when you're faced with "enterprise" challenges.

This is obvious.  I'm sure you're sitting there (or standing) thinking, "duh!" or "when is this dude going to get to the point?" or "does this moron really think this is revolutionary?!"

My point is as simple as this.  Rails is awesome.  Simplicity is awesome.  But as I sit here in my ivory tower looking out over the landscape I see lots of quiet subtle backlash from people against the "enterprise-y" patterns in favor of the simplicity of Rails.  This makes a lot of sense to me because, as we pointed out, who would WANT to deal with the complexity of enterprise problems and patterns?  But it is easy to be tempted by the appeal of simple solutions to simple projects.  And certainly we should always strive to find the simplest solution that could possibly work.  But we can not close our eyes to the complexities of the problem or the environment in which we are solving the problem.  And we cannot allow ourselves to be boiled alive either.

So by all means, choose the right tool for the right job, but make sure you understand the job as well as you understand the tool.

Monday, November 23, 2009

Don't Write Another Line Of Code Unless...

Don't write another line of code unless you know and have been influenced by the following things:

SOLID (from Uncle Bob)
SRP* - Single Responsibility Principle
Every class should have one clear and well defined responsibility
OCP* - Open Closed Principle (from MSDN)
Extend the behavior of a class without modifying that class
LSP - Liskov Substitution Principle
Derived classes must be substitutable for each other (this one is kind of obvious, but still important)
ISP - Interface Segregation Principle
Make fine grained interfaces, not fat interfaces (this goes along well with DIP)
DIP* - Dependency Inversion Principle
Classes define their dependencies, which other classes implement

* The three I've starred I believe are the most important as they make the biggest difference in fighting spaghetti code.

YAGNI (from Wikipedia) - You Ain't Gonna Need It
This is an Extreme Programming concept which basically says you shouldn't add functionality until you actually need it

TDD (from Wikipedia)- Test Driven Development

Loose Coupling/High Cohesion (from MSDN)

Code Smells (from Fowler)
A code smell is a "surface indication" that there may be a deeper problem with your code.  It is very useful to know these, especially when practicing TDD.

Basic Design Patterns - Singleton, Observer, Mediator, Strategy, Decorator, etc
There are lots of books on the major design patterns. I personally haven't read this one, but it has been highly recommended to me: Head First Design Patterns

MVC/MVP/MVVM (from Fowler) - Model View {Controller|Presenter|View-Model}
The biggest piece to take away from this, in my opinion, is the responsibility of the Model and the separation of the UI (the view) from the Application layer (the Controller, Presenter, View-Model).

DI/IoC/Service Locator (from Fowler) - Dependency Injection/Inversion of Control/Service Locator

Law of Demeter (from Wikipedia)
This is a useful concept to be aware of, but one that really shouldn't be thought of as a law. See what Phil Haack has to say.

Database Isolation Levels (from MSDN)
Anyone doing anything with databases needs to know the Isolation Levels, what they do, and when to use them.

Concurrency Models - Optimistic, Pessimistic (from Fowler's Patterns of Enterprise Application Architecture)
You can't write any multi-user application that updates data without understanding concurrency and the various patterns for dealing with it.

Version Control (from Wikipedia)
You should be familiar with centralized version control (like Subversion). And I think you should also understand distributed version control (like Mercurial).

--
You don't have to be an expert in all these things. But any decent developer should have at least a basic understanding of these concepts and be able to understand what they are when someone else mentions one.

Our industry is REALLY weak on education. We go to school and learn about data structures, semaphores, virtual memory, file systems, etc. Then we graduate, get jobs in Software Engineering and promptly never use any of that. I'm not saying it's not useful stuff to know; it is useful to know. But its not what you deal with day to day as a software engineer.

You can't be a software engineer without knowing the stuff on this list. I'm serious. If you don't know it, you're just a dude who's hacking out code.

That said, I'm pretty sure I'm just a dude who's hacking out code... What things do you think I should have on this list before I write another line of code?

PS. There are also lots of good books you should probably read if you're thinking about being, or already are, a software engineer.

UPDATES:
1/28/2010: added Code Smells and re-ordered list

Monday, September 22, 2008

MVC and MVP

Do a google search for MVC MVP and you will find no shortage of posts on the topic.

If you want pictures and diagrams and code samples I'll let you do the Google search. But, in brief, MVC stands for Model View Controller, MVP stands for Model View Presenter. What's the difference?

There is no difference! Well, if you look at it in enough detail, you'll be able to come up with all kinds of stuff, but if you look at the overall picture, there's really no practical difference.

Ok, I knew you wouldn't be happy with that answer... In MVC the View is stateless. When you interact with it (by clicking a button, for example) that action is forwarded directly to the "Controller" which then renders a new View.

In MVP, the View may or may not have state. In either case, when you interact with it the View handles that action (aka, the View has hooked into an event) and forwards the action into a call to the "Presenter." Unlike in MVC where a new View is rendered, in MVP the Presenter has to cause the View to update somehow. This can be done with data binding, or by the method on the Presenter returning data that the View parses, or by the Presenter raising an event that the View receives, or even by the Presenter calling a method on the View...

There is one other element. In MVC, there is a Controller for every View. In MVP, you don't strictly have to have one Presenter for every View. You could have many Presenters per View. You could have a Presenter for every "Control" in your View. Or you could have a Presenter for logical regions of your View.

In the end, the View is the same in both cases: it displays stuff. The Model is the same in both cases: it represents the data. And the Controller/Presenter is the same: it does stuff that the user asked for.

MVC is very applicable to the web, where actions on the rendered html page "post back" to the Controller on the web server.

MVP is very applicable to Windows Forms and WPF where actions on the Form/Window raise events which delegate the majority of the work to the Presenter.

Clearly, these patterns are pretty simple. But they get a lot of attention, and there is a lot of confusion surrounding them. Partly this is because Computer Scientists all have a bit of the Martin Fowler syndrome in them, so we feel like we need to classify everything. We like to have everything all lined up and tagged and placed in the right pigeon hole. Sometimes this is a good thing, other times it can lead to a "can't see the forest for the trees" type of problem.

But mainly, I think these patterns confuse people because they're named horribly. In MVC, the Controller doesn't control the View. The word "controller" invokes an image of a puppet master pulling the strings. The Controller is much more hands off than that. It's really more like an Interpreter or a Router which says, "Ah, I see you clicked the Send button. Allow me to route that to the proper sending authorities, and then I'll send you a new view." So while it certainly does control the application and how the view responds to action, "Controller" is just too loaded of a word.

In MVP, I really can't understand where the word "Presenter" came from. Maybe it's supposed to make you think of a presentation where the Powerpoint slides are the View, and the person talking and moving the slides ahead is the Presenter. But in reality it sounds more like there are two views... I think of the Presenter more like a Calculator. You're working out some equation on paper (the View) and using a calculator to execute certain functions for you, the results of which you record on the paper.

In the end the titles get in the way. What we want is a way to separate as much of our logic as we can from the display. This allows us to do a few things:
  1. Test our logic with TDD
  2. Change the display without requiring huge changes to our logic
  3. Change our logic without requiring huge changes to our display
At least, this is how I'm looking at it right now. I reserve the right to learn something new tomorrow and start from scratch.

Thursday, August 21, 2008

DIP is not for reuse

The Dependency Inversion Principle is this wonderfully clever concept for decoupling layers. I've written a bit about it before here.

To summarize, the idea is that your high layers define interfaces that your low layers implement. Thus insulating the high layer from the low layer. This fits in very nicely with TDD as you can write/test the high layers first and mock out the low layers.

So DIP is good stuff. But it doesn't play well with reusable component architectures. That is, if you're designing software components which you intend to use in many different places (some of which may be as yet unknown), you can't use DIP between them.

Maybe it's time for an example. Suppose we have a Component A and a Component B. Now we're writing a third Component C which will use A and B. Finally, we have an Application App which will use A, B, and C.

A, B, and C may all use DIP to structure the layers within the components. But you wouldn't want to use DIP between the components. If we tried to do that, we would have to define two interfaces in C that described how it used A and B. And three more interfaces in App that described how it used C, B, and A. Then A and B would both have to implement interfaces defined in C and App. Plus C would have to implement interfaces defined in App. And now you can't reuse A, B, or C in another App (without including App).


So what do we do if we want our COMPONENTS to be independent, just like our layers? Just change it slightly. Create an assembly for each component that contains interfaces used to interact with the component (ex: A.Contracts). Make A implement these interfaces, and let anyone who wants to use the component reference the Contracts assembly.


If you have another approach, or a similar issue, or you know, stuff to talk about... Let me hear it.

Friday, June 27, 2008

IoC and DI complexity

Inversion of Control Containers (Ioc), Dependency Injection (DI), and the Dependency Inversion Principle (DIP) are huge blogosphere topics these days.

Quickly, Dependency Injection (DI) is a pattern of “injecting” a class’s “dependencies” into it at run time. This is done by defining the dependencies as interfaces, then passing in a concrete class implementing that interface to the constructor. This allows you to swap in different implementations without having to modify the main class. As a side effect, it also causes you to follow the Single Responsibility Principle (SRP), since your dependencies are individual objects which perform discrete specialized tasks.

Dependency Inversion (DIP) is a design principle which is in some ways related to the Dependency Injection pattern. The idea here is that “high” layers of your application should not directly depend on “low” layers. Instead, the high layers should define interfaces for the behavior they expect (dependencies), and the low layers will come along and implement those interfaces. The benefit of following this principle is that the high layers become somewhat isolated form the low layers. This means if some arbitrary change is made in the low layer it is less likely to have to be propagated up through all the layers. Dependency Inversion does not imply Dependency Injection. This principle doesn’t say anything about how high layers know what low layer to use. This could be done by simply using the low layer directly in the code of the high layer, or through Dependency Injection.

The Inversion of Control Container (IoC) is a pattern that supports Dependency Injection. In this pattern you create a central container which defines what concrete classes should be used for what dependencies through out your application. Now, your DI classes will determine their dependencies by looking in the IoC container. This removes any specification of a default dependency from the classes themselves, and it makes it much easier to change what dependencies are used on the fly.

Clearly, these are some very powerful patterns and principles. Basically, DI and IoC remove the compile time definition of the relationships between classes and instead define those relationships at runtime. This is incredibly useful if you think you may need to modify the way your application behaves in different scenarios.

However, if you pay attention to why these patterns are primarily used by the various people talking about them in the blogosphere you’ll see that it’s for unit testing. The reason people are bothering is because they want to create mocks and stubs of their objects so that they can write unit tests. The Dependency Inversion and Single Responsibility principles that arise from this are certainly an added bonus, but not the primary goal. And the ability to swap in different REAL dependencies is not one that anyone planed to use.

Let’s be realistic. How many applications really need to be able to do the same thing in two different ways at the same time? That’s what DI is for, but I don’t think many people really need that capability. It’s much more likely that your application will evolve from doing THIS to doing THAT. DI will make this migration simpler, but only because it forced you into following SRP and DIP. You could have followed those principles without using DI.

The question is, “If your application doesn’t require DI (except for unit tests), should you use DI?”

The question that leads to is, “What's the harm in using DI for unit testing?”

The answer to that is: complexity. Using DI adds complexity to your application. IoC adds even more complexity.

Where does the complexity come from?
  • There are more pieces and components to keep track of
  • It’s harder for a person to understand how everything fits together into a functioning whole
  • There are more restrictions on the things you can do in your code: you can’t new up a dependency; you can’t require fields through a dependency’s constructor, etc
  • Interfaces can’t strictly define everything (will it throw an exception, will it return null, will it display it’s own error dialogs, etc)
  • With some IoC tools, I have to maintain an xml configuration file…
  • There are simply more lines of code
  • It is harder to browse the code and debug the code (because there are more layers and indirection)
When I brought this up in comments on the YTechie blog everyone told me the problem wasn’t with the patterns, it was with my IDE, or it was because I wasn’t commenting my interfaces well enough… This was mostly because the examples I was using to try to indicate the complexity were trivial.

The point I’m actually trying to make is just that there is more complexity! I need a better IDE because of it! I have to write more detailed implementation specific comments because of it! It doesn't really matter if doing those things are a good idea anyway. The point is that now it's complicated enough that I have to do them, I can't get by without like I could before.

To put it simply, I have to do more work. That’s the harm in DI and IoC (and to a lesser extent DIP): complexity -> more work -> more confusion -> more potential for error -> more chaos over time

The next question is, “Is this added complexity enough of a downside to make DI/IoC not worth it?”

This is the real question that everyone should ask themselves before they dive head first into the newest latest thing. Unfortunately, you’ll find a surprising lack of thought about this. Or even willingness to think about it. When people find something new they like, they don't like to admit it may come with some downsides too, however minor they may be. Don't get me wrong! Some people are thinking about it, like Dave^2. But it the blog world, it's always a struggle to get passed the "It's awesome" to the "but...".

The answer to our question is: It Depends. That’s the Computer Engineer’s motto. And it’s hugely important to remember that it always depends. It depends on your circumstances, and the complexity of your application or component, and an innumerable list of other factors. It's not an all or nothing answer either. It could be no problem here, and total disaster there.

Are having unit tests worth the added complexity for you? As long as you recognize the complexity, you’re fully qualified to make that decision. Personally, I've found many circumstances in which it was worth it, and a few others where it was just too much overhead. But let me know what you decide, and how it works out for you.

Monday, May 5, 2008

Dependency Inversion

Dependency Inversion is a design principle which states:
A. High level modules should not depend upon low level modules. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.

What in the world is that supposed to mean? Basically, the problem Dependency Inversion is trying to solve is the problem of tightly coupled layers. For example, if you're working with a database you might have tables, and stored procedures, and classes to execute the sps, and classes to use the sp classes, and finally a GUI. If you make a change to a table, you frequently have to change every single layer above that, all the way to the GUI... There are many changes for which this is inevitable. But there are some changes for which this could be avoided. Dependency Inversion is a principle for helping to avoid this kinds of water falling changes by isolating the dependencies between your layers.

Here's a picture:
It's "Dependency Inversion" because we've flipped the direction of the arrow from "high to low " to "low to high". The high layer still uses the low layer, but now the high layer is defining what it expects from the low layer, and the low layer is simply fulfilling those expectations. You can completely rewrite the low layer and as long as it still meets the high level's needs the high level need not change.

There's always a down side, so where's the down side here? The downside is that since the interface has been defined at the high level, the low level depends on the high level! What if we want to reuse the low level somewhere else? If this is a statically typed language like C#, we'd have to reference the high level's dll, even though we weren't going to use it, just because it contained the interface definition.

I don't write much in dynamic languages, so I might be mistaken, but in a dynamic language you could accomplish this same pattern without the interface declaration and without the low level depending on the higher level. Less boiler plate + less dependency definition = more flexible code base. As I understand it, that's the main appeal of dynamic languages.

But back in the statically typed world, how do we use dependency inversion AND manage to reuse the lower layer?

No really, I'm actually asking. It's not a rhetorical question. Hopefully you'll respond in the comments.

One possible way would be to make the low layer define it's own interface, then use the Adapter/Proxy design pattern to create a a class that implements the high layer's interface but uses the low layer's interface... This is clearly less than ideal though.

Tuesday, March 25, 2008

MVC and MVP

In two previous posts I discussed the Model View Controller pattern and the various flavors of it: MVC is What Exactly? and MVC in Windows Applications.

In this posts I presented my understanding of MVC that I had gained from various books, articles, blogs, and thought experiments. Shortly after I encountered the term MVP: Model View Presenter. Then I found some articles that described passive MVC differently than I had described it. Then I found some articles about PAC: Presentation Abastraction Control.

In short, I discovered that there doesn't seem to be one definitive definition of MVC, nor of MVP.

From what I can tell, MVP is just MVC where the Controller is allowed to do more work. In that regard, it is more similar to what I described in my posts on MVC. I have also seen arguments that the way I described Passive MVC is actually MVP.

In the end all the issues I discussed then still apply. I just wanted to clarify that this area of design is full of lots of slightly different ways of accomplishing the same goal, and everyone seems to use a different word to describe it.

Update 9/11/2008: Follow up post on MVC and MVP with more details

Wednesday, March 19, 2008

IoC and DI

Inversion of Control Containers and Dependency Injection.

A coworker of mine gave me an MSDN article called Loosen Up which goes over Dependency Inversion, Dependency Injection, Inversion of Control containers, and 3rd party IoC tools. It's an excellent article, I highly recommend it.

In an early post I talked about Dependency Injection and referred to it as a slippery slope. I still feel this way to some extent, but its the only way to do good unit testing, so we're stuck with it.

First I want to point out something obvious I got from that article that I hadn't thought of somehow. In Dependency Injection I mentioned how my classes defaulted their dependencies in the constructor and used Properties to allow different instances to be passed in.

This sucks for two reasons:
  1. If someone does actually pass in a different instance of a dependency, the default will have been newed up for nothing
  2. There are ton of properties on the object that it is likely no one will ever use
What's the obvious way to fix this? Create a constructor that takes in the dependencies. Create a default constructor that calls the other constructor:
public LessStupidClass( depA, depB, depC ) {...}
public LessStupidClass() : this( new depA(), new depB(), new depC() ) {...}
Solves both the problems of the stupid way I was doing it.

On to IoC. The idea behind Inversion of Control Containers is basically that you don't like the fact that the class has a way of specifying its default dependencies. You'd rather have the class lookup what its defaults should be in a "Container of Default Dependencies" that has been pre-configured. This can easily be done by performing the lookup based on the interface type of the dependency. The third party tools (like Spring.NET and Castle Windsor) take this even further and allow you to setup the default dependencies in configuration files.

That's the idea at least. Personally, I'm not a fan. I can see how this might be useful if you actually anticipated swapping in different dependencies frequently, or even at all. However, I'm just doing it so I can unit test. So introducing this container layer just makes it harder for me to figure out what the hell is going on in my code. Its bad enough depending on an interface because I can't "right click -> go to definition" any more. And it only gets worse when you move it into a configuration file...

Maybe I'm missing something here. If so, please let me know. But as far as I can tell, for the ways in which I've been using dependency injection, in which there is only 1 concrete dependency class and there is likely only going to be one, EVER, IoC just adds unneeded complexity. It moves the stuff I need to know further away from the places where I need to know it.

And it "centralizes" my dependencies... In my experience, "centralizing" things is only good when it makes sense that everyone share from the same source. It doesn't make sense to centralize when you're either A) forcing things to match that otherwise wouldn't have to match or B) moving things away from where they are used just so they can be "centered." Centralizing also has the unwanted side effect of causing things to get all tangled together. Now that everyone is sharing the same thing, defined in the same place, I have to be really careful about changing that thing... Because if I change it, it will change everywhere, even if I didn't know everywhere it was used.

Aside: Sometimes you want things to be centralized. But make sure you REALLY want it before doing it. Like consistency, it's not a good idea in and of itself.

UPDATE 6/27/08: for more on complexity, read this followup post

Monday, February 18, 2008

The Elements of Design

In the world of software design, there are 3 distinct classes of "pattern" to be aware of:
  1. Smells
  2. Patterns
  3. Principles
The focus of each of these is primarily on enabling code to be changed and understood.

Smells are symptoms that are frequently demonstrated by code which has not been well designed. These are good to be aware of as they indicate you should probably consider doing something to fix the code so it doesn't smell so bad anymore.

Patterns are common OO design techniques for accomplishing certain behaviors. They were originally captured in the "Design Patterns" book by the "Gang of Four." These are very helpful, less for how they can improve your code, and more as a communication technique between developers. Personally I've found Singleton, Strategy/State, and Mediator to be the most far reaching. These are about as close as Computer Science has come to having terminology that can be used to describe abstract code design concepts. In general, you might fix a code smell with a Design Pattern.

Principles are a cross between smells and patterns except instead of telling you what is bad they tell you what is good, and instead of giving you precise designs to accomplish tasks they tell you what, in general, good looks like in Object Oriented languages. Of all of the three classes, Principles are probably the most useful because they describe design in general. Interestingly, they seem to be less known. Probably because they are both newer and slightly harder to understand. Of these, I have found the Single Responsibility Pattern and the Dependency Inversion Principle to be the most far reaching.

Thursday, January 24, 2008

MVC in Windows Applications

In the last post I looked at what, exactly, MVC really is. Now I want to look at how it applies to Windows applications.

Windows Forms with data binding is basically Active MVC! The data binding keeps the view and the model up to date automatically. When the user performs an action (like clicking a button) an event is fired. Some code executes in response to the event, updating the model and causing the view to be updated. Just like in Active MVC. The only difference is we did it all in two classes, the form class (view & controller here) and the data class. We could separate the controller into its own class if we wanted to, and then we'd have the M, the V, and the C.


Are we comfortable with this? The only problem is that in Active MVC the Model takes on more responsibility because its responsible for keeping the view up to date. But if we're data binding to the model, it has to be 1-1 with the controls we're displaying. There is some potential for this to get complicated if we need our Model to do more advantaged state management. This could cut two ways and could be a great thing, or could become really hairy very quickly.

We could convert this to look more similar to Passive MVC by creating two models. One model will be independent of the view and managed completely by the controller. The other model will be the class we use to data bind into the View. This second model will be updated by the controller to cause values of the view to change and be read/monitored by the controller to respond to user events. With this setup we've moved more of the responsibility to the controller but we've also increased the amount of data passing that has to go on.

And there in lies the rub. On the web, the data passing is required, there is no way around it. But in a windows application, we don't have to pass data around like this. We can write code that gets the data directly from the controls and writes them to the database if we want to. There is no need to have a model class for housing data.

So what are we gaining by using MVC in a Windows Application? We've separated the data from the GUI and we've also separated the "controller" logic from the GUI. This will be nice if we ever want to make changes to the GUI like swapping one control for another. Its also nice because we can now write unit tests for the controller and mock out the GUI (and the model if needed).

So the big question is, are the benefits of an MVC design worth the overhead that comes with an MVC design?

To start with, its certainly not good to have a single form class that contains EVERYTHING. In Windows Forms this is how nearly everyone writes, at least when they're starting out. It seems like the simplest option: 1 form, 1 file, 1 class. Everything is in one place!

But as the form gets bigger (more controls, more rules, more behavior) the number of event methods just keeps rising and before too long you're looking at a 2,000 line class (not including designer code...). You can't remember where anything is and you can't find anything either. It feels like being lost in a jungle.

So we need to come up with a way of breaking this into pieces, no question. We just have to decide what pieces we want. MVC provides us with three pieces. They are nice logical pieces in theory. In practice, you really have to commit to "shoveling data around."

If you were hoping I'd end this by telling you what the best practice is, I'm sorry to disappoint, because I don't know. I'm still experimenting and researching. I'd love to hear your take, or your best practice, or even approaches you've tried and despised.

Update 1/25/08: Added chicken scratch images
Update 9/22/08: Follow up post about MVP and MVC which may be more applicable to Windows Applications and talks about View State.

Wednesday, January 23, 2008

MVC is What Exactly?

MVC (Model, View, Controller) is a design pattern or application architecture, depending on how you want to look at it, used to separate the storage of data from the presentation of data from the processing that takes place when the user interacts with the software.

It's also a huge buzzword in software development that everyone has heard about and thinks they understand but that very few people have ever actually researched or read about.

The concept of MVC was first introduced in the Smalltalk language. The Model stores data, the View presents a user interface, and the Controller handles user interaction.

It was recognized that MVC typically took one of two general forms, Passive or Active. Each form differs based on how the controller and the model behave.

Active Form:
  1. Controller handles user iteration events and updates model
  2. State changes in the model cause the view to update (observer pattern keeps model independent of view)

Note: This means the model can be changed by things other than the controller and the view will still updatePassive Form:
  1. Controller handles user interaction events and updates the model and causes the view to update
  2. Model is completely independent of view and controller
Clearly the Model must carry a lot of responsibility in the Active Form by maintaining state or whatever else is needed to keep the UI up to date. In the Passive Form the Model isn't required to do anything more than house the data. The Controller can manage the state changes.

MVC also appears in a slightly different form called the Document-View pattern used by the MFC (Microsoft Foundation Classes) framework which combines the controller and the model into one object, the Document.

MVC as seen in Ruby on Rails is basically the passive model. The controller is invoked by a user interaction. The Controller builds the model (or tells it to build itself) and/or modifies it as needed, the controller then picks what view to render and passes it any data it may need.

ASP.NET's new MVC framework works almost exactly the same way as Ruby on Rails in terms of MVC (surprise surprise!).

Passive MVC makes tons of sense on the web because the Request/Response nature of HTTP requires a very structured data passing model. Ultimately, that's all MVC is, a standard for how to pass data around:

Data is housed in the Model, accessed and modified by the controller, passed to the view to be displayed, passed back to the controller from the view w/ changes made by the user, etc...

So, MVC is a great thing on the web. It simplifies the code, makes it obvious where to go for what, standardizes the flow of data and rendering of web pages, and exactly matches the behavior of HTTP.

That being said, there are still some variations:
Does the Model match the database schema and just house data (as in .NET Typed Datasets or the new LINQ to SQL objects)? Or does the Model present data in an intelligent (problem domain specific) way and contain high level logic for modifying the Model? I'm not sure it actually matters, honestly. Its just a question of where you want to put your logic, all in the controller or spread between the controller and the model?

So, now we've surveyed MVC, talked about some frameworks that use it, and decided that it works really well for the web. In the next post I'll look at if MVC makes sense in a Windows Application.

Update 01/25/08: Added chicken scratch images

Wednesday, January 16, 2008

Unit Testing: Gateways

In an earlier post I gave an overview of Unit Testing and TDD. Now I'm going to start drilling down into some actual examples of how to structure your code to get the most out of Unit Testing.

In the last post I made the case that Unit Testing improved your object oriented design. I stand by that. But there is a stumbling block. You can still write badly designed code and add badly designed unit tests.

So how do you know what's bad? Just answer these two questions:
  1. Are your tests testing exactly one thing?
  2. "Does the object you're testing serve exactly one purpose?

If the answer to both questions is yes, you're doing great. If not, you may need to refactor.

Of course, those questions are easy to ask, but much harder to answer.

My first example will have to do with code that retrieves data from a database or some other data store. When first starting out people tend to write a classes that include data retrieval along side various "business logic" routines. For example, you may create a class that takes a data table as input, validates it for certain restrictions, and inserts it into the database.

This class does two things, it validates and it inserts. If you unit tested it your tests would be testing two things, that the validation was performed correctly and that the insert into the database was performed correctly. So, how do we refactor this?

Use the "Gateway" pattern. A Gateway is a class which serves as the path to and from your data store. The, err, gateway to your data. I always create one Gateway per "functional unit." So in this case because I'll have a Validator class and a ValidatorGateway. So far our example only requires the ValidatorGateway to have an insert method.

Once we perform this refactoring we'll unit test our Validator and we'll use nmock to mock out our dependency on the database by providing a mock Gateway (through dependency injection). Now when we Unit Test our Validator class we wont be testing that it inserted into the database correctly, only that it intended to insert into the database correctly.

However, isn't that still two different things? Validation and the intention to insert? It is. So we should probably take the Gateway out of the Validator all together. Instead, our Validator will just validate the data and tell us if it passed or failed. Then some other code will utilize the Validator and the Gateway.

Clearly those two simple questions can be very powerful in guiding your design if you take the time to ask them. Furthermore, the Gateway pattern is a very simple and very flexible concept that can easily be applied to nearly any situation. As a freebie, the gateway pattern also gives you the ability to swap out what kind of data store you're using very easily. Need to switch from talking directly to the database to talking to a web service? Just update the gateway and you're done.

Thursday, December 20, 2007

Dependency Injection

Dependency Injection is an "object oriented design pattern" for creating loosely coupled objects. It has nothing to do with needles, and if it makes you think of the Breakfast Club that's not my fault.

Lets say you're writing a class whose job is to find a certain configuration file. Its going to look in a predetermined expected location, and if it doesn't find it there it will ask the user to select it. This object is dependent on the user. And in code, it is dependent on some kind of UI for asking the user for the file.

If we're in C# you can write this object so it creates an OpenFileDialog (which doesn't have the same Memory Leak causing behavior as a regular form, by the way) and displays it to the user. However, this would not be a loosely coupled design. What if you wanted to change this to use the Vista open file dialog? Or what if you wanted to make it force the user to select a valid file by continually asking them until they select one? You'd have to edit the main class. And you'd have to be careful that the user prompting logic didn't become intertwined with the rest of the class' logic.

What can we do? Let's inject our class. Let's inject it with dependencies. Or more accurately, classes that take care of its dependencies for it.

Create an interface like IPromptUserForConfigFile which contains a method that returns the path the user selected as a string. Now modify the constructor of your main class to accept an instance of an IPromptUserForConfigFile class. The main class simply calls the method on this interface, all the details of how the user is prompted are abstracted away. Plus you can change how the user is prompted at any time by simply passing in a different class that implements IPromptUserForConfigFile.

Dependency injection seems pretty simple. It gives you loosely coupled objects, which are very orthogonal, and possibly best of all it makes it easy to unit test with the help of a library like nmock.

What are the downsides? You now have an interface and a class that you otherwise probably wouldn't have created (since you haven't actually had any practical DEMAND for loose coupling yet). And you also have to construct a class that implements the interface and pass it into the main object's constructor. There are libraries to help with that part, like Spring.NET. I've never personally used them, but they exist. Actually, when I've used this pattern I've built in a default implementation of the interface to the main class and instead of passing in the interface object through the constructor I allow you to override my default with a property. This clearly violates some of the loose coupling, but to be honest I'm really not using this pattern for the loose coupling, I'm using it so I can Unit Test.

The biggest downside here would seem to be that the size of your code base has increased. And this has happened to enable loose coupling, but mostly to allow for Unit Testing. Is this a good thing?

When I first started learning about Unit Testing my biggest worry, apart from how much more code I'd be writing and maintaining, was that I would start writing strangely designed code just so I could Unit Test it and not because it was the right design for the situation. You can imagine all kinds of terrible things. Classes with all public methods. Classes with only a single static method that is only used by one other class. Classes with tentacles and suction cups and slimy oddly named and mostly irrelevant properties.

However, I was surprised at how often my design changed for the better due to thinking about testing. My first few unit testing attempts didn't result in any tentacles or other horrible things. That is, until I encountered dependency injection. "Look! I'm making my code loosely coupled!" I thought to myself, "That's a good thing! This Unit Testing really works!"

But dependency injection is a very slippery slope. After all, the majority of classes you write are riddled with dependencies. Things like databases, framework code, web services, user interfaces, other code libraries you've written, etc. Should you seriously create a class to wrap each one of these and then pass those classes into other classes that apply the "business logic" and "glue" between how those dependencies are used? Imagine how huge your code base would be then! And you certainly can't create static classes if you're planning on passing them into another class through a constructor. And of course now that you've created all these objects that wrap various dependencies, you're going to want to reuse them. In .NET that means putting them in their own assemblies. Are we going to end up with 500 assemblies with complicated dependencies? Where do we draw the line?

An object mocking framework like TypeMock (not free!) would help alleviate the need for all the "injection" going on here just for the sake of testing, though you'd still need to create many objects. I need to look into that product more to decide if its worth the cost (its quite expensive). If it is, then the line can be drawn with a question, "Do I need this to be loosely coupled?" If it isn't, then the line needs to be drawn with a different question, "Do I need to mock this for testing or to have it be loosely coupled?" The first question is pretty easy to answer. The second one... maybe not so much.

Lets end with a string of questions. Do you unit test? Do you mock objects? What mocking library do you use? How does dependency injection make you feel?

Tuesday, November 27, 2007

IEnumerable, not just for simple collections

In C# IEnumerable is what lets you say foreach( string s in someListOfStrings ) {}
In C# 2.0 you can create objects that can be enumerated over very easily using the very Ruby-like "yield return" keyword. Here's a dumb example:

private List strings;
public IEnumerable Strings
{
get
{
if ( strings == null ) yield break;
else
foreach( string s in strings )
yield return s;
}
}

The compiler will take care of all the magic of managing the state of your loops or recursion or whatever.

Pretend that the code above was in a class called ExampleStrings. I could write this code:
foreach( string s in exampleStrings.Strings ) {}


Like I said, that was a dumb example, but now you've seen an example of how easy it is to make something Enumerable. And because of how easy it is, I'm a big IEnumerable fan. I've found two cases where I really like to use it:
  • When a library needs to return a bunch of "stuff" but doesn't know exactly how the consumer wants to use it
  • When some non-trivial work needs to be performed to determine what the next element to be returned should be
Take the first one first. Suppose you're writing a library which needs to return the name of all the scanners attached to the computer. You could write this to return a List, but what if the consumer needs a DataTable? You'll build your list and return it, then the consumer will loop through your list and build a DataTable. If you return IEnumerable instead of List you make this O(n) instead of O(2n). You also delay whatever calls need to be made to find out what scanners are connected to when you actually start looping through them. That's because your IEnumerable code doesn't execute when the property is referenced. So in the following code a break point placed in the get of our Strings property wouldn't hit until the last line:
IEnumerable strings = exampleStrings.Strings;
if ( strings == null ) return;
List l = new List( strings );

So maybe O(n) vs O(2n) isn't that big of a deal. And the fact that you don't have to create a List object isn't too huge either. Its still nicer, cleaner, and totally easy to do though, so why not do it?

As usual, its the second bullet that really makes taking a look at IEnumerable worth while. I've used this pattern in two actual projects too. One I referenced in an early post, Fun With Circles. The other I've used when I was manually performing some data paging.

In fun with circles I used IEnumerable to abstract away the calculation that determined the Point where the next dot in my circle should go. That way I completely separated my drawing code from the math to determine where to draw.

In the data paging example I created an IEnumerable DataFetcher. All the consumer had to do was tell the DataFetcher where to start and what direction to go in (start, end, specific record ID and forward or backward) and then simply foreach through the resulting rows. When the consumer had enough rows to fill its page, it would simply break out of the loop. If the data source ran out of data first, then the loop would end on its own. With this in place the consumer was completely isolated from when the data was being retrieved and how it was being "stitched" together. This also made it incredibly easy to add new data fetching behavior to the DataFetcher class as needed. Then by simply setting a property on the class you could change its underlying behavior without the consumer updating any other lines of code.

Of course, IEnumerable isn't required for any of this. You can accomplish the same thing with a GetNext() method. IEnumerable just adds some very nice syntactic sugar to both the consumer's code and the source's code.