Tag Archives: software

Why Won’t Internet Explorer Change the Appearance of an HTML Element I Changed via JavaScript

A very common technique in modern web applications is to dynamically change the appearance and/or behavior of an HTML page element via JavaScript. Often, this is done by modifying the style property of the object to apply different CSS rules to the element or by changing the layout and dimension properties inline.

The Problem

While building an application like this, you’ll likely quickly discover that Internet Explorer (at least the ~version 8 variety) doesn’t apply some of these changes when you expect, and often need, it to. The change will either appear to be applied at some random point significantly after the change to the style is made or appear to never be applied at all.

The Apparent Cause

What’s actually happening appears to be a performance optimization in these older versions of IE. It appears that the browser makes the explicit choice to defer some style changes for as long as possible. From what I can tell, the browser assumes that the layout of the page should stay largely static until something that would significantly impact the layout happens such as resizing the window.

At least that’s what appears to be happening. I don’t know specifically what decisions were or weren’t made by the development team. But I find that viewing the problem in the way I describe above helpful in understanding what is happening and how to work around the behavior.

How to Cope with the Issue

A solution to this issue is to “nudge” IE into applying the styling changes when you want. The way to do this is to reference a property in the element’s style property that IE believes it requires styling changes be applied to properly calculate. Referencing the offsetHeight property seems to work rather well in most cases.

var nudgeByReading = elem.offsetHeight;

Simply reading the property may be enough to trigger a re-layout.  However, simply reading the property often isn’t enough.  Frequently, you’ll first have to change the property and then reference it to force the re-layout.

To force a redraw regardless of style changes, you can write a method that makes an innocuous change to the style, read the property, and then reverse the “fake” style change, like so:

var savedDisplayStyle = elem.style.display || ”;

elem.style.display = ‘none’;
var nudgeByReading = elem.offsetHeight;

elem.style.display = savedDisplayStyle;
nudgeByReading = elem.offsetHeight;

To be safe, you may want to consider universally reading and writing to the property to force the recalculation just in case simply reading from the property doesn’t force the redraw.

Some Notes on Applying the Technique

One thing to remember when using this technique is that changing the layout of a parent element will force a layout calculation of each of the parent’s child elements. So, if changes are made to multiple elements that have a common parent, forcing a redraw of the parent will cause a redraw of each child.

Doing this may result in cleaner, more resilient code. But do keep in mind that forcing a redraw at a point too high in the DOM hierarchy (such as the “body” tag for example), will cause most or all of the page to redraw which may cause performance problems. As a rule, it’s a good idea to redraw as few elements on the page as possible.

How to Convert a String Representing a Unicode Character Sequence to the Unicode Character

I recently received some translated resource files from the Translations team at work.  To my surprise, all of the files, even those for double-byte languages, were returned in ASCII encoded files.  After some inquiry, I found out that because of the technical limitations of a proven legacy system, all translation files were encoded as ASCII.  What this meant is that I was confronted with a set of ASCII text files containing Unicode escape sequences (\uxxxx) that I was responsible for converting to a proper Unicode encoding.

While solving the problem, I came across a couple solutions for converting Unicode escape sequences to a different encoding.  The first was to use the StringEscapeUtils class in Apache Commons Lang.

String lineOfUnicodeText = StringEscapeUtils.unescapeJava(lineOfASCIIText);

Using the StringEscapeUtils class is very straightforward; simply read the contents of the the ASCII file line-by-line, feed the line of data in to the unescapeJava method, and write the unescaped text to a properly-encoded new file.  But this technique requires writing a utility program to feed the contents of the ASCII files into the StringEscapeUtils methods and then write the transformed string to a new file.  Not hard to do, but much more work than ideal.

The second solution is to use the native2ascii utility included with the Java JDK.  The utility can take the input file and perform effectively the same unescape transformation that Apache Commons does.

native2ascii -encoding utf8 c:\source.txt c:\output.txt

A very simple solution that works as advertised.  No quirks or caveats that I’ve noticed.  There’s even an ANT task for incorporating native2ascii into build scripts.

Setting a Custom User Agent in Objective-C

Sadly, it is a common scenario in web development to have code that handles specific browsers, or classes of browsers, differently.  The practice largely has it’s roots in the “bad-old-days” of having to handle the many various quirks and idiosyncrasies in the different CSS and layout engines of the major browser vendors.  Thankfully, this problem is getting, largely, better (at least in my experience), and the need to write browser-specific code of this type is becoming less of an issue.

