VMWare Host Only Networking problem

I just spent an hour fighting to get my host machine to be able to connect to my virtual/guest machine.

I have a virtual machine running a website staging server. I am using XAMPP to run Drupal, PHP and MySQL; because XAMPP is inherently insecure (which is fine for local developer boxes) I really wanted to only use host-only networking.

The guest would easily connect to my host computer using Windows Networking, but not the other way around. My host could not even ping the guest, and when I tried to connect to it using windows sharing (after getting Windows 7 to diagnose the problem) I got the following message:

“Your computer appears to be correctly configured, but the device or resource is not responding”

This was a real pain, because I wanted to be able to use FileZilla on my main/host computer to transfer files directly from my staging server to my production/live server.

I noticed that if I did an “ipconfig” on the host that I would get this for VMnet1 (which is the VMWare host-only network adapter by default):

But in the Virtual Network Editor inside VMWare Workstation 7.1.3 the IP address was SUPPOSED to be 192.168.84.0! Even setting the IPv4 address using the network properties didn’t change this. I fought with this for a while, trying to get the adapter to use the correct IP address…

After much searching on the net (to no avail) I decided “why fight it”? Rather than try and get the adapter to use the correct IP address, I would instead configure the VMWare Virtual Network Editor to use the IP address that the adapter seemed intent on using.

So in VMWare I used the Virtual Network Editor to configure the VMnet1 Host-only adapter to use the 169.254.200.0 subnet address:

This worked perfectly the first time, and my host could then easily connect to my guest OS, and (after updating my guest’s static IP address) my guest could connect to my host.

I hope this helps.

Robert

Tool windows with MVVM

I got the following great question today:

Robert…loved that July article on MVVM and AvalonDock.

You solved my adapting of “DocumentContent” MVVM views.

Now I need to do the same for “DockableContent” views. I am curious what general (or specific) guidelines you would recommend. In my case….there would be a fixed number of “DockableContent” views.

Setting the stage: A real-world example

To address this, let’s use the application I’m currently developing for my business to provide a concrete and real world example. My software is an easy to use financial planning tool that is based on a visual “lifeline” which is specific to the current user. Users can simply drag-and-drop financial items – called lifeline items – onto the lifeline, and the tool calculates the wide variety of financial metrics over time. For example, you can drag-and-drop expenses, employment, kids, mortgages, etc, and the tool will calculate income, expenses, assets, liabilities, etc.

To avoid (modal) dialog boxes – always a good usability practice to avoid dialog boxes! – I make heavy use of dockable tool windows. Furthermore, I enable and disable certain tool windows based on the type of document the user currently has open. In the screenshot below the user has a lifeline open and there are actually eight tool windows available! However by default only two of these are actually pinned open. In the image, the draggable lifeline items are displayed on the left, and the properties of the currently selected lifeline item are displayed on the right:

Other tool windows available are “Help” which is docked up to the top left, “Undo”, “Transactions” (which displays the financial transactions for the currently selected lifeline item), and “Lifeline item graph” (which displays a graph of the important financial aspects of the currently selected lifeline).

While the undo tool window is tied to the current document, almost all of the other tool windows available are tied to the currently selected item on the lifeline. When no lifeline item is selected, the properties window displays information about the lifeline as a whole. In the above screenshot the “baby” lifeline item is currently selected, and in the right-hand properties tool window you can see the initial baby expenses associated with that lifeline item including car seats, cribs, and monthly diaper expenses.

Of course I’m using MVVM for all of this!

 

Using MVVM to control available tool windows

As you can imagine I have a very rich domain logic layer, with hundreds of classes. This results in a very large view model layer as well (unless you are using dynamic proxies, or exposing your domain classes directly to the view). As mentioned in the MSDN article, I’m using a document manager adapter to keep the management of the documents in the view model layer and out of the view layer. I use a very similar separated approach to control which tool windows are open for each document type. This allows the view model layer to control which to Windows are available for a given document type (which is very powerful). However, I found that in the case of controlling tool windows, it was enough to simply have the view-model layer provide an IToolWindows interface with a collection of Boolean properties, where each Boolean property determines if a tool window is available or not. Then the view layer implements this interface with a concrete implementation that knows all about my docking component. The concrete implementation is then injected into the view model layer when the application is initializing. This is the standard “dependency injection” design pattern, however I typically do manual dependency injection to avoid the long-term maintenance ugliness of IOC containers.

