Patterns and Principles (Part I) - Getting Started

by Rasmus Kromann-Larsen October 24, 2008 15:54

Introduction

Design patterns and principles are a fundamental thing in software development. Yet they're can be quite elusive and difficult to get into. As one of my goals with this blog is to further my own knowledge, as well as share it with others, I've wanted to do posts on basic object oriented principles and patterns. I believe that patterns is one of those things you grasp best when actively thinking about them - and thus to improve my own skillset on patterns, writing blog posts and thinking up good examples is a great way to go.

While this post is mostly an introduction to the series, my approach will definitely be a pragmatic one. I'm aiming to have two types of posts in this series, basic posts introducing specific design patterns or principle with up-to-date .NET examples and more advanced posts on the variations of the patterns and my own crazy experimentation with them. In any case, both types of posts should be brimming with examples if all goes as planned.

Design Principles

Drops of distilled wisdom and experience. Most of these principles deal with increasing maintainability, testability, flexibility, reducing (unneeded) complexity and attaining high cohesion and low coupling. Allowing you to mitigate at least one of the inevitable three (death, taxes and changing requirements).

I personally see them as guidelines for thought, not golden rules, you might encounter situations where fewer of these principles may apply, as there's often trade-offs involved. However, keeping them in mind is a way to open your eyes to other solutions. In my experience, some of them are easier to be adamant about (DRY springs to mind), while some are more subjective considerations and best practices. I guess my point is that you should avoid following anything blindly without thought. Broaden your horizon, don't narrow it.

I'll not dig too deep into these, but rather give a short introduction in this.. uh, introduction post. Note that this is not an exhaustive list.

  • Single Responsibility Principle
    • Separation of Concerns. An object should have one and only one reason to change, thus increasing cohesion and avoiding coupled responsibilities. It ties into many of the other principles.
  • Open/Closed Principle
    • Your software entities should be closed for modification, but open for extension. Hard to explain briefly, but the gist is to be able to extend the system without modifying existing code (save for bugs). Examples could be: Avoiding dependencies on internal workings and down-casts to specific types.
  • The Interface Segregation Principle
    • Do cohesive, responsibility-based interfaces (think roles) instead of huge general interfaces. Your clients will then only depend on a minimal subset of your methods, instead of potentially depending on methods they're not using.
  • DRY
    • Don't Repeat Yourself. Duplication is bad, mkay? A good example of this is duplicate code, you'll always miss at least one spot when making changes later.
  • Dependency Inversion Principle
    • "High level modules should not depend upon low level modules. Both should depend upon abstractions.". Seeks to lower coupling in the system and increase testability. Applied through dependency injection and often IoC (Inversion of Control) containers.
  • Liskov Substitution Principle
    • Informally: When defining an interface or contract, the system should be able to use any (correct) implementation of it. That is, clients of the contract should not have to know the implementation details (or depend on them). Ties into Design by Contract.
  • Law of Demeter
    • Also known as the Principle of Least Knowledge. Don't talk to strangers. The law states that a method on an object should only call methods on itself, parameters passed in to the method, objects it created and composite objects. This means don't go dot, dot, doting yourself into the entire object tree.
  • Tell, Don't Ask
    • Aim to tell objects what to do instead of asking it about it's state and deciding what to do. The idea is that the object probably knows better than you. It also forces you to think about responsibilities.
  • YAGNI
    • You Aren't Gonna Need It. From Extreme Programming. Don't waste your time adding functionality based on what you think the future might bring. You will (most likely) be wrong. In addition, you will have to maintain this extra code and complexity. Variation of KISS (Keep It Simple, Stupid).
  • Favor Composition Over Inheritance
    • Inheritance is often over- and misused. Inheritance is an 'is-a relation' and is often used as a 'has-a relation' (composition). An advantage of composition is that composed objects can be replaced dynamically - and they can vary independently. Inheritance still has it's place in some cases though (Hint: When you have an 'is-a relation').

Design Patterns

Design patterns are reusable solutions to recurring problems in software development. One of the best points about design patterns is that they allow developers to talk on a higher level, since they have a shared vocabulary of design techniques. Seeing pattern names in code can also communicate an intent that can otherwise be hard to see.

A lot of the same things from the design principles section apply here too. An UML diagram describing a design pattern is just one instance of the pattern - they're meant for inspiration and almost all patterns have several variation points.

I'll not even try to list design patterns yet, they come in all shapes and sizes, better save something for next time.

Literature

While blog posts and other online sources are good for quick answers, nothing beats sitting down with a well-written book on a subject.

 