But handling layout differences across browsers isn’t the only reason to treat different clients uniquely.  Dropbox’s matching of the sort order paradigms of either Windows or Mac depending on which OS the site is being viewed on is a practical example of when functional differentiation is desired for different clients.

Dropbox on Mac

Dropbox on Mac

Dropbox on Windows

Dropbox on Windows

These techniques are nearly always implemented by inspecting the user agent string provided in the headers of each request the server receives.  Each browser provides a user agent header that describes the type, version, OS, and other relevant details about the client sending the request.  For a web application, the client application is the web browser, so you don’t need to worry about specifying one, the browser provides it. You only need to worry about consuming it if necessary.

But what about hybrid native applications where mobile content is running within a web browser control (such as UIWebView in iOS) within a native application.  By default, the web browser control typically sends a subset of the user agent string the full-browser version would send.  But what if you want your server code to recognize when your native application is submitting requests?  How can you specify details about the native application in the user agent string if you need the backend application to behave differently for these hybrid clients?

In the iOS SDK, the answer is to modify the UIWebView’s user agent string for your application.  This is easily done by:

– (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString *existingUserAgent = [[[UIWebView alloc] init] stringByEvaluatingJavaScriptFromString:@”navigator.userAgent”];

NSString *newUserAgent = [NSString stringWithFormat:@”%@ custom-information-about-my-application”, existingUserAgent];
NSDictionary *userDefaults = [[NSDictionary alloc] initWithObjectsAndKeys:newUserAgent, @”UserAgent”, nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaults];

/* … your application code … */

}

The essence of the above code is that the existing UIWebView user agent is retrieved from a UIWebView instance (it doesn’t need to be the instance that will actually display the content), the custom user agent information is appended to the original user agent, and then the new user agent is registered to the user defaults of the application under the key UserAgent.  This will set the user agent sent for all network requests sent from your application’s code, including raw NSConnection requests.*

In my experience, you should always augment the existing user agent rather than completely replace it as the server will likely make some assumptions about whether you are a supported client and what flavor of display code to deliver based on the web view control’s existing agent string.  This is especially true in large applications where you don’t own every aspect of the server code.

* NOTE:  Things can get a little weird for requests issued from a linked library (like making an API call such as stringWithContentsOfFile).  Therefore, it is dangerous to assume that EVERY server connection issued by your application will carry the custom user agent. Your milage may vary, so verify that the custom agent is being applied uniformly for all calls and adjust how the agent is registered if needed.

Fun with Simulators and VMs – Can’t Delete an Application from the iOS Simulator

For the most part, Apple’s simulator environment for iOS (both the iPad and iPhone), does a pretty good job.  There are mountains of odd “simulator-only” bugs and some obvious features are simply not implemented (three-finger+ gesture emulation anyone?).  However, as anyone who has worked with device emulators other than iOS’s can likely attest, Apple’s offering more than holds its own in terms of features and usability.

That said, the quirks and bugs can drive you mad.  The latest one I’ve noticed is that I am no longer able to uninstall an application from the simulator using the iOS “uninstall” feature (i.e. tap and hold the application’s icon until it starts to shake, then press the ‘X’ in the corner to remove the application).

This isn’t a big thing as re-running from the simulator will reliably (in my experience) replace the existing binary on the simulator.  However, there are times when I want to completely remove the application to remove things like the Settings bundle or resource and data files stored in the bundle directory of the application on the simulator.  The easiest way to do this had been to uninstall the application via iOS itself.

However, in the 6.0 or 6.1 SDK (I’m not sure when I first noticed, and I’m not motivated enough to track down the specific release the bug was introduced), the “uninstall” feature stopped working.  Tap and hold will still cause the icons to shake and the ‘X’ to appear, but pressing the ‘X’ causes the simulator to lock up.

The work around to this is simple.  You can just delete the application bundle directory from the simulator’s install directory on your hard drive.

Open the terminal and cd to:

cd “~/Library/Application Support/iPhone Simulator/6.1/Applications/”

Change the “6.1” in the above path to the version number of the simulator where the application you want to remove is installed.  If you issue an ls command in this directory, you’ll see a list of directories with GUIDs for names.  Each directory represents an application deployed to the simulator.  Find the directory for the application you want to remove and delete the directory