This simplified approach avoids the need to raise many events (and therefore wire-up all the event listening code) but is different than the document-manager adapter approach discussed in the article. However for the sake of simplicity (around tool windows) and ease of implementation I was okay with this difference in my design.

The overall approach helps me follow my first bit of MVVM guidance:

MVVM Guideline #1: Strive to minimize the code used in the XAML code behind by putting as much code as possible in the view model layer (but don’t get stupid about it).

This approach has a small amount of code in view layer, which implements the interface and interacts with the docking controls. However, the vast majority of the code is in the view-model layer, which allows me to easily replace the docking controls if need be: I only have to replace the one class that implements the interface.

Of course, I get all the other benefits of MVVM such as separation-of-concerns, and the ability to easily write unit tests against the bulk of my code (in the view-model layer).

 

Using MVVM to display stuff related to the document

To display document related content in the tool windows, I have a special class called ActiveDocument in my view-model layer. Not surprisingly, this class always contains information about the currently active document, regardless of the type of document that is currently active. This class is actually a Singleton, and so it exposes a static “Instance” property which is easy to data bind to.

The class hooks into the view model document manager to provide its functionality. Thus, the Undo tool window can easily bind to the list of changes that need to be displayed:

<ListBox
ItemsSource=”{Binding UndoList,
         Source={x:Static documents:ActiveDocument.Instance}}” />

 

And similarly, the Properties tool window data-binds to a property of the active document’s view-model:

<!– Include data templates for the lifeline item view-models here
using resource dictionaries so that the right property-editor (baby, mortgage, etc) shows up –>
<ContentControl    VerticalAlignment=”Stretch

        HorizontalAlignment=”Stretch
        Content=”{Binding ViewModel.ActiveObject,
         Source={x:Static documents:ActiveDocument.Instance}}” />

 

MVVM Guideline #2: Don’t get stupid about following #1.

In actuality, my undo functionality is not as simple as a simple ListBox displaying a collection of undoable changes. Instead I wrote a custom WPF control understands that it is displaying undoable changes and knows how to invoke those undoable changes based on user actions. It is almost certainly possible that I could have done this using pure MVVM, but a user control was dramatically easier to implement. Sometimes, putting logic in the view layer is the right decision, especially when there’s a lot of user interaction based on clicking, selecting, selecting multiple items, or dragging. Like every other design pattern, MVVM is simply another tool in your toolbox that should be used with careful consideration and thought. I try and put as much code in the view models possible, but sometimes after thinking about how to do that I cannot come up with any elegant solution, and so I will resort to using a more “Windows Forms” programming style in those cases with code in the XAML code-behind.

However, it is been my experience that the majority of the time MVVM works quite nicely. For example, for my Properties tool window, the code sample above is my actual application code copy-and-pasted into this blog entry. Even the lifeline view (in the application screenshot above) is just XAML using MVVM with a very simple data binding:

    {Binding LifelineItems}
						

Coding without a License: The trick question of “Counting code with LINQ”!

The job offer

My small business recently posted a job offer for a part time contract C# and WPF developer. Here’s a snippet from my job posting:

I am not really interested in your resume or schooling as much as I am interested in:

  • Your programming prowess
  • Your communication skills
  • Your ability to work independently and with others
  • Your ability to get things done and done elegantly

If you are interested, please send me your answers to the following:

  • What is a dependency property?
  • When would you use an attached dependency property?
  • Write a thread-safe singleton in C# and explain why it is thread-safe.
  • Write a C# program that counts and displays the number of lines of C# code across all files in the current directory and all subdirectories.
  • Compare and contrast an RRSP with a TFSA.
  • Suggest some alternatives to using dialog boxes from a usability perspective.

You are of course welcome to use the internet to help answer these questions

And at the very bottom of the job posting I wrote:

“BTW, I will only be contacting applicants that have great answers to the above questions.”

I received about 15 job applications from people that had not even bothered to answer the questions and who “spoke English really good” (or words to that effect). I of course deleted their e-mails without a second glance, but I wondered why people do that? Do these people really get jobs that way? Why on earth would you expect me to hire somebody that can’t even follow the simple directions in the job application?! I can only imagine how badly they would do if I asked them to program something reasonably complex (literally – I have no idea how they program because they didn’t send me any code…)

However I was happy to receive a healthy number of job applications that did answer the questions and provided a C# program to count lines of code. Some of the solutions were simple console applications, while others were multi-threaded Windows Forms applications that were hundreds of lines of code (I know of course because I ran the program against its own source code).