Design Patterns: Elements of Reusable Object-Oriented Software

Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides

If you've read anything about patterns, you will undoubtedly have heard of the GoF (Gang of Four) book, the often proclaimed Bible of Design Patterns. While this is a great book, especially as a reference catalogue of patterns when you want to look something up, I was kind of lost when I read it the first time. The book is rather abstract and it can be rather confusing for someone starting out with design patterns. I really think you should make it part of your book collection, but if you're starting out with patterns, I would recommend starting out with this book instead:

Design Patterns Explained: A New Perspective on Object-Oriented Design

Alan Shalloway, James Trott

This book was my personal eye-opener. It is somewhat more chatty than the GoF book, slightly less catalogue, slightly more "getting into object-oriented design". It's a great introduction to design patterns and the authors go to great lengths to not only describe the patterns, but to discover them by examining different solutions and quantifying the strengths and weaknesses. This is a great book for bridging the gap before GoF.

 

Refactoring: Improving the Design of Existing Code

Martin Fowler

While refactoring is not design patterns per se, refactoring is a method to mold your code (or others code) towards some of the same goals as the ones presented by design patterns. It's all about improving the maintainability and flexibility of your software. Fowler does a fine job of explaining the reasons for the different refactorings, describing code smells and which tools to use to get rid of them. Another reason knowledge about refactoring is good is that often, you won't have the luxury (or curse) of working solely with your own code. Refactoring can be a great tool to unravel spaghetti code and gaining insight while (hopefully) adding tests to support it.

Online Resources

If you want to get started reading more about patterns and principles, here's a few good links for getting started.

Conclusion

In this post, the first in a series of N, I gave a short introduction to design patterns and principles. I've outlined some recommended getting-started literature and hope to have sparked your interest. Next part will be a basic post describing the first pattern.

Note: I could have more sources in this post, but most of this post is tidbits from experience, opinion and a compilation of snippets from way too many sources. I'll list them in following posts, when we dig into the detail.

kick it on DotNetKicks.com

Tags: , ,

Development | Design Patterns

BlogEngine.NET, TinyMCE And SyntaxHighlighter

by Rasmus Kromann-Larsen October 21, 2008 19:55

I went through my few posts the other day to put some tags on them using BlogEngine.NETs administration page, but as I finished and went to see the end result, TinyMCE had stripped my syntax highlighting.

Apparently this is a known issue and there's a fix to have TinyMCE allow pre html tags to keep their name attribute (needed for syntaxhighlighter). The fix can be found on Scott Dougherty's page here.

Furthermore it seems that TinyMCE eats my indentation which is rather annoying. Scott's fix didn't solve this, so I'll have to either avoid online editing or find a fix for this as well.

If you know, please let me know.

kick it on DotNetKicks.com

Tags: , , ,

BlogEngine.NET

Ditching ActiveRecord For More NHibernate Love

by Rasmus Kromann-Larsen October 15, 2008 22:19

Introduction

I had a project using an old version of Castle ActiveRecord and NHibernate 1.2. Lately there's been a lot of interesting projects surrounding NHibernate and I've been wanting to make the switch away from the old version of ActiveRecord.

ActiveRecord is a thin layer on top of NHibernate that makes it easier to use and configure, especially through configuration using attributes on classes and properties (hence the ActiveRecord name as seen in Ruby on Rails). However unless you build all the tools yourself, it can be quite the dependency hell to play around with all the new NHibernate toys. So I wanted to eradicate ActiveRecord from my reference list and upgrade NHibernate from 1.2. So I thought I'd share my experiences and some of the useful links I found along the way.

Fluent NHibernate

One of the new things I wanted to try out for NHibernate was Fluent NHibernate, a refreshing new way of doing configuration using a fluent interface in C#. NHibernate is usually configured through XML files that look something like this:

<?xml version="1.0" encoding="utf-16"?>
<hibernate-mapping  auto-import="true" default-lazy="false" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:nhibernate-mapping-2.2">
  <class name="Model.Survey, Model" table="Surveys">
    <id name="Id" access="property" column="Id" type="System.Guid" unsaved-value="00000000-0000-0000-0000-000000000000">
      <generator class="assigned">
      </generator>
    </id>
    <property name="Name" access="property" type="String">
      <column name="Name"/>
    </property>
    <property name="Label" access="property" type="String">
      <column name="Label"/>
    </property>
    <property name="HeaderFile" access="property" type="String">
      <column name="HeaderFile"/>
    </property>
    <property name="FooterFile" access="property" type="String">
      <column name="FooterFile"/>
    </property>
  </class>
