Modern Programming: Object Oriented Programming and Best Practices
上QQ阅读APP看书,第一时间看更新

Capturing Elements of Reusable Design

A pattern for increased monitoring for intellectual property theft by departing insiders

Title of (an article in the Proceedings of the 18th Conference of Pattern Languages of Programs — https://dl.acm.org/citation.cfm?id=2579157), PLoP'11

Christopher Alexander, while evidently seminal in the field of built architecture, seems pretty lazy as architects go. Why? Because rather than designing a building or even a town himself, he expects the people who will live, work, shop, and play there to do that for him, and even to build its prototype.

In fact, this has little to do with laziness; it's because he believes that they are the best people to do the designing as they are the people who best know the uses to which the structure will be put and the problems it will solve. What does he know about that? Not much; what he knows is the expertise architects have gained in solving problems that crop up when designing and constructing towns and buildings.

In A Pattern Language: Towns, Buildings and Construction, Alexander and his coauthors and reviewers sought to encapsulate that professional knowledge in a grammar that would allow a user to solve their own construction problems by taking advantage of the solutions known to work by the expert architects. Each pattern describes the problem it solves, the context in which it solves it, and the advantages and limitations of the solution. Some represent instant decisions to be made – the placement of columns in a building construction; others represent experiences to be nurtured gradually – the opening of street cafes to facilitate relaxed interaction between people and their environment. The grammar developed in A Pattern Language is additive, so each pattern develops ideas that have been introduced previously without depending on patterns that will be seen later, and there are no cyclic references. Each pattern is hyperlinked (old-school and using page numbers) to the preceding patterns it builds upon.

We could expect that, in taking inspiration from A Pattern Language, software designers and builders would create a pattern language that allowed users of computers to design and build their own software, by elucidating the problems the users are facing and expressing known approaches to solving those problems. And indeed, that is exactly what happened when Kent Beck and Ward Cunningham published Using Pattern Languages for Object-Oriented Programshttp://c2.com/doc/oopsla87.html. The five Smalltalk UI patterns listed in that report are like a microcosm of a Human Interface Guidelines document, written for the people who will use the interface.

However, what most of us will find when looking for examples of a pattern language for software construction are the 23 patterns in the 1994 "Gang of Four" book Design Patterns: Elements of Reusable Design by Gamma, Helm, Johnson, and Vlissides. Compared with the 253 architectural design patterns documented by Alexander et al., the software pattern language seems positively anemic. Compared with practice, the situation looks even worse. Here are the three patterns that see regular use in modern development:

  • Iterator: You won't have implemented the Iterator pattern yourself; it's the one that programming language designers have worked out how to supply for you, via the for (element in collection) construct.
  • Singleton: You'll have only built Singleton so that you could write that blog post about why Singleton is "Considered Harmful."
  • Abstract Factory: The butt of all jokes about Java frameworks by people who haven't used Java frameworks.

Here's the thing: the Gang of Four book is actually very good, and the patterns are genuinely repeatable patterns that can be identified in software design and that solve common problems. But as Brian Marick argued in Patterns Failed. Why? Should we care?—https://www.deconstructconf.com/2017/brian-marick-patterns-failed-why-should-we-care, the 23 patterns discussed therein are implementation patterns, and software implementors (that's us) don't want repeatable patterns; we want abstraction. Don't tell me "Oh, I've seen that before, what you do is..."; tell me "Oh, I've seen that before, here's the npm module I wrote."

The big winner for software reuse was not information that could be passed from one programmer to another, but information that could be passed from one lawyer to another, which allowed other information to be passed from one programmer to another's program. The free software license (particularly, due to the conservative nature of technologists in business, the non-copyleft free software licenses like the MIT or BSD) permitted some programmers to publish libraries to CTAN and its spiritual successors, and permitted a whole lot of other programmers to incorporate those libraries into their works.

In that sense, the end situation for software reuse has been incredibly similar to the "software ICs" that Brad Cox described, for example, in Object-Oriented Programming: An Evolutionary Approach. He proposed that we would browse the catalogue (the npm repository) for software ICs that look like they do what we want, compare their data sheets (the README.md or Swagger docs), then pick one and download it for integration into our applications (npm install).

Anyway, back to design patterns. Marick suggested that the way we work means that we can't benefit from implementation patterns because we don't rely on repeated practice in implementation. Some programmers do participate in Code Katahttp://codekata.com/, a technique for instilling repeated practice in programming, but by and large we try to either incorporate an existing solution or try something new, not find existing solutions and solve problems in similar ways.

Indeed, we could vastly shrink the Gang of Four book by introducing Strategy (315) and describing all of the other problems in its terms. Abstract Factory? A Strategy (315) for creating objects. Factory Method? The same. Adapter? A Strategy (315) for choosing integration technologies. State? A Strategy (315) for dealing with time. But we don't do that, because we think of these as different problems, so describe them in different terms and look for different solutions.

So, abstraction has to stop somewhere. Particularly, it has to stop by the time we're talking to the product owners or sponsors, as we're typically building specific software tools to support specific tasks. Built architecture has techniques for designing residences, offices, shops, and hotels, rather than "buildings," A house for a young single worker is different from a house for a retired widow, although both are residences with one occupant. So, this points us, as Brian Marick concludes, to having design patterns in our software's problem domain, telling us how domain experts address the problems they encounter. We might have good abstractions for stateful software, or desktop application widgets, or microservice-based service architecture, but we have to put them to specific ends, and the people who know the field know the problems they're trying to solve.

And indeed, that is one of the modern goals of the Pattern Language of Programming conference series and the software patterns community. I expected that, on first reading, the pull quote chosen for this section ("A pattern for increased monitoring for intellectual property theft by departing insiders") would raise a few cynical laughs: "Wow, the patterns folks are so far down the rabbit hole that they're writing patterns for that?" Well, yes, they are, because it's a problem that is encountered multiple times by multiple people and where knowledge of the common aspects of the solution can help designers. Any enterprise IT architect, CISO, or small company HR person is going to know that leavers, particularly those who left due to disagreements with management or being poached by competitors, represent an increased risk of IP theft and will want a way to solve that problem. Here, the pattern language shows the important dimensions of the problem, the facets of the solution, and the benefits and drawbacks of the solution.

A quote from the pattern description is revealing:

The authors are unaware of any implementation of the pattern in a production environment.

This means that, while the solution does (presumably and hopefully) capture expert knowledge about the problem and how to solve it, it is not tested. The design patterns from the Beck and Cunningham paper (and Beck's later Smalltalk Best Practice Patterns), and indeed the Gang of Four book, were all based on observation of how problems had commonly been solved. There were not lots of C++ or Smalltalk programs that all had classes called AbstractFactory, but there were lots of C++ or Smalltalk programs that solved the "We need to create families of related or dependent objects without specifying their concrete classes" problem.

On the other hand, there is nobody outside of an SEI lab who has used "Increased Monitoring for Intellectual Property Theft by Departing Insiders" as their solution to, well, that. So, perhaps patterns have gotten out of hand.