I had not realized that such a seemingly simple task would be solved by different programmers so dramatically differently, and it was really interesting looking at everybody’s code and the different ways they solved the problem. I think you can learn a lot about a program from a small sample of their work (which is of course why I had asked them to write some code). Thank you to everybody that provided a response and I really am keeping you on a short list when I hire next time.

My code-counting solution

Before I posted the job, I wanted to ensure that I wasn’t asking anything that I couldn’t do myself in just a few lines of code; so here is my LINQ solution in only 20 lines of (non-blank) code:

using System;
using
System.IO;
using System.Linq;

namespace
CodeCount {

/// <summary>
/// A simple program that counts all the lines of C# code in the
/// current directory and all sub directories.
/// </summary>

public class Program {

public static void Main(string[] args) {

var cwd = Environment.CurrentDirectory;

int lineCount = (from fileName in Directory.GetFiles(cwd, “*.cs”,

SearchOption.AllDirectories)
where
!fileName.EndsWith(“AssemblyInfo.cs”)

from
line in File.ReadAllLines(fileName)

where
line.Trim().Length > 1

select
line).Count();

Console.WriteLine(“Number of non-blank lines of C# code:” + lineCount );

}

}//class

}//namespace

I took the liberty of also excluding the AssemblyInfo.cs file, which most programmers usually don’t even modify and so do not really reflect on the size of the application (although it doesn’t add much either).

What I love about LINQ is that it’s possible to accomplish a lot of functionality in very few lines of succinct but highly readable code. I think I could provide the above code to another programmer who could easily modify it to meet additional requirements (perhaps excluding C# line comments (lines starting with // and ///)).

To see how this performed I added a Stopwatch around the line counting code to see how well it was performing:


var timer = Stopwatch.StartNew();

var cwd = Environment.CurrentDirectory;

int lineCount = …

timer.Stop();

Console
.WriteLine(“Counted in “ + timer.ElapsedMilliseconds + “ms”);

On my reasonably powerful developer-desktop this program took 572ms to count »135,000 loc, which is pretty slick (although completely without any baseline, but it’s fast enough that I went “Ohhhh… Ahhh…” which is all I was looking for).

Trick question!

However, my job posting question was actually a trick question! The real answer to my original question #4 – and
the answer that unfortunately nobody gave me – was simply, “Can you please provide more details around exactly what you are looking for?” I would have been very happy to open a dialog with any job applicant about what my “requirements” for the program were. I would hire a developer that asked for clarification over a developer that programmed a multithreaded GUI application in a heartbeat because I’m paying by the hour! As a small business I really can’t afford to be paying somebody $75/hour to build the wrong thing! I had decided ahead of time to respond that a “console application would be fine, and perhaps LINQ would simplify the code” – but nobody asked.

Theorem:

At a very fundamental level: No programmer can possibly know everything about anything! Off the top of my head:

  • Textbooks on just basic coding practices (on things like why multi-exit functions aren’t actually a slippery slope to hell)
  • The subtleness of object-oriented analysis and design
  • A small pile of textbooks around design patterns
  • The .NET framework is an amazing but enormous pile of functionality
  • C# has piles and piles of subtle points (for example, what’s the difference between throw; and throw e; ?)
  • There’s all the complexities and wonderful weirdness of WPF, Silverlight and XAML
  • There’s the huge kettle-of-fish called WCF

There’s simply no way for a developer to know everything (which is also why it takes at least 10 years to get really good). Of course any reasonable manager/boss should know and accept it, expect a constant learning curve, and offer continuous mentoring.

Aside: I remember one time when my family doctor said, “Hold on, I’m going to look-up the best medicine for these particular symptoms” – I was both delighted and relieved, and then awestruck when he pulled down a textbook the size of three thick design-pattern books with font ¼ the size and started flipping through it. Why isn’t every doctor doing this? Are they really pretending to have memorized ever possible medicine out there and all of its side-effects and interactions with other medicine? What are they prescribing anyway?! Sure there are the classic standbys, but in more than decades of going to doctors this has only happened once…

The main corollary to the theorem “You can’t possibly know everything” is that “You need to be good at looking things up”. That’s why I asked the questions in the job application and specifically stated that of “course you are welcome to use the internet to help answer these questions”. I wanted to know how good people were at looking things up and summarizing and (maybe even) understanding what they found.

Robert

BTW, the individual to whom I offered the job included this comment with his code: “I wasn’t sure how fancy or complicated this program should be, but in the end, simple usually trumps gold-plating.” I thought that was pretty wise.

Design Patterns 2 – The Enterprise version

Back in May I suggested that ever developer should read the “Gang of Four’s” (or GoF if you’re trying to be really cool and pick up girls) “Design Pattern’s: Elements of reusable object oriented software”. While this is a great book, it was written before enterprise databases and database-access were ubiquitous and before XML was even invented or SOA was the buzzword of the year (hell, it was written before the .NET boom/bust, which was like a long time ago ;-); which is to say, that the patterns presented in GoF area really great and really important but they’re only the beginning…

The book that takes your “Design Pattern Toolbox”™ ;-) to the next level is Patterns of Enterprise Application Architecture” by Martin Fowler.

Like the GoF book, this one opens with a collection of very well written narratives covering:

  • Application layering (wonderful stuff)
  • Organizing domain logic (key information you need to know)
  • Mapping to relational databases (very good stuff)
  • Web presentation and session state
  • Concurrency (pretty rare back in the ’90’s but now ubiquitous with multi-core processors)
  • Distribution strategies
  • And a final “Putting it all together” chapter

Section 2 of the book then contains all the design patterns. I suggest you follow my previous advice on reading a design pattern book but not abusing your new-found power knowledge.

Some of the patterns I have used most are:

Robert

PS. If you’re actually trying to pick up girls, using “GoF” will only help you pick up really geeky girls…

Problems and Solutions with Model-View-ViewModel

My MSDN article on the MVVM design pattern is finally available!
http://msdn.microsoft.com/en-us/magazine/ff798279.aspx

Unfortunately, Figure 1 is not correct;  we’re working on getting that fixed in the article. In the meantime here’s a corrected version:

  • The WPF Utilities component should not depend on any unit tests
  • The unit test components should not depend on any other unit testing component
  • The domain model should NOT depend on the data access layer.  Instead, the data access layer should depend on the domain model.  The domain model is the core of everything.  Acthieving this is not easy, and I’ll post about how to achieve it.

Let me know what you think of the article!

Robert

Mea Culpa

This is a great quote:

…what really matters in programming … is realizing that the complexity of software dwarfs even the most brilliant human; that cleverness cannot win. The only weapons we have are simplicity and convention. Tattoo that on your forehead in reverse so that you always see it reflected in the screen

Coding without a license 2: Getting your license

There’s a very interesting discussion on stack overflow right now about learning how to program:  http://stackoverflow.com/questions/2823571/im-graduating-with-a-computer-science-degree-but-i-dont-feel-like-i-know-how-to

Beautiful, elegant, and smart too.Yesterday, my pair-programming partner mentioned that he thinks code should be art.  A few weeks ago, another programmer said she wanted to write beautiful code.  These are awesome goals, and I it made me happy that they even realized these are laudable goals; code, application design, and a running program can (and usually should) be beautiful and elegant.

So, I’m going to start a series of posts all about beautiful coding, elegant designs, and creating wonderful applications.

The advice on the above stack overflow discussion is very good, and I recommend reading it.   A related post is Joel’ Spolsky’s excellent “The Perils of Java Schools”.

Certainly there’s nothing better for learning about how a computer works internally than programming 2D or 3D graphics routines in assembler and linking that to your hybrid C/C++ program managing the rest of your game.  If you’re using a C++ object oriented approach for the elements of your game (weapons, characters, land tiles, whatever) then you can start to get a sense of good object oriented design.

However, my understanding is that very few game programmers are doing things in assembler these days – DirectX with C/C++ is blazingly fast, and DirectX with .NET is usually fast enough and is much nicer to program in with its automatic memory management and the extensive functionality of the .NET framework.

At the heart of becoming a great programmer is – not surprisingly – a desire to become a great programmer!  You have to want to write beautiful code using elegant designs to produce wonderful applications.  You have to want to write code that you can be proud of, even years later.

It’s going to take at least 10 years.  That’s not 10 years working in a big corporation where 50% of your time is writing TPS Reports, 20% is in meetings, 10% is office gossip, and 10% ;-) is maybe spent fixing somebody else’s mess with the cacophony of 5 simultaneous conversations about TPS Reports rage in the cubicles around you.

