Oct 052011
 
Web browser usage share fr

Image via Wikipedia

Reading the book Responsive Web Design has got me to thinking.

I’ve been a web developer in some capacity or another since the mid 90s (oh, hey, turns out I’m old).  Over the past decade and a half, philosophy about browser experiences has evolved along with browsers, following a pattern that looks roughly like this:

Triassic: Support all browsers in existence, especially older versions.  Do whatever it takes to provide the same experience everywhere.

Jurassic: Provide the best experience in modern, standards-compliant browsers and degrade gracefully in older browsers.

Cretaceous: Screw older browsers.  Seriously, folks, upgrade.  I’m tired of making table-based layouts just for you.  If you’re still on IE5, my website is the least of your worries.

The point is, as the Old Browser dominance picture shifted, so did the philosophy about how much to worry about their design.  We want our websites to be usable in IE5, but we’re not concerned about IE5 when we make a website.  We do not spend thousands of dollars trying to preserve a pixel-perfect analog in browsers that are significantly less standards compliant than the browsers of today.

Today, there are all kinds of ways progressive websites are preparing an experience for mobile delivery – tablets and phones, primarily.  They make URLs for mobile versions of the site.  They use more flexible and responsive layouts.  They use media queries.  By and large, the dominant philosophy is to design the website per normal for the desktop, then do whatever special things you need to do to make them decent on a mobile device, not entirely unlike how we used to think about older browsers.

I wonder if we aren’t staring down the barrels of needing to design to modern browsers, and by that I mean mobile ones.  At what point do we treat desktop browsers like we used to treat IE5?  In other words, have we come to the point where it makes sense to design your website for mobile delivery, then make it gracefully adjust to desktop browsers?

We may not be ready for the “screw desktops” phase of web development, but we may get to that point quicker than you’d think.

Aug 182011
 
AbiWord HTML

Image via Wikipedia

Dear InfoWorld and Web Developers Who In All Ages Continue to Misunderstand Markup,

HTML 5 is/does:

  • A markup specification
  • Used in a text file that will be transmitted over the Internet
  • Attach semantic metadata to the aforementioned text
  • Use words that appear between greater than and less than signs in that text file – slashes sometimes involved

HTML 5 is/does not:

  • Display media
  • “Use the Cloud”
  • Create Flash or other animations
  • Hit databases, local or otherwise
  • Make things move
  • Do anything visual whatsoever

Snide comparisons to criticizing HTML 5 for things it is/does not:

  • One of the hard truths about gasoline is that there are a lot of car wrecks out there.
  • One of the hard truths about the U.S. dollar is that people sell drugs.
  • One of the hard truths about modern plumbing is that my boss hit me with a lead pipe.
  • One of the hard truths about movie theaters is that Highlander 3 sucked.
Jun 222011
 
Diagram showing example of inheritance - birds

Image via Wikipedia

In 1987, Barbara Jane introduced a principle that henceforth became known as the Liskov Substitution Principle (sorry Jeanette).  The upshot of the principle is this:

If you have a type of something (Dog) and a more specific subtype of that type (Beagle), then you should be able to substitute the subtype everywhere you have the type and not meaningfully change any of the properties.  So, if I’m writing a program about dogs, I should be able to substitute in Beagle everywhere I have Dog and basically have things stay the same.  This is a good programming principle for coding to abstractions and not violating the contract those abstractions imply, which is why the Liskov Substitution Principle is the “L” in SOLID.

An example that gets thrown around in talking about this principle is, if you have a Square class, and you have a Rectangle class, which one should be the type and which one should be the subtype?  Geometrically speaking, a Square is a more specific type of Rectangle, and you’d think that Rectangle should be the type and Square should be the subtype.

“Ah, but hold!” say the Liskov nerds.  “That way lay disaster and ruin, for the Rectangle will have Width and Height that can be set separately, while the Square’s Width and Height must change the other when one is set.  Thou canst no longer substitute a Square for a Rectangle and get the same expected behavior, for the Height and Width are independent in the type, but co-dependent in the subtype.”

Now, developers will look at that and immediately think of many ways using composition and generics to sidestep this problem altogether.  Eliminate the inheritance hierarchy while sharing structure or functionality.  But Barbara Jane didn’t have some of those solutions available in 1987, and even if she did and we decided to keep to this proposed inheritance structure, what are we trading away, and are we actually violating LSP?

We could make the Square and Rectangle immutable, and that would solve the problem.  The problem isn’t the inheritance model, per se, but the behavior of setting Height or Width.  If you remove the setters, the problem goes away.  This may be quite limiting to a program that had to deal with squares and rectangles, however.

If we reverse the hierarchy and make Square the type (maybe with a Side property) and the Rectangle a subtype (inheriting Side and adding… well, I don’t know what you’d call it… OpposingSide?  OtherSide?), we might be doing the “right” thing from an LSP standpoint, but we are certainly sacrificing the clarity of the domain.  We are no longer modeling truth – that is, that a Square is a Rectangle with an extra business rule, and the difficulty of naming the common property and the extra property a Rectangle would have just illustrates this.