</hibernate-mapping>

Actually I don't mind XML files that much, except that they are cumbersome to write. But moving to code has it's merits. First of all you get the static type checking from the compiler, which is nice for avoiding spelling mistakes and such. Secondly, having your mapping directly in code makes it refactor-friendly. Renaming properties will automagically propagate to your mapping and reduce strange errors. However, unless you specify column names for your mapping, you might end up refactoring your database indirectly (depending on how you manage your schema), so keep that in mind. Third of all I like the clarity and readability of the configuration:

    public class SurveyMap : ClassMap<Survey>
    {
        public SurveyMap()
        {
            WithTable("Surveys");

            Id(x => x.Id).GeneratedBy.Assigned();

            Map(x => x.Name);
            Map(x => x.Label);
            Map(x => x.HeaderFile);
            Map(x => x.FooterFile);
        }
    }

Notice the clever use of lambdas and expressions to avoid strings. Nice indeed. The Fluent NHibernate package also includes a some "framework" classes to ease the testing of your database mappings, as outlined in this post by Jeremy Miller.

LINQ to NHibernate

I haven't had much time to try LINQ yet, so getting my NHibernate upgraded meant a chance to try out LINQ to NHibernate. Actually LINQ to NHibernate is scheduled for NHibernate 2.1, which is not out yet, but Daniel Guenter has created a backport for NHibernate 2.0. Playing around with it was a pleasant change from writing SQL or HQL in in strings. I haven't spend that much time on expanding the use of IQueryable<T> into my application yet, but I did convert my repositories so they use LINQ now. I really want to experiment more with this and I think I'll draw some inspiration from this post by Søren Skovsbøll on his repository layout.

Gotchas

I ran into a few issues when doing the actual conversion.

As my focus was to upgrade my version of NHibernate, I didn't want to convert all my mappings to Fluent NHibernate from the beginning, so I wanted to generate the XML mapping files from my ActiveRecord configuration and then use these as my basis for going fluent later. However, I was using an InPlaceConfiguration with ActiveRecord which is really just a glorified dictionary of properties for setting up connection strings and such instead of an XML file or a web.config section. ActiveRecord Configurations have a Debug property which will output the XML mapping files for you, but unfortunately this property was read-only in my old version of ActiveRecord. I actually checked and it seems to be fixed in the ActiveRecord trunk. So I converted my InPlaceConfiguration into an XML file and enabled debug to get my mappings.

There was some breaking changes in NHibernate 2.0, as outlined in this list by Ayende. The only one I ran into was that configuration values no longer were prefixed with "hibernate". This threw me off with some peculiar errors at first until I found the list.

The last thing I ran into was actually a feature from ActiveRecord that I use on application startup called "VerifyModelsAgainstDBSchema". What this does is to verify that the database schema has the necessary table and columns to fit your mapping. Since the application is question is designed to be very drop-able in terms of throwing it into a web directory and starting it up, I've included functionality to create the database if needed. Luckily, this feature is implementing using very little code. If using LINQ to NHibernate, it can be done as easy as:

try
{
    var query = (from o in Session.Linq<Object>()
                 where 1 == 0
                 select o);
    query.ToList();
    IsDBInitialized = true;
}
catch (ADOException ex)
{
    _dbExceptions.Add(ex);
}

The trick (as far as I understand) is that NHibernate supports polymorphism in query engine, so by querying for objects of type Object, you're actually grabbing all the tables in your mapping and thus checking the consistency - since the SQL statement will fail on invalid table and/or column names. By adding the always false statement 1 == 0, you make sure that you don't actually pull anything from the database. Clever.

Conclusion

In this post I described my 8-hour hike from an ancient version of ActiveRecord to NHibernate 2.0. It was actually very smooth and the problems were easily solved. I'm really looking forward to working more with these new exciting technologies. Enjoy.

kick it on DotNetKicks.com

Tags: , ,

NHibernate

Embedded Scripting Language? Boo!

by Rasmus Kromann-Larsen October 07, 2008 21:59

 

Setting the stage

In a recent project, I've had the need to use an embedded scripting language. The main purpose was to give the end user a DSL like feeling, while retaining the power of a full-fledged scripting language. For a long time the project has been using IronPython to provide this, but recently I've run into a few problems and started searching for something new.

Problems with IronPython

One of the strategies I've used is to have functions that return functions to provide a more humane syntax, like so:

