Design Patterns • II Design Patterns • II Alexei Khorev Alexei Khorev Design Patterns • II Gang of Four Pattern Catalog Erich Gamma on Design Patterns 1 Software DPs Software DPs The Design Pattern Bible COMP2110/2510 Software Design Software Design for SE September 10, 2008 Software DPs The Design Pattern Bible JUnit case study JUnit case study 2 The Design Pattern Bible GoF Catalog GoF Catalog 3 JUnit case study 4 GoF Catalog Alexei Khorev Department of Computer Science The Australian National University 16.1 Refresh DP’s definition Design Patterns • II 16.2 What the Design pattern is? Alexei Khorev Design Patterns • II Alexei Khorev Software DPs • A design pattern is a way of reusing abstract knowledge The Design Pattern Bible about a problem and its solution JUnit case study • A pattern is a description of the problem and the essence of GoF Catalog its solution According to Buschmann et al, “PatternOriented Software Architecture”, Wiley 1996: • A pattern is a reusable abstraction which can be applied in “ A pattern for software architecture describes a particular recurring design problem that arises in specific design contexts and presents a well-proven generic scheme for its solution. The solution scheme is specified by describing its constituent components, their responsibilities and relationships, and the ways in which they collaborate.” • A pattern is the abstraction from a concrete form which keeps Software DPs The Design Pattern Bible JUnit case study GoF Catalog different settings recurring in specific non-arbitrary contexts • Pattern is an abstraction which goes beyond object characteristics such as inheritance and polymorphism, and often relies on them 16.3 16.4 What the Design pattern does? Design Patterns • II Design patterns characteristics Alexei Khorev • A design pattern represents a widely accepted solution to a recurring design problem in OOP • A design pattern describes how to structure classes to meet a given requirement Design Patterns • II Alexei Khorev • A pattern describes a solution to a recurring problem that arises in specific design situations • • Patterns are not invented; they are distilled from practical experience Software DPs The Design Pattern Bible JUnit case study GoF Catalog • A design pattern provides a general blueprint to follow when implementing part of a program • A design pattern does not describe how to structure the entire application Patterns describe a group of components (eg, classes or objects), how the components interact, and the responsibilities of each component. That is, they are higher level abstractions than classes or objects • Patterns provide a vocabulary for communication among designers. The choice of a name for a pattern is very important • Patterns help document the architectural vision of a design. If the vision is clearly understood, it will less likely be violated when the system is modified • Patterns provide a conceptual skeleton for a solution to a design problem and, hence, encourage the construction of software with well-defined properties • Patterns are building blocks for the construction of more complex designs Software DPs The Design Pattern Bible JUnit case study GoF Catalog • A design pattern does not describe specific algorithms Patterns help designers manage the complexity of the software. When a recurring pattern is identified, the corresponding general solution can be implemented productively to provide a reliable software system. • A design pattern focuses on relationships between classes 16.5 The Gang-Of-Four Book Design Patterns • II 16.6 Facts about the GoF book Alexei Khorev The adoption and efficient use of a new technology benefits greatly from a systematic and high quality description of such technology. In the case of DPs, the incontestable source of their description is the famous book: Design Patterns • II Alexei Khorev • The authors worked on it over four years, selecting OO design practices which could be recast as design patterns, distilling the presentation, culling those deemed not immature yet etc. The result: Software DPs The Design Pattern Bible JUnit case study Software DPs The Design Pattern Bible JUnit case study • One of the top bestselling books on software — fourteen GoF Catalog GoF Catalog years on, it’s reprinted 3-4 times a year, more than half a million copies have been sold so far. People are eagerly waiting for a new edition. . . Author Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides • Printed T-shirts with individual DPs can be Title purchased from Coder Gear Company — choose your favourite design pattern today! • A CD version of the book is also available (very handy!) • Now, Amazon does not only sell the book, but also provide an on-line copy for reading (akin to Google Books service) Design Patterns: Elements of Reusable Object-Oriented Software Publisher Addison–Wesley Year 1995 16.7 16.8 Erich Gamma on GoF experience Design Patterns • II Pattern-driven design: JUnit framework Alexei Khorev Erich Gamma gave a series of interview to Aritma Developer on-line magazine in which he offered a valuable advice on the practice of design pattern. Here are some quotes: “You have to feel the pain of a design which has some problem. [Only then] you. . . appreciate a pattern. Like realizing your design isn’t flexible enough, a single change ripples through the entire system, you have to duplicate code, or the code is just getting more and complex. If you then apply a pattern in such a messy situation it can happen that the pain goes away and you feel good afterwards. It’s an eye opener to realize that oh, actually this pattern, factory or strategy, is a solution to my problem.” Design Patterns • II Alexei Khorev The famous testing framework JUnit was first developed by Kent Beck and E. Gamma during a trans-atlantic flight in 1997. The circumstances of this feat (“Never software industry owed so much to so fewer lines of code”) is the testimony of the great communicative benefits which DPs bring into software development: Software DPs The Design Pattern Bible JUnit case study GoF Catalog Kent and I were fluent in patterns when we designed JUnit. So of course, we’d say things like, "Hey, that’s composite." Composite is a pattern in JUnit. We also use template method. That’s a basic one. We have command. This is of course a key one. We started with test and said, "Oh, this is a command. Oh, this is a template." Because we were fluent in patterns, our conversation was going really fast, enabling a high-velocity design.” [The high-velocity design means Software DPs The Design Pattern Bible JUnit case study GoF Catalog just that — over six-seven hours at the high altitude.] “Do not start immediately throwing patterns into a design, but use them as you go and understand more of the problem.” (“20 out 23” case) On the difference with Alexander’s pattern language approach to design: “. . . when you follow Alexander’s patterns approach you follow the patterns in some sequence. We don’t prescribe a particular order. If you have a problem, we have the solution for that, but we don’t have the next step. We don’t give you hints on what to do next. Alexander is way more thorough in this regard.” “These days software is too complex. We can’t afford to speculate what else it should do. We need to really focus on what it needs. That’s why I like refactoring to patterns.” 16.9 Design of JUnit Design Patterns • II 16.10 JUnit Design – TestCase, Command Alexei Khorev Design Patterns • II Alexei Khorev The core of the JUnit testing technique is an object of the TestCase class. Standard testing techniques: Goals of JUnit (“mission statement”): • Create facility for automated tests for classes developers write Software DPs • It has to be a small (easy to learn) framework (flexible and adoptable) • Make created tests to retain their value over time; allow to Software DPs The Design Pattern Bible • print statements The Design Pattern Bible JUnit case study • debugger expressions JUnit case study GoF Catalog • test scripts combine tests and run them independently GoF Catalog To make manipulating tests easy, one has to make them objects. The test object has to execute a testing routine. The Command pattern deals with creating object for an operation and give it a method “execute” — this intent fits the goal perfectly. • Leverage existing tests to create new ones — provide setup or fixtures for automated selection of tests for run and creating an appropriate execution environment Design approach: public abstract class TestCase implements Test { private final String fName; 1 start with nothing (skip the SRS, ,) 2 apply patterns, one after another, until you have the architecture of the system public TestCase(String name) { fName = name; } 3 Refine and refactor the design public abstract void run() ... } 16.11 16.12 JUnit Design – run(), Template Design Patterns • II Design Patterns • II JUnit Design – TestResults Alexei Khorev Next, one has to define the place to put the fixture code and the test code itself. The common structure to all tests — they set up a test fixture, run some code against the fixture, check some results, and then clean up the fixture. Software DPs The Design Pattern Bible JUnit case study GoF Catalog Template Method intent addresses the problem: “Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.” The developer should to be able to separately consider how to write the fixture (set up and tear down) code and how to write the testing code. The execution of this sequence, however, will remain the same for all tests, no matter how the fixture code is written or how the testing code is written. Alexei Khorev After the test has run, one has to get a summary of what did and didn’t work. Because tests are expected to work, we only want to record the failures and a highly condensed summary of the successes. The Smalltalk pattern (but not GoF!), Collecting Parameter, fits the bill: when you need to collect results over several methods, you should add a parameter to the method and pass an object that will collect the results for you. We create a new object, TestResult, to collect the results of running tests. public class TestResult { protected int fRunTests; public void run() { setUp(); runTest(); tearDown(); ublic TestResult() { fRunTests= 0; } Software DPs The Design Pattern Bible JUnit case study GoF Catalog public void run(TestResult res) { res.startTest(this); setUp(); runTest(); tearDown(); } } } For details see JUnit A Cook’s Tour. 16.13 JUnit Design – TestCase, Adapter Design Patterns • II 16.14 JUnit Design – TestSuite, Composite Alexei Khorev We need an interface to generically run our tests, but all test cases are implemented as different methods in the same class. This avoids the unnecessary proliferation of classes. A given test case class may implement many different methods, each defining a single test case. Each test case has a descriptive name like testMethod1() etc. The test cases don’t conform to a simple command interface. Different instances of the same Command class need to be invoked with different methods. Therefore our next problem is make all the test cases look the same from the point of view of the invoker of the test. Software DPs The Design Pattern Bible Design Patterns • II Alexei Khorev We often need to run many tests. Our next challenge is to extend TestCase to run many different tests. This problem can be solved easily when the invoker of the tests doesn’t have to care about whether it runs one or many test cases. A popular pattern to pull out in such a situation is Composite: “Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.” Software DPs The Design Pattern Bible JUnit case study JUnit case study GoF Catalog GoF Catalog The Adapter pattern springs to mind: “Convert the interface of a class into another interface clients expect”. Two implementations are possible; a shorter one uses anonymous inner classes (this is an example of an idiom used for the pattern implementation): The Composite participants: • • • TestCase test= new MoneyTest("testMethod1") { protected void runTest() { testMethod1(); } } Component: declares the interface we want to use to interact with our tests Composite: implements this interface and maintains a collection of tests Leaf: represents a test case in a composition that conforms to the Component interface Another solution involves the Smalltalk pattern P S, which allows to use a single class which can be parameterized to perform different logic without requiring subclassing. 16.15 16.16 Design Patterns • II JUnit Design – the full picture Now we can put everything together: JUnit Design – Pattern Driven Design Alexei Khorev Alexei Khorev Let’s repeat the Pattern Driven path of the JUnit design: Software DPs Design Patterns • II Software DPs The Design Pattern Bible The Design Pattern Bible JUnit case study JUnit case study GoF Catalog GoF Catalog Very impressive! But in reality such a streamlined application of DPs during the design process is rare, and should not be relied upon. The JUnit design has very high “pattern density” — the ratio of DPs used to the number of classes. This is not typical: ordinary application need not be “pattern-dense”. Frameworks, on the other hand, usually have higher “pattern density” (and they are more difficult to design). 16.17 Design Patterns • II Catalog of Patterns: Three categories Alexei Khorev In the following lectures will shall discuss some of the GoF DPs. Creational Structural Software DPs • • • • • Abstract Factory Factory Method Builder Prototype Singleton • • • • • • • Adapter The Design Pattern Bible Bridge JUnit case study Composite GoF Catalog • • • • • Observer Decorator Façade Flyweight Proxy Behavioural • • • • • • Chain of Responsibility Command Interpreter Iterator Mediator State Strategy Template Method Visitor Memento 16.19 16.18
© Copyright 2024