(Guest post by Bob Dawson)
Bob has held titles ranging from Armor Officer to Director of Bioinformatics, but he still thinks of himself primarily as a software designer and developer. His interests include world travel, history, narrative theory, and software architecture.
I've had the privilege of working with Bill, and fully appreciate the circumstances that led to this frustration about visual code libraries. Nevertheless, user interface component libraries may be a 'baby and bathwater' issue where cautions for how to survive in the middle of the road are more helpful than making it sound like everyone should stay off the road entirely as too dangerous. Visual component suites do indeed have costs far beyond the initial sticker price. But of course, acquisition cost not being the full story is true of all code. The additional costs and risks must be appreciated and managed.
All that said, I still think there's still a strong case for them, for both intrinsic and extrinsic reasons. First. Bill's quite right in saying that no 3rd party provider is likely to command the depth of testing facilities and user base that an OS vendor enjoys. But to me that's not really the full story; they certainly have more than the end-point development operations they in turn support, whether those are commercial code operations or internal business software developers. So I think that the build-or-buy equation still tips dramatically in the direction of buying, not writing, common interface controls. There's simply no way, as an endpoint shop, that I'd want to compete with the economies of scale, testing base, or degree of focus that a visual component library vendor brings.
Then too, I'd point out that, at least for Windows shops, there isn't really a competitive library actually included in the OS. Historically, Microsoft-supplied visual components haven't just belonged to the OS team, and weren't in-the-box at the OS level. Rather, MSWord and Office promulgated new components with every release for many years—so those Microsoft applications constituted the actual competition and 'effective standard' for 3rd party applications. That's why 3rd party library vendors always tended to advertise the 'Office look and feel' capabilities rather than simply being better than vanilla Windows controls. In the face of that reality, any shop that doesn't use external libs, or doesn't undertake the potentially massive task of writing its own, is starting very much behind user expectations.
That being the case, however, it remains that Bill's right about the potential costs and risks of such external dependencies, so let's list out some guidelines for risk management:
1. Have an official 'formulary' and publish and enforce it. The introduction of new systemic dependencies on the business's technical stack should not be taken lightly, nor without the full knowledge of the entire dev organization. Having dependencies on dozens of one-offs that no one even knows are already available is worse than no library at all, and not getting the entire development community involved in library selection is like producing an application without getting input from the complete user population—because that's what it is. Dependency selection is an organization-wide issue that cannot be delegated out to individual teams.
2. Never buy or even consider libraries without source code. If you can't compile it and test it, it's about as useful (and dangerous) as that app that what-was-his-name wrote back when he worked here in some language that seemed cool at the time. Sourceless code is toxic no matter how it's acquired.
3. For the same reason, component libraries belong in your source code control system and your build cycle (see 2). Compiling it today doesn't mean it will still work on the next version of your language/stack/VM/OS mix etc. Dependencies are intrinsically dangerous—uncontrolled dependencies are much worse.
4. Plan for that extra upgrade cycle delay that Bill mentioned—you can't just move to next OS or tool chain version, you have to wait on the component vendor to move before even considering your own migration.
5. Plan for and assign a support specialist. Just like you wouldn't use a database without wanting someone who can handle the DBA tasks, you don't want to promulgate a visual component library without immediately available expertise. Even vendors who offer on-call technical support often encourage shops to appoint a specific technical contact for support questions, and they're right. Your team ought to have someone who can be the internal help desk for library capabilities, good practices, and limitations. Your library starts dragging on productivity if "don't do X" becomes something that every using developer must to learn individually through bad experience. Lack of a component expert becomes an organizational learning disability.
6. Make component use a specific code review question—is the component really necessary? Is it being used as designed and appropriately?
While the latter question is relatively straightforward--something your internal library advocate/authority should be able to answer--the question of need demands some additional attention. This is not simply a question of YAGNI or user delight, but of basic architecture. Visual components and libraries fundamentally compete on power—but does all that power really belong in the UI? Or rather (in the case of a sortable grid for example) shouldn't your business layer rather present a non-visual technical collection that accepts sorting and filtering plug-ins? In the worst case, drop-in library use can mimic the worst antipatterns of the old RAD, single layer, all-business-logic-in-the-UI approach. Will the business logic ever be migrated across platforms or deployment patterns? Does a crucial piece of business logic get missed because another application uses a different component, or even the same component configured slightly differently? Is business logic buried in some visual component event handler rather than being where it belongs, in the object and operations model?
A "does everything" grid can rapidly become a fatal constraint if, by its very flexibility, it blinds the programmer to use cases that s/he should have considered and made explicit, and explicitly supported, in the business object model. As a result, the business ends up with apps supporting workflows that were never anticipated or documented, aren't known to the developer team, and that may not be safe or maintainable. At that point, the development organization can be faced with systems that will be immensely hard to refactor because the developers don't have an actual handle on how the current system really works or needs to work. Their sense of the application logic has been drastically reduced. Logic and constraints are just there in the components, and don't ever get surfaced or consciously addressed. "I didn't know the app was doing that" and "I can't find how it does it" are poor opening positions when changes are needed, but a rich UI component library can make either statement very easy to come to. So while not needing to model or support how users actually work can undoubtedly save time if you're lucky, it's also a potentially fatal mistake: the conceptual and object models of the business are at best incomplete, and at worst completely wrong. Complex UI components are powerful, but as with any pixie dust, their implications for total code maintainability may be wide, deep, and, most dangerous of all, hidden.
All that said, I still see UI libraries as tremendous tools, but my approach is cautious. Ideally, an application should be able to satisfy all known requirements or use-cases without them. You should be confident that the problem domain is understood and adequately modeled. In a way, I'm advocating using them primarily as last minute substitutions to cover unknown border cases that, in a complex and changing business, can't realistically be anticipated, and under the banner of YAGNI, perhaps shouldn't be worried about until they emerge in actual practice.
Visual component libraries are a layer of delight and amazement. And more than being just eye-candy, they can in many cases function as safety nets for unanticipated needs. But no matter how fast and easy it might seem, they shouldn't be allowed to replace an organization's main business code, the central business logic on which the organization depends.