def TextWidth(width):
  def f(xq, xs):
    xs.SetTextWidth(width)
  return f

 

The idea here is that the users script will create a function that will be called later in the correct context and have the inner function take other arguments. However, it does make the script files more verbose and it can be hard to read the functions when they get more complex. Also it's very hard to add extra arguments to a given script context, since you have to find all the functions called in this context and add the argument to the inner function.

Lately, I've been finding myself leaning more in the direction of Ayende's anonymous base class approach. Basically, what you do is to provide a class that wraps the end user script and provides the scope of functions that can be called from the script. However, Python's class mechanics lend themselves very badly to this method, because Python requires abundant amounts of self keywords.

Another idea I had using the anonymous base class approach was to separate the actual scripting logic from the API using the bridge pattern. In pseudo-Python, it'd look something like this:

def TextWidth(width):
  impl.SetTextWidth(width)

 

I will probably write another post about this, but the main idea is to be able to swap the implementation of the script logic on runtime. One use of this could be to find more errors when new scripts are entered, by using a script logic implementation that performs extra validation on the arguments instead of actually performing the intended actions.

Enter Boo

I've had my eye on Boo for quite a while. It's an object oriented statically typed programming language that looks a lot like Python, written on the .NET framework. It's open source and was created in 2003 by Rodrigo B. De Oliveira. The really cool thing about Boo is the focus on extensibility. It's rather easy to insert extra steps into the Boo compiler if you want your own special macros or syntax.

So I grabbed the latest stable bits from Boo distributions (version 8.2), started up a new VS project and added a reference to Boo.

Compiler or Interpreter?

As mentioned in Arron Washington tutorial on Boo as a scripting language, it's possible to either use the Boo compiler or the interactive interpreter. I went with the compiler. I don't have intimate knowledge of the differences between Boos compiler and interpreter, but usual trade-offs include things like speed, since you're running compiled code instead of traversing some form of the abstract syntax tree.

One thing to keep in mind when using the compiler is that you can't unload the assemblies you create unless you unload the entire AppDomain. So unless you worry about AppDomain boundaries and have criteria for unloading your script AppDomain, memory usage will increase as you continue to compile different things. This problem is beyond the scope of this post, but Google is your friend. As my application is an ASP.NET application that usually gets recycled rather often and because my scripts are semi-static, I've decided not to dig deeper into this. Maybe if circumstances change.

Simple Example

As a simple example, the below snippet will load up the Boo compiler, compile a simple script where I inject some code into a class and call the method via the C# interface.

 

namespace BooConsoleApp
{
    public interface IRunnable
    {
        void Run();
    }

    public class Program
    {
        public static IRunnable CompileToRunnable(string source)
        {
            // Boo class we're injecting our code into
            // A simple Test class implementing our IRunnable interface
            var classDef = String.Format(
@"import BooConsoleApp
class Test(IRunnable):
  def Run(): 
    {0}", source);

            var booCompiler = new BooCompiler();
            // Compile to memory
            booCompiler.Parameters.Pipeline = new CompileToMemory();
            // Compile as library to avoid missing 'No entry point' error
            booCompiler.Parameters.OutputType = CompilerOutputType.Library;
            // Add our Boo code as input
            booCompiler.Parameters.Input.Add(new StringInput("test", classDef));

            // Compile the code
            CompilerContext context = booCompiler.Run();

            // Very basic compile error handling
            if (context.Errors.Count > 0)
                throw new Exception(context.Errors.ToString(true));

            // Create the actual instance of our IRunnable
            var runnable = context.GeneratedAssembly.CreateInstance("Test") as IRunnable;

            return runnable;
        }

        public static void Main(string[] args)
        {
            // Compile our hello world
            IRunnable runnable = CompileToRunnable("print 'hello world'");
            // Run the program
            runnable.Run();
            Console.ReadLine();
        }
    }
}

 

And the output is as expected:

image

Conclusion

In this post I gave a short primer on getting started with Boo as embedded scripting language. I hope to follow up with more advanced topics. Good luck on getting started with Boo until then.

kick it on DotNetKicks.com

Tags: , , ,

Boo | Development | IronPython

Powered by BlogEngine.NET 1.6.1.0
Theme by Mads Kristensen | Modified by Mooglegiant | Adjusted by Rasmus Kromann-Larsen

About Me

I am a danish .NET developer blogging about the technical side of my life, mostly .NET stuff, but also fundamental topics like design patterns, principles and productivity boosters.

In addition, I am a core group member of Aarhus .NET User Group.