rm -r <GUID>

Nothing complicated, and for people comfortable with the terminal at least, an easy method for clearing a deployed application from the simulator.

Resetting the Undo/Redo Stack after Applying an Undo/Redo Action in iOS

If you are developing iOS applications and are not using NSUndoManager, you should be.  The class provides a very solid implementation for enabling undo/redo functionality within an iOS application.

However, when I first wired the class into a project, I quickly noticed that changing a value after navigating backward into the undo stack did not clear the now-downstream, previously-applied undo stack operations.  Which is to say, if I undid an edit and then changed the value of the “undone” field, I could redo to the value prior to the undo.  Which, much like that last sentence, is very confusing and hard to follow.

Most undo/redo implementations assume that applying a change after navigating backwards in the undo stack should invalidate the forward operations within the stack.  So while I was surprised that wasn’t happening right out of the box with NSUndoManager, I assumed it was capable of the behavior (i.e. I must be doing something wrong).

And I was correct.  Straight out of the box, NSUndoManager assumes that all undo operations are non-discardable, which is to say, it will preserve them even when the state of the class hints that the operation may no longer be valid.  To enable the functionality of having the traversed undo operations removed from the redo stack once a modification is made to the “undone” data value, I simply had to indicate that the applied undo operations should be treated as “discardable“.

A very straightforward, and possibly overly-aggressive, way of doing this would be to subclass the NSUndoManager and override prepareWithInvocationTarget as so:

– (id) prepareWithInvocationTarget:(id)target
{
// This ensures that the redo stack is reset if the user
// edits a field after moving back in the undo stack.
[self setActionIsDiscardable:true];
return [super prepareWithInvocationTarget:target];
}

As is often the case with software development, your project likely has some characteristics that are very specific to your application, so the above code likely is not be a perfect fit to your problem. However, if you’re looking for a way to reset the redo stack of NSUndoManager, the above code should provide some guidance on how to develop a solution that fits your needs.

Extension Cords

The Power and the Pain of Plugin Development, Part 3

Previously, we looked at why a client-side plugin architecture might be a good idea and why it might not be.  Now, let’s formalize our recommendations.

Some Final Thoughts on When You Should and Shouldn’t

Now that we’ve discussed some of the benefits and pitfalls of taking on plugin development, hopefully you have a better feel for when leveraging a plugin is appropriate for your project. However, there is an additional aspect that I factor into my evaluation:

  • perceived appropriateness for the platform

Basically, this factor is meant to gauge both how frustrated your users will find the idea of a plugin and how friendly the general developer community is to the idea of plugins for the platform category to which your host application is perceived to belong.

This is how I break down platform categories as they apply to this particular question:

  • desktop software built on the idea of plugins
  • desktop software that has a plugin API, but isn’t plugin-oriented at it’s core
  • web browsers

Desktop and Based on Plugin as the Core

Software of this variety tends to be complicated, valuable, and used for sophisticated work. The most well known examples are Adobe Creative Suite and Eclipse. Less prominent members of this class are smaller, albeit popular, applications such as Emacs and command shells on various platforms. The products are built in such a way that core product development is often done as plugins. In these ecosystems, plugins are not just encouraged, they are expected.

For disciplines such as media design and software programming, these nuanced products tend to have highly technical users asking for a solution to very specific problems. In environments such as this, plugins tend to flourish. If this is where you’re project is targeting, you should have few concerns about the appropriateness of using a plugin as the delivery channel.

Desktop with an API but without Primary Orientation

This is, more often than not, the Microsoft Office case. While there are other products that fit this category, Office is the prominent player. Typically, there is a very polished extension API and even a large and committed community around extending the products. But unlike the more technically-oriented applications mentioned above, the technical fluency of this class of software’s users can vary widely.

Plugins can be successful and popular here. The appeal of having software do new and cool things is a universal draw. You don’t have to be a geek to love a new feature.

However, because the broader audience tends to be less tech-savvy, UI, delivery, and support decisions typically need to be more conservative. In general, you want to make sure your design and marketing message are closely aligned with the attitudes of the people likely to install the plugin.

Because the user of these applications tends to be less technically-oriented, the place of plugins in the ecosystem tends to take more of a secondary role. Your plugin would need to become phenomenally popular to give it comparable clout with the internal Strategy and Architecture teams at the host application. On these platforms, you must be prepared, and frankly expect, to rewrite the plugin often and abruptly in these ecosystems.

