Framework as an anti-pattern

Framework is certainly a pattern, but it often becomes an anti-pattern. I’ve heard someone say that this antipattern is inevitable in large systems, but I believe that avoiding it is a matter of keeping two simple rules in mind all the time:

Make interfaces as unrestricted as possible.

Create utilities for working in a certain way rather than requiring the user to work in that way.

As an example, consider an application like Photoshop. How do you design filters, keeping in mind that an image doesn’t necessarily fit in memory? An obvious solution would be this:

class IFilter
{
public:
  ImageBuffer Transform(const ImageBuffer& buf) = 0;
};

(Actually, the output buffer is smaller than the input buffer, and you have to express that somehow, but that’s not the point.) So now you have either a class or a function that uses IFilter to convert a complete image, and all is well.

This works for some time, and then you want to create a geometric morphing filter, and the IFilter design doesn’t suit it. So you create IGeometricTransformation, that converts a Point2d to another Point2d. But then you need to create some new filter that doesn’t work in any of these two ways, and you start twisting the design to accommodate for it. Gradually you get a mess.

The corrected design would be this:

class IFilter
{
public:
  ImageDocument* Transform(const ImageDocument& doc) = 0;
};

class LocalizedFilter : public IFilter
{
public:
  ImageDocument* Transform(const ImageDocument& doc);
private:
  ImageBuffer Transform(const ImageBuffer& buf) = 0;
};

class MorphingFilter : public IFilter
{
public:
  ImageDocument* Transform(const ImageDocument& doc);
private:
  Point2d Transform(const Point2d& pt) = 0;
};

That is, specific partial filter implementations are given as utilities rather than rigid rules, and IFilter is the least restrictive possible interface for a filter.

In the next post I’ll take this simplification one step further.

Advertisements

One Response to “Framework as an anti-pattern”

  1. Boris Says:

    Lev, all is good as long as you *know* when to avoid any step that has a potential to lead you to creating an inner platform or, G-d forbid, a framework. You’re absolutely right that both are anti-patterns way more often than any use can be obtained from them. Question is, how to avoid the eternal sin? Methinks that more often we notice these things in retrospect and engage in refactoring or any other way to clean the mental mess.

    Just an observation, really.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: