This book is an introduction to a new class of design pattern, the Elemental Design Patterns, which form a foundation for the study and application of software. of Hazrat Mawlana Jalaluddin Rumi's work, regardless of who they are and Immersing oneself in the ocean of love and co. PDF | The decomposition of design patterns into simpler elements may reduce significantly the creation of variants in forward engineering, while it increases the .
|Language:||English, Spanish, Dutch|
|Distribution:||Free* [*Registration needed]|
Elemental Design Patterns [Jason McC. Smith] on fernlowlitiltsi.tk *FREE* shipping on qualifying offers. After fifteen years, the field of design patterns is still . Visit us on the Web: fernlowlitiltsi.tk Library of Congress Cataloging-in- Publication Data. Smith, Jason McC. (Jason McColm). Elemental design patterns / Jason. Elemental Design Patterns: A Formal Semantics for Composition of OO. Software Architecture. Jason McC. Smith, David Stotts. University of North Carolina at.
PDF pone. Redistribution ability may be particularly variable for benthic marine species that disperse as pelagic larvae in ocean currents. The blue mussel, Mytilus edulis, has recently experienced a warming-related range contraction in the southeastern USA and may face limitations to northward range shifts within the Gulf of Maine where dominant coastal currents flow southward.
Introduction Recent increases in mean and extreme temperatures have been implicated in driving local populations and range-restricted species to extinction, and species extinctions may become increasingly common in the next century see  — .
In order to persist i. Although poleward range shifts have already been documented for a number of species  —  , redistribution ability is often unknown and unaccounted for in attempts to forecast species' ranges . Furthermore, populations inhabiting locations with currents that flow predominantly equatorward, opposite the direction of likely climate shifts, might face limitations to shifting poleward .
There is emerging evidence that global warming is precipitating declines in blue mussel, Mytilus edulis, populations of the eastern USA  , .
But this book is all about the exception to that halfhearted 65 66 ELEMENTAL MAGIC approach to animating special effects by default, and whether we are animating effects by hand, or digitally, we can take a cue from the masters of the art and bring that extra magic to every little detail of special effects animation that we create.
Whether we have a tiny or massive budget, the classical design and animation principles that drive the highest quality effects animation can be brought into play and elevate our art form across the board! Do we have anyone around here who knows how to animate water? Interestingly though, before we were introduced to computers and digital 3D effects animation tools, there were actually some great advantages to drawing our special effects that are missing for the digital artist today.
To draw these things accurately is almost impossible. I have puzzled a great deal over the apparent lack of attention that is given today to the importance of these classical animation techniques and principles as they pertain to digital special effects animation.
I have come to believe that it is to a large extent the intoxicating power we have using digital tools, to closely mimic the overwhelming detail of natural special effects, that makes us tend to forget about the importance of stylizing, exaggerating and economizing our designs. Although classical technique is emphasized quite a bit in any really good digital character animation school, young artists delving into the world of digital special effects are more often than not spending very little time learning about classical techniques.
The emphasis, more often than not, is put squarely on learning how to use the various complex software applications that are used to create digital special effects, and these young artists are missing out on an entire universe of classical effects animation knowledge that would elevate their special effects to a much higher level of artistry—if they were only given the opportunity to learn it.
For these young artists, the natural thing to do is to look for the solution to their effects animation problems, somewhere in the highly complex 3D software that has been so heavily emphasized in their animation educations. Keep in mind also, that digital tools open up a world of detail that was never possible for classical animators to draw by hand.
It feels good to be able to make cool effects that look realistic— but do they really look great in a highly stylized cartoon world? The term 2. Add to that a solid understanding of the underlying structures and energy patterns inherent in all special effects elements, and the wellinformed digital effects artist of today does not have to lean on the computer for inspiration, but rather to bring the inspired imagination and vision of a classically trained animation artist to the computer.
We must never forget that the real super computer is our imaginations. And our audiences around the world, the countless millions of people who are inexplicably drawn to and have been enormously entertained by the magic of animation for the past 80 years, need us to remember that.
To best illustrate just how diverse this art form really is, let me share with you a short list of some of the things I have been called upon to animate over the years. First of all—water. Lots of it! Gas, oil, syrup, oatmeal, mud, slime, and saliva. Cigarette smoke, smoke signals, smoking guns, ray guns, exploding planets, bursting bubbles, laundry detergent, soup, salad, sandwiches, wine, whiskey, beer, coffee, bottles breaking, windows smashing, wood splitting, tires spinning, skateboards and running shoes.
Boats and bombs, ships and saddles, boots, pillows, handbags, chicken legs and tacton toes, forks and knives, cups and plates, tornadoes and whirlwinds, leaves and branches. Strings, ropes, threads, beds, and spider webs, just to name a few.
If this seems confusing, let me give you a few illustrations of just how blurry the boundaries get. When water evaporates into mist and clouds, it begins to look a lot more like smoke than water.
So which chapter does it fall into? On the other hand, water that is frozen and forms glaciers, which then crack and break off in great chunks of ice, resembles rocks more so than a liquid. By necessity, we will have to cross-reference many of the effects elements we will be discussing, closely observing their similarities, but more importantly, pointing out the not-so-obvious differences.
The informing energy of the dust, on the other hand, is the pounding hooves of the horse and gravity; once the horse has passed, the dust quickly becomes a victim of gravity, falling back down to the ground as it dissipates.
Where there are splashes in water, there will need to be some bubbles and ripples as well. As you can see, effects is replete with cause-and-effect scenarios between inorganic and organic phenomena and the patterns of energy contained within them. While the shapes of the elements themselves may appear random, if not scattered, as they change states, the main force in the scene will determine the path of that chaos.
Special effects animation is full of these kinds of forces of nature at work. The categories I have committed to are not carved in stone, they are simply the fairest approximation of a logical categorical breakdown that I could imagine. In addition, artists discover their own unique solutions for problem solving regardless of how they initially learned to animate.
This drive for innovation and exploration sharpens the craft and keeps us from falling into the artistic doldrums. I have never worked on two projects in a row, even in the same studio, without noticing a shift in both jargon and method. When in doubt, draw a picture. Sounds simple enough, right? But what sounds like a relatively simple scenario, can quickly turn into a great deal of work for a special effects crew.
The energy released by this clashing of elements is chaotic and unpredictable, but at the same time it contains a marvelously designed energy pattern that is intuitive and natural. But the animator has had to take a lot into consideration to get to this point. Each element has been carefully planned out and executed according to the laws of physics, and the needs of the scene from a storytelling viewpoint. Chapter 4 Liquids This is perhaps the most important chapter in this book.
After over two decades of animating water I am still learning every time I animate another splash, no matter how simple.
Imitating and animating such a sublimely formed natural phenomenon is a process that never gets old for me. It is important as always, to remember the basic golden rules of effects design: avoid repetition, twinning, and symmetry, and keep your silhouettes dynamic and interesting.
Ripples, splashes, currents, bubbles formations, or droplets, do not really create any kind of lines in the water at all. The tiniest change in water surface shapes can radically effect how light bounces off of it.
In this series of drawings, I have taken a piece of calm, rocky shore line and broken it down into four simple and distinct elements.
The same is true today, although the artwork is either scanned or is computer-generated and then the layers are sandwiched together using software specially designed for this task. LIQUIDS 95 It is extremely important when attempting to draw water, to learn how to break down the shapes we see in natural water formations into much simpler shapes and designs.
The amount of detail in even the smallest, simplest splash is intimidating. Just tossing a medium-size stone into a swimming pool will generate hundreds of droplets breaking up off of the main mass of displaced water, with an extremely complex design of over-lapping ripples radiating outward, as the hundreds of droplets all fall back into the water.
If we attempt to draw all of it, we will quickly be overwhelmed by the details. This can be said of most effects elements we will be discussing in this book, so watch out for it. Very, very important to simplify and stylize! However quite the opposite is true. How a splash integrates with the perspective of its environment is extremely important if we expect our animation to feel natural. We must determine our perspective grid before attempting to animate any water surface or splash, and then determine how the circular or elliptical shapes that underlie the structure of our water designs sit upon that perspective grid.
Our effects must always integrate themselves credibly with their environment, or else the viewer will feel that something is amiss, and their attention will be drawn away from the story.
Properly executed special effects should not draw undue attention to themselves. A perspective grid must be established when animating effects which occur on a surface. The ellipses of ripples caused by a splash must always conform to this perspective grid. If we animate ripples expanding uniformly in every direction, we lose the correct angle of the perspective.
Ripple ellipses must expand farther horizontally than vertically, in order to stay true to the perspective. Ellipse 1 is quite narrow vertically, and describes a sharp perspective on which the ellipse is sitting. Here we have the same ellipse 1, and ellipse 5 has stayed true to the perspective, and is simply a larger version of the exact same ellipse as the smaller one. Also extremely important to remember is that as our elliptical shapes animate—the perspective must be retained from drawing to drawing.
This is where the mistake is often made, even by some of the best effects animators in the business. In order to draw this phenomena, we need to stylize and simplify. These photos are random and do not represent a sequence of action.
In these sequences, only four drawings are used. In some cases only three or even two drawings can work reasonably well. Personally I always like to go a little bit farther even with something as simple as a raindrop. This is a straight on side view. The drops on this page would be hitting a solid surface. It is plain to see, that these are much simpler designs than something like the photos of the milk drop on the previous pages.
This is especially important when you are animating lots and lots of raindrops, but it also looks cleaner and neater than getting too detailed with your splashes.
This is a slightly downward view of a raindrop. This is a straight down shot of a raindrop splashing on a solid surface. Again, this formula is not carved in stone. This would introduce a nice amount of variety to the look and implied scale of the raindrops. The sheer volume of water being displaced is tremendous, and to really get that feeling of immense volume across to the viewer, the effects animator needs to make this splash move relatively slowly after the initial explosive impact.
There are no fast easy ways to make something this big look convincing. It is interesting to note that after working with certain highly talented effects animators over the years, I am able to recognize their effects drawings with only a cursory glance. All of the splashes on these two pages are roughly the same size. Not only is it pleasant to look at, it is also a far easier style to animate, and therefore cheaper to produce.
The ball drags a bubble of air underwater with it, which breaks apart almost immediately into smaller air bubbles. Waves or ripples emanate outward in a circular pattern from the point of impact. This hang time is an important aspect of any splash animation, and will largely determine the scale and dramatic effect of our splash. As this apex hang time is occurring, ripples continue to emanate outward from the initial point of impact, slowing down and diminishing in size and intensity as they go.
Its timing will also differ from and overlap the timing of the initial splash Figs. It is green and lush, and it thrives in that area without maintenance. For that specific area, moss is a good ground cover solution. In the rest of the yard with little or no shade, it turns out that moss and grass do play well together, more or less. Unfortunately, the moss has a side effect. In the sunniest areas, the moss acts as a protective layer for weeds to sprout underneath, safe from birds and mice who would eat the seeds or shoots, and properly moist.
By letting the moss exist in the sunny areas, I was giving weeds a nursery to get established, and when they penetrated the moss, they thrived in the sunlight and spread rapidly. The moss also provided a protective moist layer for the roots of weeds to travel along, offering them an unhindered growth channel.
Within a couple of months, I was fighting a literal turf war with the weeds. The moss was never a problem by itself, but it set the scene for a much larger one. And now I know the why behind removing moss from a lawn. Essentially, the moss creates a new set of forces at play that form a new context.
Within that new context, that new environment, new problems arise—like weeds. Now the advice to remove the moss makes sense, at least for areas where weeds are an issue, such as the sunny areas of my yard.
Because I know the why, I can now alter my application of this knowledge according to the environmental forces. In the sunny areas, I must remove and prevent the moss so that weeds are not a later problem.
What was initially tribal mythology is now tribal wisdom that can be shared, adjusted, and applied when and where appropriate. In essence, it is the beginning of a pattern. There is no doubt that patterns are a thriving meme, and one with great utility. Tools exist to produce, display, generate, and extract patterns. Patterns, as a collective whole, are an assumed component of the software engineering landscape.
Two issues prevent a more comprehensive approach to patterns, and unfortunately they are ubiquitous in the industry. The first is treating patterns as frozen elements to be blindly copied, the second is confusing language-specific pattern implementations with variants of the patterns themselves.
Patterns are intended to be mutated, to be warped and molded, to meet the needs of the particular forces at play in the context of the problem, but all too often, a developer simply copies and pastes the sample code from a patterns text or site and declares the result a successful application of the pattern.
This is usually a recipe for failure instead of a recipe for producing a good design. We undermine the entire purpose of design patterns when we do that.
We need to be able to describe the whys behind a pattern as well as the hows. Without the understanding of the reasons that led to the description of that pattern, rote application often results in misapplication. At best, the result is a broken pattern that simply does not match the intended outcome. At worst, it injects an iatrogenic pattern into the system— one that is intended and thought to be of benefit but instead produces a malignant result that may take years to uncover.
This is patterns as tribal mythology—action without understanding. Introduction to Design Patterns The traditional design pattern form, as defined in Design Patterns , explains the whys behind a pattern—motivations, applicability, and consequences—but it is up to the reader to tease out the underlying concepts that form a pattern.
To some degree, these subconcepts are described in the Participants what are the pieces and Collaborations how do they relate sections for each patterns, but again, these are frequently treated by developers as checklists of pieces of the solution for rote implementation instead of as a description of the underlying concepts and abstractions that comprise a solution.
Different languages offer different strengths centered around the concepts they support and how they express them. How those concepts happen to be expressed is more often the start of flame wars between language fans, but ignoring the underlying concepts leads to much argument over nothing of particular consequence in most cases.
What this means is simply that some patterns are easier to implement in some languages than in others. The Visitor pattern is a good example. In fact, some programming languages support it directly CLOS, for example. For a language feature?
In most other languages, however, Visitor provides a clean way of expressing the same programming concept of double dispatch. This illustrates an important point. If you mention double dispatch instead of the Visitor pattern to the same CLOS developers, they would know what you mean, how to use double dispatch, and when not to use it. Terminology, particularly shared common terminology, matters a great deal.
No language can really be considered superior to another in this case, however. Design patterns describe useful concepts, regardless of the language used to implement them. Whether a specific concept is baked into the feature set of a language or must be implemented from scratch is irrelevant. The concept is still being expressed in the implementation, and that is the critical observation that lets us talk about software design independently of software implementation.
Design is concepts; how those concepts are made concrete in a given language is implementation. This sounds like a lot of work, but these were concepts considered so important that they launched a revolution in language features to make them easier to work with. That revolution was object-oriented programming. In object-oriented languages, those concepts are included as primary language features called classes, visibility, and constructors.
Again, we can refer to the GoF: And yet again, this is a fundamental point that seems lost on most developers, so let me restate it. Patterns are language-independent concepts; they take form and become concrete solutions only when you implement them within a particular language with a given set of language features and constructs.
Some design patterns are unique to specific languages, and only those languages, but those patterns are often called language idioms. In this text when we use the term design patterns, we are specifically talking about concepts that are language independent. Introduction to Design Patterns difference between patterns as expressed in Java and those expressed in another language such as Smalltalk.
The concepts are the same; only the manner in which they are expressed and the ease with which a programmer can implement them in that specific language differ. We need to focus on these when investigating design patterns, and these abstractions must be the crux of understanding patterns. Unless we make the effort to look at patterns as language-independent concepts, we are merely learning rote recipes again and losing much of what makes them so useful. We have an art. What we need is a science.
After all, we throw around the terms computer science and software engineering with abandon. Treating patterns as sample code misses the point of design patterns. Design patterns enable us as an industry to experiment with those concepts and share, discuss, and refine our findings.
Patterns as rote recipes are tribal mythology. Patterns as concepts are the foundations of a science. Elemental Design Patterns are the building blocks of that science. Two traits make them unique: First, they are written in the style of the design patterns literature. Each is treated as a standalone concept with a specific name by which it can be discussed and mulled over until it is understood. This book presents each EDP along with a problem that it is suited for and discusses when the pattern should and should not be applied.
You will find example implementations, comments on possible consequences of using the patterns, and related patterns that you should look at as well.
This humanoriented definition of each EDP provides you with a common term you can use to clearly and precisely converse with other students or developers about the concept. Second, design patterns are descriptions of solutions to common problems that were found through the examination of existing software systems.
EDPs are also solutions to common problems, and once you know what to look for, you will find them everywhere. They are in fact so common that, until now, they have not been considered worth writing up in any comprehensive way.
EDPs were originally identified as a comprehensive body of interrelated design concepts not in software but in a formal description of software. Elemental Design Patterns of object-oriented languages, but rest assured, with the exception of an appendix safely tucked in the back, this text is mathematics free. The solid yet simple ideas underlying the EDPs provide a strong framework on which to revisit these basic concepts, give them new life, and repurpose them for new applications.
This foundation also gives you a compelling ability to use them as tiny building blocks, almost like atoms, to describe other design patterns in solid and direct ways. And, like atoms, you can build worlds with them. This book gives you some background on EDPs, where they came from originally, and how they fit into the larger context of design patterns in programming.
It also gives you just enough of a taste of object-oriented theory to understand how the patterns all relate to one another, but no equations, I promise. We discuss some of the ideas underlying the basics of object-oriented programming, much of which you may already be familiar with. Finally, you learn how that basic theory gives rise to a veritable stable of concepts that you can use in your everyday programming.
Later chapters explain how you can use EDPs to make your designs better. SPQR is a research project for identifying instances of known design patterns within an existing body of source code. It can find design patterns independent of the original source code language and can easily find various implementations of the same design pattern from a single pattern definition.
I was inspired to create SPQR while working as a professional software engineer. I was on a team responsible for one of three libraries used in a real-time commercial and military flight simulation system. In one of our joint all-library development meetings with the application team, they thanked us profusely for a feature we had just added, stating that it was exactly what they needed.
After the meeting, the three library teams looked at each other and asked if the others knew what the application team had been talking about. Nearly developer hours later, we had our answer. We had an instance of a Decorator pattern, one of the Gang of Four GoF patterns, embedded and hidden within the system. Pieces of it were scattered across the three libraries, and the application team had stumbled onto their integration as a whole.
We were stunned. A rather heated debate ensued: Was this really a design pattern? Well, most software does just that. It grows organically, and often in unexpected ways. In managing software projects, we can only manage what we know, and knowing that there was this useful design element provided us an opportunity to enhance, streamline, and document its existence for developers to use effectively.
Finding it—that was the problem. Remember, we had written the software in question, we were the experts, and it still took us an inordinate amount of time to deduce what was going on. Automation of the process was the obvious answer. As I mentioned in Chapter 1, what we really want is self-documenting code, or at least a system to extract that documentation.
SPQR is such a system. Creating SPQR necessitated solving a fundamental problem: I had to teach the computer how to identify design patterns. Patterns are not rote recipes; they are soft and amorphous things we humans call concepts. Most research and industry systems that attempt to find instances of patterns in source code do so by looking at patterns as constructs—as rigid forms that look like implementations—rather than as abstract concepts.
This is a reasonable approach, and it treats patterns as many developers do: The thing is, this approach once more reduces the design patterns to specific implementations.
Every variation of a possible implementation requires a new definition. These tools are stellar examples of the approach and are worth your investigation. They do their job well, and they add value if you happen to meet their requirements. The problem with this approach is that defining a pattern for queries as a construct is highly fragile. None of these conditions would be found by a construct-oriented approach to From the Library of Santiago Itzcoatl Salinas Reyna 16 Chapter 2: Elemental Design Patterns design patterns, and they would require new pattern definitions.
Remember, patterns are implementation-language independent—the scope of the issue is much larger. It seemed obvious that a different tactic was needed with SPQR. Diving into the background and history of design patterns yielded the necessary clue. As I read his first and, at least within the software engineering community, least-cited treatise on design patterns, Notes on the Synthesis of Form , I realized something important had been lost: This simple truth fundamentally alters what I was trying to teach the computer to recognize.
Teaching a computer system to look for language constructs bolted together in rigid structures will never give us the flexibility we desire with the accuracy we need. Unfortunately for this particular task, the established design patterns literature is primarily geared toward describing high-level, abstract concepts, which is part of what makes them so powerful—they lift the discussion of a design to a higher level of abstraction.
Programmers generally have a good working handle on lowerlevel abstractions, so establishing them as patterns has never seemed necessary. The design patterns community is rightly focused on documenting those lessons that are not already ingrained and well understood. These design patterns described by the software community tend to be at the larger end of the spectrum. Computers, on the other hand, are fundamentally only as knowledgable as the foundation we can teach them.
For SPQR, we had to establish a chain of concepts from the ground up so it could help us deal with the concepts of programming. We had to fill in the gap between the highly rigid pieces of an implementation and the sometimes fluid concepts that they represent. In doing so, it became apparent that the EDPs were just that—design patterns that form a fundamental basis from which to describe software design not just for automated analysis but for humans as well.
This book is a partial catalog of the EDPs written for human, not machine, consumption. It is intended to be used by developers, students, and designers to help fill in the gaps in our understanding and our language when discussing software design. As expected with design patterns, each EDP has an informal write-up, or pattern specification, to use an accepted term, and also has an origin as a mathematical construct. This latter trait makes the EDP catalog unique. This brings us to two ways of describing EDPs: The following section intertwines the two while keeping the formalisms to a minimum.
What do we do when faced with a large and gnarly task in computer science? We break it down. Deconstructing the design patterns literature is not a simple thing. A few attempts have been made over the years [12, 17, 32, 40, 41, 43], but they have been partial deconstructions, seen as oddities or curiosities by most developers and researchers outside the immediate field. After all, these smaller deconstructed pieces and concepts are obvious, right?
They are basic concepts, basic things we deal with every day, so why bother describing what we already feel we know? Someone who was trained in functional programming in ML understands recursion very differently from someone whose primary background is C.
The two developers will have different assumptions about recursion, where it is useful, and how it should be applied, even though the basic underlying problem that it is solving is the same. Given the discussion of housing styles in Chapter 1, this idea should start to sound familiar. I said earlier in this chapter that the lower-level concepts of programming have not been a primary target of the design patterns community because the literature is aimed at documenting concepts that are neither ingrained nor well understood.
Elemental Design Patterns The low-level concepts we use in programming are unselfconscious, as Alexander defined it.
Most of us never study the principles underlying those concepts, but they exist and are well understood at a mathematical level. In a nutshell, EDPs are the underlying core concepts of programming and software design that have remained mostly undescribed.
Those that have been described have not been related to one another in a meaningful and wellfounded manner until now. Each EDP is a selfconscious description of a core concept. The EDP catalog as a whole relates the EDPs to one another to form a conceptual framework that the student or developer can use to understand other patterns. It provides a taxonomy and lexicon for describing higher-level abstractions, homogenizing the language and abstractions such that when any two developers reference, for example, the EDP Extend Method, they both have a precise understanding of a common definition.
EDPs provide a language with which to reason about, describe, and discuss software, from the most fundamental levels on up. Mainstream design patterns have done an amazing job of providing this knowledge base for the seasoned pro, but until now, no one has aimed that same tool at the novice or student in a comprehensive way.
So how far can we deconstruct these concepts from the design patterns literature? Types and classes in examples are capitalized and set in monotype font.
Code examples use the same system. In general, Decorator is a popular and commonly used design pattern that provides a mechanism for behavior to be extended dynamically at runtime. You can think of it as an internal plug-in or extension system, like you would find in a web browser.
Suppose you want to decompose Decorator to better understand it. It is, after all, a rather high-level abstraction. If you can absorb smaller pieces individually, you can almost certainly have an easier time understanding the pattern.
You can download one, put it in your garage, break out the tools, and disassemble the whole car, or you can learn about the pieces individually. You can study the internal combustion engine, for instance, or the hydraulic braking system. Those systems can be further broken down into parts that you can investigate one by one to make the larger study task easier.
In the end, if you know how a gasoline engine works, you not only have the facility to comprehend that portion of the race car as a unit, as an encapsulated abstraction, but you can apply that knowledge to other vehicles, or even lawnmowers, generators, and any other gasoline-engine-driven machine.
Decomposing design patterns serves a similar purpose: After an exhaustive search of the existing literature on design patterns and remember, there are thousands , you might notice that Decorator shares similarities with two other patterns. One is Objectifier, first described by Walter Zimmer in , shown in Figure 2. Objectifier describes a way for a single object interface to represent multiple From the Library of Santiago Itzcoatl Salinas Reyna 20 Chapter 2: When a client requests a method to be invoked through the Objectifier interface, it does not know which of the two or more concrete method bodies is executed.
Object Recursion chains together two objects with related types. Looking at the UML diagrams in Figures 2. Although they are not exactly the same, certain features in their structure of the UML are similar enough that we can describe parts of Decorator in terms of these other patterns—we can say that Decorator is composed of these patterns.
A closer look shows that Objectifier can be considered a part of Object Recursion. Object Recursion uses Objectifier as the backbone of its form, but it adds a link between one of the concrete implementations and the interface, and it does From the Library of Santiago Itzcoatl Salinas Reyna 2. In other words, when the Initiator class calls handleRequest , by the intent of Objectifier, either the Terminator or Recursor class might handle it. If Terminator handles it, the request is complete.
If Recursor handles it, an additional call is made through the interface for another handleRequest , and the process starts over again. This chain continues until Terminator is the handler, at which point the chain, unsurprisingly, terminates. We should have a better decomposition to work with, but at least we know that patterns can be described in terms of smaller patterns.
What is the smallest deconstructed pattern we can make that is still a pattern? To answer that question, we need to ask again, What is a pattern? We know it is a concept, we know it is an element of design, and we know has certain critical components.
Design is the manner in which parts of a whole interact with and relate to one another, as illustrated in the outline of a design pattern written in the accepted canonical format popularly described in the GoF text. Consider a common definition of design pattern: The structure, implementation, and sample code are unmistakably the solution. The intent, motivation, and known uses describe the problem space. Elemental Design Patterns Table 2.
They describe the parts and their relationships that lie at the intersection of the three arms of a design pattern. Relationships form the core of design. The design of a car is more than a pile of pieces: A house is more than a stack of lumber, a case of nails, and some copper piping; it has a form, or plan, that fights entropy and, we could say, keeps the structure at a higher energy level than just a rubble pile.
The parts list ensures that you have everything you need to begin building, but the relationships in the design tell you how to make them work in concert.
What is the smallest relationship we can define? Well, that one is easy. A single relationship between two things is simplest. Now we can apply this insight to the deconstruction of design patterns. This gives us a clear goal. Well, not all relationships are created equal. Some are quite important when discussing design, and some are there to provide a context.
The primary contextual relationship is that of scoping, and it appears in many forms. The scope is how that element is made unique from all others in the system.
Their scope indicates that they are distinct classes, never to be confused. This principle applies any time there is an enclosing something that has a name and within which you define something new. Classes are scopes for the methods and fields they define. Namespaces and packages are scopes for anything inside of them. Methods and functions are scopes for the local variables declared within them.
Over and over again we see the same mechanism at work in many different language features. To access a specific element, we state precisely which one we want by providing the scopes from the top down.
Sometimes these scopes are implicit, and we can leave them off, such as when referring to a local variable within a method or to another member within a class. Furthermore, despite their common behavior, these scopes can have different syntaxes through which they are accessed. Menu, using a double colon. Given an instance of that class, however, we would access its list of menu items as aMenu. Both of these techniques specify which element we wish to select from a scoping element, but they do so in different ways.
This text defines a single way in which we can treat all scoping, regardless of how it is implemented for specific language features within specific languages.
A has a field b of type B. In the main body, an instance a of type A is instantiated, and then a. The method f is scoped by the object a. In object-oriented languages, functions and methods are always enclosed by some scope, even if the scope is implicit. Check Clause 3. Elemental Design Patterns Listing 2.
Again, objects are being used to scope and wrap elements that have previously been considered as freely roaming. Getting back to the code example, a. The relationship between a and f, one of enclosure or scoping, is contextual.
It helps specify which method we are talking about. A similar relationship exists between b and g. The call from a. Scoping relationships help us refine our view to a particular design element. We need exactly two such design elements to form the single relationship described in an EDP.
There may be a number of scoping relationships that set up the final single relationship we are interested in, but we are not immediately concerned with them. They are part of the description of the elements of programming that comprise the endpoints of the relationship we wish to work with. Returning to our earlier metaphor of housing styles and design, the scoping elements are a bit like stating that a piece of wood is a two-by-four or a half-inch-thick sheet of bias-grain plywood.
Now we just have to determine what a relationship of interest is. What remains are classes, their fields and methods, and little else.
One item seems to be missing from the list: It is object-oriented programming, after all! For a formal explanation, see the appendix. For now, we have these four kinds of programmatic entities on our list: This may seem like an odd thing to do, but it actually makes solid sense. A class is an interesting beast in that it is so common in most object-oriented languages that many students and developers consider it a primary and necessary element.
The reality, from a strictly object-oriented viewpoint, is that it is not. Instead, they rely on prototyping, cloning, and other actions on objects to perform the same functions. Even Smalltalk, arguably the progenitor of most object-oriented languages, has a quite different implementation and understanding of a class even though the same term is used.
First, it describes the elements that will be in instantiated objects of that class, the member methods and fields.
Most of us expect a class to be used in this way. Second, it describes elements that are common across all instantiated objects of that class, the class methods and fields. The first use case corresponds directly to a type in the formal sense, and the second use case can From the Library of Santiago Itzcoatl Salinas Reyna 26 Chapter 2: Notice that in main the use of the class field sharedField is prefaced by the class name MyClass.
This is exactly the same notation used to access aField in the defined myNamespace. We provide the name of the object and the piece we want selected out of it, just like any object that was instantiated from a class in the normal way. When the language provides a namespace, a package, or a class, it is providing a way of instantiating these objects automatically. Still not convinced? In Smalltalk, the class is represented by an object. Literally, it is named the class object.
Class methods and fields live in that class object.
It is almost exactly the scenario we are describing here. Or, look at Java. In Java the class object is a special object that is available for inspection through reflection and is associated with a class that a developer defines.
Listing 2. Although the details of how it is handled will differ from language to language, in every case a class can be emulated using a type and an object. While this may sound a bit foreign to you at first, it quickly becomes second nature in practice. Any defined class members would be moved into a corresponding class object, as in Smalltalk, or into the reflection-accessed Java class object. We needed types in order to satisfy basic properties of typed languages, and objects are the core of object-oriented languages regardless of their class features.
By using these two in conjunction, we can emulate classes from class-based objectoriented languages. This allows us to simplify our set of items needed to define design patterns to just our four previously mentioned items: In what ways can the items on this short list interact? Table 2. Methods can, in some languages, similarly define, or scope, inner methods or types, and of course we can define local variables or fields. Methods can also call other methods, use nonlocal fields, and have a return type.
Fields are simpler in that they can be assigned the return value of a method or of another field. And, of course, they have a type. Not that many interactions are possible now, which means that we can start enumerating them into a finite and, better yet, quite small set of possibilities.
A field has a type on which it relies; this is simply the type of the field. The same holds for objects. Similarly, methods have return types. They are used to define what a piece of data is, whether it is a field or another object such as a parameter or a return value from a method. Much like scoping, defining data has the feel of describing the object or field itself, not providing a relationship between two entities.
For instance, look at the code snippet in Listing 2. The data member pos is defined as being an instance of the type Position. Similarly, the types of the parameters to the scaleCopy method only tell us what those parameters are, not how they relate to anything else. On the other hand, other relationships, such as a type relying on another type, provide more information than just a description of one element. We might even say it is ingrained and understood.
For the purpose of defining the EDPs, there are only the four basic relationships left in the center of Table 2. As shown in the preceding tables, we can call these a method call, a field use, a state change, and cohesion. Believe it or not, nearly this entire book concentrates on just the first one, a method call reliance.
Yes, there is a lot to be said about a simple method call reliance when looked at in the right light. It has probably occurred to you that a method call looks an awful lot like a structural entity, not a conceptual one. Consider a method f that calls method g in its body. We say that f relies on g. Now assume that g in turn calls another method h, as in Listing 2. We say that g relies on h. It should be self-evident that this relationship is transitive—if f relies on g, and g relies on h, then f also relies on h.
If we want f to rely on h, does it matter if it is a direct method call or if method g is in the middle? It does not. As long as f relies on h by some path, our requirement holds true.
We just made the leap from a structural connection, that of a method call, to a conceptual connection, that of a method call reliance. This frees us from having to discuss low-level programming concepts of design in a structural manner and enables us to describe them in the conceptual way outlined earlier as necessary for working with and finding design pattern instances with SPQR.
We discuss this in more detail and show how it forms a critical portion of working with EDPs in Chapter 4, Section 4. In the process of teaching SPQR about programming concepts, we made the transition away from rigid structures of programming and instead gained a From the Library of Santiago Itzcoatl Salinas Reyna 30 Chapter 2: By using these same techniques ourselves, we provide developers and designers with the same flexible thinking and ability to abstract design from implementation in a methodical yet understandable manner.
We get double duty out of the same approach. We have reduced our list of interesting elements of programming to just four: We concentrate almost exclusively on the method—method reliance in this book. Can this one reliance, based solely on method calls, really do anything useful to help us describe the larger design pattern literature?
Given the right context, anything is possible. We focused on primary reliances such as those between methods and fields, bypassing other kinds of relationships, such as type—type reliances or inheritance. For a given method call reliance, there are three other pieces of information we can work with to help us figure out what the purpose of that reliance is in a particular design.
In more pure languages such as Java, you cannot; each method must be in an object, either as an instantiation of a class or as a static class-level method, which is equivalent to placing the method with the class-object for that class. For any given method call reliance, then, there are four pieces: Figure 2. These pieces are present in every method call. The three pieces of information hiding in plain sight are: The similarity between the enclosing objects 2.
The similarity between the types of the enclosing objects The 3. Colloquially, it means what you think— a resemblance between two things. But what does it mean in the context of method call reliance? Elemental Design Patterns Object similarity is the extent to which one object is like another. Is it the same object? Is it an alias to the second object through a pointer? Is it completely unrelated? We can also discuss the similarity of relationship between the types of the objects.
Are they the same type? Is one a subtype of the other? Or maybe one is a sibling type of the other, with a common supertype ancestor? Method similarity is a bit trickier. We need to determine whether two methods are trying to do a similar task. We could look at many aspects: There is a much easier way, however, if we take a page from social engineering and look at the method names and, to a lesser extent, the method signatures.