Arguments and Results
Total Page:16
File Type:pdf, Size:1020Kb
Arguments and Results James Noble MRI, Scho ol of MPCE, Macquarie University, Sydney. [email protected] Octob er 20, 1997 Abstract If an ob ject oriented program is a collection of communicating ob jects, then the ob jects' pro- to cols de ne the languages the program sp eaks. Unfortunately, proto cols are dicult to design in isolation, so many programs' proto cols are not as well designed as they could b e. This pap er presents six patterns which describ e how ob jects proto cols can b e designed or redesigned. By using these patterns, programs and designs can b e made more simple, more general, and more easy to change. Intro duction Ob ject's protocols, also knowasinterfaces, are very imp ortant in ob ject oriented design. An ob ject's proto col is the face the ob ject presents to other ob jects surrounding it. Using an ob ject's proto col, other ob jects in the program can use the ob ject as a server,thus accessing the b ehaviour the ob ject provides. Similarly, an ob ject can act as a client to other ob jects, in turn using their proto cols to access their services. This pap er presents six patterns for designing ob ject oriented proto cols see Figure 1. The patterns fo cus on two asp ects of proto col design | the messages ob jects can receive, and the results ob jects return in resp onse to the messages. These patterns do not attempt to describ e novel techniques, rather, they present well-established solutions for ob ject oriented design. These patterns should be useful for intro ducing the techniques to novice programmers, and for more exp erienced programmers, should illustrate when particular techniques are applicable and their relative strengths and weaknesses. These patterns are interrelated, but they do not form a whole language. Rather, the patterns are two fragments Patterns ab out Arguments and Patterns ab out Results whichmay one day form part of a larger pattern language. Eachof the fragments has the same structure see Figure 2 with one general pattern, and a couple of more sp eci c patterns which re ne the general pattern to handle sp ecialised contexts. Figure 2 also illustrates two relationships between the patterns. One pattern can re ne another pattern, meaning one pattern is a more sp eci c version of the other. Alternatively, patterns can con ict, meaning that the patterns are mutually exclusive, each providing a di erent solution to a similar problem [26]. Forces Each of these patterns resolves a numb er of di erent forces, and some con icting patterns resolve similar problems in di erentways. Many of the patterns consider the ease of reading or writing of a particular solution | generally, solutions which are easy to write are more likely to b e chosen by programmers, and solutions which are easy to read are likely to b e easier to maintain. Since smaller, simpler programs are generally easier to read and write, the patterns are concerned with the complexity or size of a design, suchasthe number of messages an ob ject understands, or the number of arguments needed by a message. Since much complexity cannot b e avoided, the patterns prefer complexity to b e handled once in server ob jects, rather than many times in every client ob ject which uses the servers. 1 Pattern Problem Solution Arguments How can you simplify a complex proto col Make an Arguments Ob ject to capture the Ob ject that has a regular argument structure? common parts of the proto col. Make a single message taking an ob ject How can you simplify a proto col Selector representing the message selector as an ex- where several messages di er mainly in Ob ject tra argument. their names? Curried How can you simplify an extremely com- Send simpler messages to an intermediary Ob ject plicated proto col? which elab orates them within its context. Result How can you manage a dicult answer to Make a Result Ob ject the whole answer to Ob ject a dicult question? the question. Future How can you answer a question while you Make a Future Ob ject which computers Ob ject think ab out something else? the answer in parallel. How can you answer a question that is Lazy Make a Lazy Ob ject which can answer the easy to answer now, but that may never Ob ject question later, if necessary. b e asked? Figure 1: Summary of the Patterns Arguments Object Result Object Selector Object Curried Object Future Object Lazy Object Figure 2: The Structure of the Language Several patterns address the cohesion and coupling of the resulting designs, as designs with high cohesion within ob jects and low coupling b etween them are more exible, understandable, and easier to maintain. This is often related to whether a concept is represented explicitly by a single ob ject in a design, or whether it is implicit in the communication b etween several ob jects. Representing a concept explicitly as an ob ject generally makes it easier to identify the concept within the design, to change the implementation of the concept if necessary, and to reuse the concept elsewhere, esp ecially if the ob ject represents a real concept from the program's application domain. The patterns are also concerned with eciency | the time and space cost of a design, and the number of objects it requires at runtime. Consequences A common principle underlies all these patterns | that designs can often b e improved byintro ducing nding additional ob jects from within the program. At rst, the newfound ob jects seem out of place in the program, but as the program evolves, the found ob jects b ecome b etter integrated into the design, and can b e recognised as mo delling concepts from the application domain. Because they nd new ob jects, these patterns tend to generate designs with many small, simple 1 ob jects ,intro ducing an extra level of indirection, and imp osing space and time costs at runtime. All these patterns simplify a design lo cally for example, bychanging one particular proto col but imp ose global changes to the program b ecause extra ob jects are needed to implement the changed proto col. As a result, although ob jects may b e easier to understand in isolation, the global design of the program may b ecome confused. To quote Alan Perlis: In the long run every program becomes rococo | then rubble. [20]. If these patterns are applied injudiciously they will accelerate this pro cess. 1 This is not limited solely to these patterns. Many other patterns have this e ect, including those in Design Patterns [9] and Smal ltalk Best Practice Patterns [5], as do Parnas's criteria for program decomp osition [19]. 2 Form The patterns are written in electric mo di ed Portland form. Each b egins with a question in italics de- scribing a problem, followed by one paragraph describing the pattern's context, and a second describing the forces the pattern resolves. A b oldface \Therefore:" intro duces a summary of the solution also italicised followed by the a description of the solution in detail. Then follows an example of using the pattern, the patterns consequences b ene ts rst, a b oldface But:, then the liabilities and nally some known uses and related patterns. Patterns ab out Proto cols Ob jects communicate via proto cols | a program's proto cols are the glue that binds its ob jects together. The following three patterns describ e how ob jects can b e found within proto cols. 1 Arguments Ob ject How can you simplify a complex protocol that has a regular argument structure? Some ob jects have large and complex proto cols with a regular internal structure. For example, a graphical View ob ject will provide proto col for drawing manytyp es of ob jects in many di erentways, but almost every message will take arguments which sp ecify the colour, stipple, and line thickness to use when drawing. The same combinations of arguments may o ccur across many proto cols, and as a result, many arguments may b e passed in parallel through many messages and across many ob jects. Large proto cols are easy to use b ecause they o er a large amount of b ehaviour to their clients. Unfortunately, they are often dicult or time consuming to implement, and for client programmers to learn. Every client of a large proto col dep ends up on the proto col's ne details, such as the names and arguments required by each message, and these dep endencies make large proto cols dicult to change. Moreover, large proto cols are more likely to be changed than small proto cols | adding an eleventh argument to a message with ten arguments is qualitatively quite di erent to adding a second argument to a unary message. To quote Alan Perlis: If you have a procedure with 10 parameters, you probably missed some [20]. Therefore: Make an Arguments Ob ject to capture the common parts of the protocol. In its simplest form, an Arguments Ob ject should have one variable for each argument to be eliminated from the proto col, and the usual messages to access and up date its variables. Change the proto col and its implementations to accept a single Arguments Ob ject in place of the eliminated arguments, and change the proto col's clients to create Arguments Ob jects as required. To supp ort optional arguments, initialise the Arguments Ob ject's variables with default argumentvalues when it is created.