Web Browsers

Early in my career, I tended to think of web browsers in the same class as the “Desktop with an API but Nothing More” camp. The browser was an extremely widely-used desktop application with a good extension API. However, over the course of time, I’ve significantly revised that assessment. Browsers are in a class of their own.

Because browsers tend to lag only operating systems in terms of usage, browser plugins come up very often on product roadmap wish lists. However, the size of the audience is almost always more of a curse than a blessing.

One of the most resonant messages uttered by advocates of the “pure web” movement has been that things on the web should be free and that they should be universally available. I have been shocked often at how articulately non-technical users can attack any bit of software that doesn’t fit the free and universally available model of the pure-browser-delivered web. Even if your plugin is free, it will run afoul of the “universally available” purists if it doesn’t seamlessly run on every platform without any user interation.  Just ask Adobe.

Personally, I think this frustration often boils down to the fact that most people don’t care about technology, only the things technology can do for them. So any point of view that affirms those two notions is innately appealing.

Because of that, most of that uber huge audience of browser users tends to be:

  • annoyed that they should have to install anything for any !@@#-ing reason
  • skeptical that anything they are asked to download and install is actually free or safe

Installing software can be a pain, especially on a system like Windows that often insists the user close an application or reboot the machine to complete an install. Users expect access to a site’s information or functionality to be available as soon as the page loads.  Anything that gets in the way of that is an annoyance, plugins especially.

In general, I’ve found web browsers are an unforgiving platform for plugin development. Expectations for cross-browser support and the ability to override or circumvent security mechanisms tend to run pretty high. Because the zero-friction, potentially cross-platform delivery channel of HTML is available literally right in the same application, the question of ‘why aren’t we doing this as a web application?” essentially never goes away with web browser plugins. Because of this, in my opinion, browser plugins should be avoided.

Conclusion

That’s my take on plugin development.  Hopefully the information will help you in determining whether a plugin is the right choice for a software project.  Like I said above, this series is based on my experiences in building plugins and not intended as gospel truth.  Like all things in software, your mileage may vary.

Extension Cords

The Power and the Pain of Plugin Development, Part 2

Last week, we looked at why you might consider plugins.  Now let’s look at why you might not.

This Sounds Awesome! Why isn’t Everything a Plugin?

Although plugins are powerful, can save you time, and can help in user adoption, they are not free of drawbacks that must be considered.

A quick list of potential pitfalls that you should consider when developing a plugin are:

  • technical restrictions placed on plugins by the host application
  • how to play nicely within a UI you don’t fully own
  • licensing requirements that may be imposed on your plugin
  • how hard will it be to find and install the plugin
  • where does “help desk”-style support for your plugin end and for the host application begin
  • Lashing yourself to a “narrow” platform

This is far from an exhaustive list, but covers most of the challenges I’ve encountered. Your circumstances likely will govern just how complete this list feels.

Technical Restrictions

It’s tempting to believe that because plugins are typically written in “native” code that developing a plugin will provide the same degree of freedom that developing a stand-alone application does. More often than not, this isn’t the case. Even if the host application allows your plugin to execute in an effectively unrestricted manner, your ability to control and interact with the host application in a sanctioned way is still constrained by the host’s plugin API.

Even more importantly, just because you technically can do something, doesn’t mean that you should do it. Your plugin is a guest in someone else’s house, so it is typically a good idea to act on your best behavior. A healthy amount of respect for the plugin’s operating environment will go a long way toward preventing future maintenance and compatibility headaches as your plugin and the host application grow old together.

How to Play Nicely in a UI You Don’t Fully Own

Continuing with the notion of respect for the operating environment, more often than not, a plugin should visually and functionally fit within the host application. The visual appearance of menus, dialogs, buttons, etc… should all take their queues from the host application. The same thing applies to more functional notions such as the concepts of navigation and initiating actions. If the host application tends to use buttons to initiate an action, then the plugin most likely shouldn’t use text links as the primary mechanism for initiating actions.

Like most things of a design nature, this particular advice is a bit subjective. If you have a good thought on differentiation through the look and feel of the UI, have a thorough appreciation for how a drastically different appearance may be perceived by the end user, and you still feel strongly that you should implement a custom look for your plugin, then the last thing I want to do is advise you not to do so. Just go into such decisions with honest conviction. If you are on-the-fence or ambivalent at all about making that kind of design decision, you probably shouldn’t. If you’re confident you understand what you’re doing and that it’s the right thing to do, then with all sincerity, Godspeed.