3167591319_1b163496d9[1]

To really learn to program you need to work on things you’re passionate about – a small personal project, or better yet a large personal project.  There’s nothing better than fixing bugs in your own code 2 years later while cursing the idiot that wrote the code for not using a better design and writing some useful documentation.

image My own project was a 75,000 line artificial intelligence natural language application written in C++ (and later migrated to C#) that I started shortly after graduating university.  It was really hard and I made a lot of mistakes.  I fixed them.  I made more mistakes, and cursed myself for repeating some mistakes, and then I fixed them.  Over 3 years I worked on this project a lot; I learned a lot.

Similarly, back in high school and university I programmed games.  I made a lot of mistakes there too, and I learned a lot.  A few years ago somebody said to me, “I wish I had your knowledge of computers”.  I replied, “It’s easy, just devote years of your life to programming something you’re passionate about.”  He didn’t seem interested, and fair enough, but that’s why I can charge a lot for my consulting time.

Of course I still make mistakes, although it’s a lot less now than I used to, and usually I make new mistakes.

I studied math at university, and the amazing thing about studying math is that you’re usually being taught things first discovered hundreds or even thousand of years ago; Newton published Principia Mathematica over 300 years ago!   Computer science and object oriented programming are really only about 50 years old (and yes, I’m not talking about the difference engine), so it’s only natural that as a discipline we’re all still learning.  Which, really, is great because it’s a lot of fun.

Coding without a license – ubiquitous method parameters

I saw some very poor code today, and amazingly it was written by a programmer of 10+ years.  The programmer had updated an existing class by adding a new parameter – exactly the same parameter – to each and every method of the class.  In fact, the object couldn’t work properly without this information.  Here’s my Java pseudo-code version of the updated code:

public class Before {
    public Before() {...}
    public void SomeMethod(int x, int y) {...}
    public void AnotherMethod(int x, float y) {...}
    public void AThirdMethod(int x, String a, String b) {...}
    public void YetSomeOtherMethod(int x ) {...}
}

He had also deprecated all the previously existing methods, figuring I guess that he could simply force all users of this highly shared component to update all their code.

I politely pointed out that if the data was always required, perhaps it would be better to require the data in a constructor.  Here’s  my Java version of the same change:

public class After {
    public After(int x) {
        this.x = x;
    }

    public void SomeMethod(int y) {...}
    public void AnotherMethod(float y) {...}
    public void AThirdMethod(String a, String b) {...}
    public void YetSomeOtherMethod() {...}

    // A new immutable variable, which completely
    // eliminates the pervasive x parameter
    private final int x;
}


This has a number of benefits:

  1. It simplifies the method signature of every method in the class
  2. It eliminates the need to check the parameter’s validity in every method. Instead, the parameter can be checked once by the constructor.
  3. It allows the variable to be frozen to avoid accidental tampering – in this case using Java’s “final”, but this can also be done in C#’s using “readonly”, or in VB.NET using “ReadOnly”.
  4. There is no need to deprecate all of the existing methods
  5. It may be possible to leave previous constructors in place and assume a reasonable default, or even use the C++/C#4/VB.NET feature of default parameter values to reduce rework (although this requires a re-compile).

In this case, the change was even more egregious because the class was actually implementing an interface, and the programmer had updated the interface.  Updating the interface required all implementations of the interface to pass in the “x” parameter – but “x” was an implementation detail!  So the other implementations didn’t need anything to do with “x” whatsoever!  (“x” wasn’t an integer in the real code).  Instead, using the constructor approach above, any consumer of the interface remains unchanged, and other implementations that do not rely on “x” also remain unchanged, so the impact to the API and the many, many applications that depend on the API is much less.

Think before you code, and document as you go.

Paradigm shift

For a few years I was both a Java and a .NET expert – I was even got certified in Java and got something like 98% on my test.  I made most of my consulting money off Java and its complexities – especially around the early versions of EJB and any IBM software; unfortunately I’ve had to let the Java expertise slide a fair bit to get really good with .NET.  Learning LINQ, WPF, and all the amazing new stuff in .NET 4 including the BCL improvements, language improvements, dynamic programming,  and Parallel programming with .NET 4, takes a lot of time, and with a social life that I don’t want to die completely, and three wonderful children and my beautiful/wonderful wife something had to give.

Back around 2005’s I decided to start really focusing on .NET because Microsoft really seems to care about making developers as productive as possible – every new release makes programming even easier and faster.  This makes sense, because they care deeply about having developers build great products that run on their platforms.

While Java lets me run “anywhere”, the Java platform folks just don’t seem to care about my productivity anywhere near as much as the folks over at Microsoft.  (Nor does Java have anything near as cool as WPF for building amazing applications.)  It will be interesting to see how Java evolves now that Oracle owns Java (what the hell was IBM thinking?!) and James Gosling has left the company.  Interestingly, Microsoft often lags behind Java in adding new features, and it seems to me that the Microsoft folks learn a lot from Java’s exploration of new ideas.  However Microsoft also adds lots of new stuff such as LINQ, WPF, and now the DLR.

I’ve also glanced at Ruby and Python a few times and lots of people seem to love them and I’m sure they’ are very cool languages, but I just don’t have time to become very proficient, and they don’t seem like enterprise/commercial software languages (certainly I have never seen a consulting job with Python).  An amazing graphics designer I know tells me that ActiveState’s Komodo is an amazing IDE, but I just don’t have the time anymore to pick up a new IDE, new language and a new platform.

As for JavaScript/JQuery/HTML/CSS I would love to learn these, but it takes 10 years to become a master of something, and – you guessed it – unfortunately I just don’t have the time.  These technologies – more than any other I think – are changing very rapidly, especially with the introduction of new browsers and HTML 5.  Additionally, there are lots of web designers with fine arts degrees that can draw circles around me with Photoshop and makes things look much better than my “command line” like view, so I’m happy to hire them to make things look good visually – I’ll focus on making elegant code and building applications that add business value.

So when a friend was telling me today that he’s trying to learn all these different technologies it gave me pause for thought.  For me personally, I’m not happy being a jack-of-all-trades; I want to be a master of at least platform, because that means I build applications quickly and elegantly that help solve a business or personal problem.  And being a master in just one platform still requires being a master of OOAD, design patterns, unit testing, debugging techniques and general problem solving, deployment techniques, database design, etc.  And off course these additional skills are usually easily transferable or “leveragable” if a paradigm shift to a different platform is required or desired.

So I responded to my friend that the language he chooses to become really proficient in largely depends on his goals. It seems to me that if you want to build a cool new open source technology that you tinker with in your spare time then Ruby or Python using Komodo are your best choice. If you want to be a web developer then be a great web developer and master Photoshop while you’re at it. If you want to build serious commercial applications then learn .NET.  (My friend is proud-to-be-cheap, so I directed him here: http://www.microsoft.com/Express/.)  And if you want to build applications that can even run on your toaster, learn Java, but be prepared to write a lot of code.

Update:

This was referenced by the morning Code Project e-mail:  http://iamgabeaudick.tumblr.com/post/576987756/which-language

Design Patterns

Amazingly, there are still many developers out there that have never read Design Patterns Elements of Reusable Object-Oriented Software:

image

This book was the start of the design patterns revolution, and if you haven’t read it yet and you are serious about writing software, you should stop reading your Star Trek fan fiction and instead rush out to buy this book and read it.  But, with two caveats:

  1. Do not read it cover-to-cover – it’s just too dry and you’ll find yourself consuming large amounts of liquids (H2O or C2H5OH) just to get through it.   I mean seriously, I’m a pretty hard-core geek and I still didn’t want to read this book cover-to-cover.  Instead, I read the introductory chapters in their entirety because they were interesting, and then I just read the first page and a half of each “pattern chapter”; this approach gives a nice overview of the available patterns.  Then, when you’re working on a problem and get that nagging “I’ve seen this before” feeling, you can flip through the book, find the relevant pattern and read the now suddenly interesting chapter in its entirety, solve your problem 10 times faster and more elegantly than you would have otherwise, and THEN you can go out and sip your liquid of choice with your many happy friends on a sunny patio.
  2. Do NOT read this book and then attempt to apply every pattern to your code in the next month.  Seriously.  This book is full of awesome ideas, many of which I have used many times, and some of which I still haven’t needed to apply.  This book provides you with a toolbox of great solutions to apply to very specific problems.  Don’t go looking for problems that need a solution.  I knew a guy that read this book, and then applied one pattern to his code every day for the next month, whether the pattern was relevant or not.  It made his code really, really bad.  Please don’t do this.  If you do, people will think your code stinks, and then probably think that you stink, and then not even the ugly girls (or boys, whatever you’re interested in) will want to dance with you at the next company party, and pretty soon you’ll find yourself all alone because everybody moved to a new corporate headquarters and forgot to mention it to you – all because you decided to apply these design patterns where they weren’t appropriate.
  3. Go to #2.  Then go study up on infinite loops.
Follow

Get every new post delivered to your Inbox.