Maybe that doesn’t bother you, but it bothers me.

If a domain model is supposed to be a ubiquitous language between a business process and software, then shenanigans like this violates that trust.  We know the business is one way in reality, but we’re going to model it a different way for the sake of the integrity of a coding principle.

If you were writing software for a veterinary hospital, you wouldn’t make OneLeggedDog the type and Dog the subtype because the Dog has more legs.  Clearly, the Dog is the base type, and OneLeggedDog is a more specific type.

Then there’s the issue of how much of a violation this actually is.  I admit, if you substituted a Square for a Rectangle, and you did not know this substitution occurred, then it would be a surprise to find that changing the Height also changed the Width.

But this is actually expected behavior for a Square.  In fact, it’s definitive behavior for a square.  One could just as easily argue that, if the Square were the type and the Rectangle the subtype, this is an LSP violation because you would not assume a Square’s sides could be set independently.  You would assume your type (Square) would constrain all the side lengths.  Without care, the LSP principle could argue against virtually any kind of overriding, disrupting what you’d “expect” from a base type.

Yes, I know.  You can do plenty of overriding without fiddling with expected postconditions, but do you see what I mean?  The LSP can’t be the end of a discussion on how to model a domain.

Thankfully, modern OO languages give us lots of options to avoid this very thing.  An IPolygon interface with a Sides collection comes to mind – allowing us to faithfully model the domain and keep the LSP intact.  And if there’s a moral to my rambling story, maybe that’s it.  That if you’re violating the LSP, perhaps that should spawn conversations about how you could more flexibly, yet accurately, represent a domain, and not be something you have to shoehorn conformity to in ways that don’t describe reality.

Feb 242011
 
IMG_9840

Image by sunshinedistrict via Flickr

On February 17, 2011, Ayende said this stuff.

Oh, look everyone – a lesson on simplicity from the man who invented HBM files!

Leaving aside the specifics of the recommendation and the perhaps unwarranted comparison to CQRS, every developer needs to put aside their ego for a moment and think about the values that Ayende is trying to preserve: simplicity of understanding code and ease of modification.  I hope that any developer who isn’t deliberately trying to show off or maintain job security by way of obtuseness agrees that these are good values to protect.  So, we’re on the same page in terms of what’s important in this discussion.

What is the general way Ayende is recommending to protect these values?

Don’t have abstractions for the sake of having abstractions.

Here is where there may be a fork in the road, and I have to side with Ayende on this.  We love our DDDs, SRPs, SOLIDs, and a whole lotta other acronyms.  I see too many developers start every solution with an ORM, an IoC container, an MVC framework, a services layer, a domain model layer, and all of this spread out over fifty different assemblies without even stopping to think what value all of this brings to their specific project.  It’s just what you do.

The problem is that nothing is the right way to do every project.  Even something as common as using a relational database for persistence isn’t right for every project.  There’s a reason this guy notes patterns like Active Record and Transaction Script.  The fact is, a thoroughgoing multilayered approach to every application is not appropriate, even if it might be the right choice for a good number of them.

The project I’m working on now is distributed across multiple servers and a WCF layer (on its own machine) bridges between the database server and the web server (on their own machines).  Does my solution have several layers in it?  Yup.  I have assemblies that will be on different machines and a requirement to make all calls through WCF.

Furthermore, the infrastructure of my project is volatile.  The RDBMS hasn’t even been decided on, and we started development a month ago.  This application also needs to communicate to a mainframe and possibly one other proprietary data store.  The jury is still out on whether or not we have to make all queries via stored procs.  The ability to swap out implementations of the respositories, ORM, etc. has real value to our project.

Do all projects need this level of modularity?  Not at all.  And the less modularity I think I need, the less abstractions I will have.

Then we get to the actual, specific recommendation: Ayende wants to see the UI make direct calls to NHibernate.

The irony of this is, if you wanted to use the simplest data access route possible, especially if you go a CQRS route, then NHibernate is the kind of thing you don’t necessarily want and certainly don’t need.  DataTables work just fine.  Stored procs work just fine.

The reason we love NHibernate (and I do) is because it solves a specific problem – disparity between a domain model and the structure of a data store.  If you don’t need a domain model, or there is no disparity between your model and data store, why on earth would I add an extra layer of mapping in there, even for write operations (note: Ayende’s example is a read operation)?

The thing is, a domain model does more than provide a means of shuffling data around – it models a business and business processes.  Domain objects have dependencies on each other because distinct business elements have dependencies on each other in reality.  If all your app does is act as a front end to a database, and your infrastructure is nice and stable, then by all means, lose the domain model.  Use stored procs and DataTables and DataReaders and go nuts with your poorly-abstracted self, because abstractions will buy you very little.

But if your application is actually automating business processes, then maybe the simplest route to data access shouldn’t be your primary consideration.  Maybe it’s worth modeling business truth in your app and not a convoluted SQL query or HBM file.  Maybe the ability to test that you’ve accurately captured your business’ logic and not just whether you’ve got the right fields on a page will buy you something.