A related aspect to general look and feel is that the UI shouldn’t strive to dominate the host application. In my experience, a Development team usually looks at this position as “not a big deal.” However, once you involve teams like Strategy and Marketing, their first impulse likely will be to make their product as apparent and prominent as possible.

It is a natural impulse and, realistically, the “right” position for those teams to take, but it’s also a move almost guaranteed to backfire if you are too aggressive about it while running within the context of another application. I assure you, that if a user installs your plugin and then sees it within the host application as a 600px wide sidebar that they cannot resize and are presented with a nagging dialog asking essentially “why no love?” when the user tries to close said sidebar, your user (also known as the customer) will hate you. They may leave that sidebar open forever. They may even use it’s unbelievably awesome feature from time to time. But she or he will always hate you. And they will never voluntarily do anything for you again.

The essence of this guideline is that by agreeing to be part of a larger application, you are implicitly seeding some degree of design control to the host application. If you think Outlook is a usability disaster and a primary element of the value proposition of your plugin is world-class user experience, then you may want to rethink whether an Outlook plugin is the right delivery channel for your application.

Licensing Requirements and Impositions

A review of source code licensing will likely take a big role in the later stages of your project. It will likely manifest as a big checklist from the legal department asking what open source projects have been used; for copies of every third-party header included in the project; for assurance that the proper license disclosure is in all source files, etc… The need to cross ‘t’s and dot ‘i’s regarding how source is licensed and used is a big concern of any company of reasonable size.

And if you’re delivering a plugin, the chances are really good that you’re going to have additional questions to answer than you would if you were delivering a stand-alone product. At a minimum, you should be familiar with any licensing requirements imposed by use of the host application’s plugin SDK and get sign off on its use from your company’s legal team and senior management before you start the project. I’m not a lawyer, so don’t treat this as legal advice because it’s not, nor does it intend or claim to be in any way. But you still should.

How Hard Will It Be to Find and Install the Plugin

This one usually isn’t a deal breaker for plugin projects and is generally a common concern for any software product, but people tend to overlook this regarding plugins until late in the development cycle for some reason. When designing the product, think through how a user will both find the plugin and how they will install it.

If the host application has a site or integrated install/update feature that the user can search to find the plugin, then that’s a good sign. Figure out what you need to do to be placed prominently in that ecosystem. If the user can install the plugin directly from the host application without requiring a restart of the application, regardless of where they get it, even better.

If the user has to go to your company’s website, download a TAR file, go to a different website to download WinRAR just to unpack the TAR, unpack it, run a command script with admin privileges, and then reboot the computer, all just to install your plugin, then you’ll likely face some adoption issues regardless of who your target user is.

What Does Support Mean for Your Plugin

Regardless of how clearly branded your plugin is and how distinct the host application makes plugin UI from the base UI, to an end user, your plugin is part of the host application and the end user typically has no notion of where the host application’s bits end and your plugin’s bits begin.

While this can be a goal to aspire to regarding the user experience, it can lead to headaches for your support organization. Your team will need to think through what is and isn’t a question that your support organization should field. Realistically, you should also prepare resources that can be referenced, even informally, so that Support can at least steer people in the proper direction if it’s appropriate to do so.

Additionally, your plugin becomes colored by the perceived stability of the host application. If the host application crashes all of the time, especially if your plugin looks like it’s doing something when the host does crash, your plugin becomes a candidate for blame whether it was actually at fault or not. There’s little you can do to categorically prevent this beyond ensuring high quality in your plugin and possible messaging on a social media channel. You’ll need a thick skin and fully invested management to weather a plugin quality critique whether or not your plugin is the root cause of the problem. I strongly encourage ensuring you have both before setting a plugin loose into the wild.

Lashing Yourself to a “Narrow” Platform

This particular constraint can be an interesting one and related push back is typically fueled by the background and general work outlook of the organization. Many developers loath the idea of building for a single platform. Most companies do as well, albeit often for different reasons.

While the vast majority of widely-used software has established some notion of multi-platform support, two of the most widely targeted plugin platforms, Internet Explorer and Outlook, historically have been decisively single-platform, and in IE’s case, still so in a largely concrete way.

You must make sure that you have a good answer to the question of multi-platform support. If the majority of your customers are on a single platform, then targeting the plugin for that platform while providing comparable functionality in a less-targeted manner for your secondary platforms will likely be not just regarded as a good solution, but a great one. But you need to think through how that will look early in design.

Next week, we’ll look at some special considerations regarding plugin development and formalize recommendations for when you should and shouldn’t use plugins.

 

Extension Cords

The Power and the Pain of Plugin Development

Call me strange, but I really enjoy client-centric plugin development. I think plugins are a powerful extension model for large software products, especial those of the pre-packaged, commercial-off-the-shelf variety such as MS Office. In a geek sense, plugins are awesome.  However, over the years, I’ve grown skeptical of projects where the assumed solution is a plugin, or extension or add-on if you prefer.

Plugins can be great, but they’re not right for every situation. I start the product design phase by assuming that a plugin is probably not the right option for the project and plan to implement a plugin only after I’m satisfied it’s the best, and often only, solution for the problem the project is aiming to solve.

Let’s Agree on What We’re Talking About

Before examining what I feel are the pros and cons of plugins, let’s have a brief discussion on terminology. I find the nuances between the categories of plugin, extension, and add-on tend to be highly technology/platform specific while the functional difference between them is more or less insignificant. So I’m choosing to use the term plugin generally to refer to:

a packaged software component that conforms to the public API of a host program, is intended to augment the functionality of the host program, and appears to the end user to be a seamlessly-integrated part of the host program

Additionally, I want to acknowledge that plugin architectures exist for server-side products, and that those solutions share many of the attributes of their client cousins. If anything, server-side plugin development has significantly greater productivity gains because you can eliminate the end-user “technical familiarity” limitations associated with leveraging them. However, this article takes a client-focused perspective.

The Value of Plugins

With that out of the way, let’s continue with what makes plugins great and when you should use them. In my mind, the primary benefits of plugins boil down to these two things:

  • user familiarity with a product
  • integration into a larger functional process flow

User Familiarity with a Product

Building an intuitive application that is easy for anyone to use is hard. Very hard. Whole disciplines have emerged over the last few years where practitioners devote themselves solely to the study and understanding of design-focused topics like user experience and practical implementation techniques such as user-centered design. If you believe your passion as a developer and the raw, untapped value of your application are enough to get people to use it, you’re probably wrong.

Because building an inherently “usable” system is difficult to do, simply encouraging people to engage with your new application can be a challenge. If there is a business-oriented expectation that a new user will need to learn how to use a new product, that product better deliver tremendous value that the user can’t get elsewhere, otherwise that user simply won’t bother investing the time to become fluent with your product.

Plugins can help overcome some of the challenges associated with user adoption by exposing the new functionality as part of an application the user is already familiar with. If a user already knows how to use Outlook and already opens it first thing in the morning, you can gain a tremendous leg up in encouraging user adoption by making your application a part of Outlook.

Integration into a Larger Functional Process Flow

What I mean by integration into a larger functional process flow is that not every feature or function deserves its own application. Some features, even powerful and valuable ones, only make sense in the context of broader functionality.

If your project is intended to provide a mechanism for generating rich graphs and charts from data stored in your CRM system, it doesn’t really make sense to write an entire word processor just to satisfy the “must be easy and intuitive to embed into text documents” requirement. A plugin for Word will likely be a better option for such a requirement.

A more nuanced but less clear-cut example of when this guideline is applicable would be this: if you are developing a programming language, should you write your own IDE or adopt Eclipse with your language supported as a plugin as your development environment?  It’s a complicated question with many non-technical influencing factors.

In practice, I’ve found that evaluating projects on this scale tends to feel less like the glaringly obvious first example and closer to the more nuanced second, where there are likely compelling reasons from the business and product strategy points-of-view to invest in re-implementing functionality that may offset the technical benefit of piggy-backing off of an existing application.  Even when a plugin may be the right technical fit, it may not make sense from a business perspective.

But even in those less-obvious scenarios, engaging in the exercise of thinking through how a new feature could be incorporated into a tool the user already has and loves is a valuable exercise. Intelligently leveraging the work of others is a practical reality in professional software development, so you should at least talk through the possibilities plugin architectures present.

Next week, we’ll look at the reasons why you may want to avoid a plugin architecture and implementation.