Presentation is loading. Please wait.

Presentation is loading. Please wait.

Dennis Mancl dennis.mancl@alcatel-lucent.com November 2013 Design Patterns Dennis Mancl dennis.mancl@alcatel-lucent.com November 2013.

Similar presentations


Presentation on theme: "Dennis Mancl dennis.mancl@alcatel-lucent.com November 2013 Design Patterns Dennis Mancl dennis.mancl@alcatel-lucent.com November 2013."— Presentation transcript:

1 Dennis Mancl dennis.mancl@alcatel-lucent.com November 2013
Design Patterns Dennis Mancl November 2013

2 Design Patterns Outline
What is a pattern? The Design Patterns Book One example pattern: Singleton Patterns versus Idioms Some useful software design patterns Choosing algorithms with Strategy Wrapping with Facade objects, interfacing with Proxies Observer Patterns for: Analysis, Architecture, Enterprise applications PDF file of this presentation:

3 What is a pattern? A pattern is a solution to a problem in a context
Name: Information Expert Problem: How to decide which class or object to assign responsibilities to? Context: A responsibility usually requires some information or data for its fulfillment – information about other objects, an object’s own state, the world around an object, and so on. Solution: Assign a responsibility to the class that has the information needed to fulfill it. (from Applying UML and Patterns, third edition, Craig Larman) A pattern is a solution to a problem in a context The problem and context come from some domain (software development, project management, …) The problem and context contain some “unresolved forces” that need to be addressed. The solution is a proposed way to resolve the problem Question: Where to put the “Print Shipping Label” operation? CustomerOrder Order Id Customer Id Billing Address Shipping Address Items To Ship Add New Item Customer Customer Id Customer Name Default Billing Address My Shipping Addresses Send Latest Catalog Note: in the example, we are looking for a solution to a software design problem. The context is an existing partial design. Also see the description of “Pattern Language” in the Wikipedia --

4 What is a pattern? Patterns are used to capture knowledge and experience – for example, what to think about when making design choices Patterns are not a cookbook – the pattern doesn’t give you an automatic answer Each pattern might trigger others Name: Loose Interfaces Problem: To avoid development bottlenecks, we need to be able to limit the effect that one team’s work will have on another. Context: Interfaces need to be somewhat flexible if the teams are working quickly. Requirements may be changing rapidly, and it may be difficult to communicate between geographically distributed subteams. Solution: Limit the number of explicit, static interfaces. Define larger-grained interfaces that allow developers to code against interfaces defined early, but that do not overly constrain functionality. Consider using the Hierarchy of Factories pattern. (from Organizational Patterns of Agile Software Development, Coplien and Harrison)

5 Patterns in non-software domains
Name: ChocolateChipRatio Context: You are baking chocolate chip cookies in small batches for family and friends Consider these patterns first: SugarRatio, FlourRatio, EggRatio Problem: Determine the optimum ratio of chocolate chips to cookie dough Solution: Observe that most people consider chocolate to be the best part of the chocolate chip cookie. Also observe that too much chocolate may prevent the cookie from holding together, decreasing its appeal. Since you are cooking in small batches, cost is not a consideration. Therefore, use the maximum amount of chocolate chips that results in a sturdy cookie. Consider next: WalnutRatio or CookingTime or FreezingMethod (from Wikipedia: Not enough sugar = cookies taste more like bread Too much sugar = cookies fall apart Not enough egg = cookies are too flat and dense Too much egg = cookies have a thick outer crust Use the recipe on the package of your favorite chocolate chips This example shows that there are multiple patterns in a Cookie pattern language, but this pattern focuses on one of the critical characteristics of good chocolate chip cookies – getting the amount of chocolate right. Personally, I always follow the Nestle recipe, which is the recipe on the bag of Nestle’s toll house morsels – their ratio is just about right to satisfy the competing forces of good taste and solid cookie architecture.

6 Software patterns The first “Object Oriented Design Patterns” are found in the book Design Patterns by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (known as “Gang of 4” or “GOF”) 23 patterns: three categories (Creational, Structural, Behavioral) The patterns are for software problems Examples in C++ and Smalltalk The patterns also apply to other languages (Java, Visual Basic, Perl) The Design Patterns book first appeared in fall The book was a big hit at the OOPSLA conference (sponsored by ACM SIGPLAN) – the Addison-Wesley booth was completely sold out of copies of the book. Many of the other books on design patterns make reference to these 23 patterns – either by repeating them, extending them, or discussing some specializations of the patterns for certain contexts.

7 More books

8 Singleton Pattern Name: Singleton
Problem: We need to restrict the creation of new objects for a particular class: only one instance. Context: Other objects in the design need a single point of access to use the object. Solution: Define a “static member function” within the class that returns a pointer (or reference) to the Singleton object. The static member function will create the object the first time it is called. All constructors are made private to prevent other objects from being created. Singleton is the simplest pattern in the book. It is relatively easy to implement in C++. The access to the object is controlled: by putting the “instance” in the private section of the class, any function outside of the class can’t directly access the object – the access must be done through the advertised interface (the getInstance() static member function). Note: The actual “construction” of the singleton object is deferred until the first time the application tries to access it – see the next page.

9 More about Singleton Simple version of Singleton (in C++, without multi-thread support): MySingletonClass – instance : MySingletonClass * other attributes … + getInstance() : MySingletonClass * – MySingletonClass() other operations … underline means static data member if (instance == 0) { instance = new MySingletonClass(); } return instance; Access the Singleton like this: MySingletonClass::instance() Different implementations of the Singleton pattern for Java, multithreaded support, allocation in special memory, and so on. Suppose you need a Singleton in a multi-threaded context. In that case, the instance == 0 test plus the call to the new operator in the getInstance() function is a “critical section”. If two threads try to do this operation at the same time, the results are unpredictable. You *might* wind up with two instances of the singleton object. A solution to this problem can be found in Design Patterns Explained by Alan Shalloway and James R. Trott. if (instance == 0) { lock.acquire(); instance = new MySingletonClass(); } lock.release(); return instance; This is called the “double checked locking idiom” – and it is widely used in languages like C and C++. Note: it doesn’t work in Java – and the reasons are somewhat complicated, See for more details.

10 More about Singleton Simple version of Singleton (in Java, with multi-thread support): // return the instance // in the “holder” class return MySingletonHolder.instance; MySingletonClass attributes … + getInstance() : MySingletonClass – MySingletonClass() other operations … // need a helper class to ensure the // creation is thread-safe private static class MySingletonHolder { private static final MySingletonClass instance = new MySingletonClass(); } 1 MySingletonHolder – instance : MySingletonClass Why is this version more complex? If you use the C++ method of creating the singleton object, you might get two threads requesting the object at the same time… this could possibly create two objects. See -- this uses Java’s “initialization on demand” feature.

11 Patterns and Idioms What have we done? We have used a “design trick” that solves a specific problem Some standard design tricks are called “idioms” they tend to be small, tricky, and language specific example: virtual destructors in C++ example: anonymous inner classes in Java How are patterns different from idioms? Patterns are more about design Singleton is useful in Java, Smalltalk, Visual Basic, Perl, … different “realizations” of patterns in different languages There is some overlap between idioms and design patterns. But for the most part, idioms are aimed at more concrete circumstances, and they tend to be written as “rules”: define the copy constructor, assignment operator, and destructor for C++ classes that manage dynamic resources (for example, classes that allocate dynamic memory regions, open file descriptors, or open databases) always define a virtual destructor for C++ classes that contain other virtual functions never return a reference to an object on the stack in a C++ function

12 Patterns in the Design Patterns book
23 Design Patterns: three categories Creational Structural Behavioral Abstract Factory Adapter Chain of Responsibility Observer Builder Bridge Command State Factory Method Composite Interpreter Strategy Prototype Decorator Iterator Template Method Singleton Facade Mediator Visitor Flyweight Memento Proxy This collection of software design patterns is widely used in many areas of design. It is very useful to know these patters – you can save some design effort, and it gives you a good way to discuss design issues with others.

13 Sources of information
So, you want to learn how to use these design patterns to make your OO designs better Where to look to learn more: the book A Learning Guide to Design Patterns ( Pattern Stories Wiki ( other books: Pattern-Oriented Software Architecture by Frank Buschmann et. al. Design Patterns Java Workbook by Steven John Metsker Refactoring to Patterns by Joshua Kerievsky Design Patterns Explained by Alan Shalloway and James R. Trott New books, articles, and courses on patterns are being written every day.

14 Why learn the Design Patterns?
Your own designs will improve borrowing well-tested ideas pattern descriptions contain some analysis of tradeoffs You will be able to describe complex design ideas to others assuming that they also know the same patterns You can use patterns to “refactor” existing code refactoring is improving the structure of existing code without adding new functionality some techniques for transforming and adapting legacy code are based on design patterns The Refactoring to Patterns book by Joshua Kerievsky gives some good ideas of how to improve existing designs by adding some design patterns.

15 Strategy Pattern Problem: An application needs to use a family of similar algorithms the selection of which algorithm depends on the client making the request or some characteristics in the data Context: Two possible situations: you have a group of classes that contain the same data, but they have different behavior (functions); or you have a class that defines many behaviors, and these behaviors appear as multiple conditional statements in the operations of the class Solution: Define a family of algorithms, encapsulate each one, and make them interchangeable there will be a family of classes, one per algorithm variation Strategy pattern is a design idea that is used to help combine several related algorithms into a single structure. The idea is to turn a group of algorithms into a single interface supporting multiple variations. The variations can be selected at run time.

16 Example of Strategy Internet-based business
When a customer accesses the home page, you want to present a few products that the customer might be interested in Web presentation program uses one or more “recommendation engines” commercial off the shelf software uses customer survey information or previous purchase history to make a recommendation Might use multiple engines Might also want to highlight special sale items Customer getAdvisor() getRecommended() Advisor <<abstract>> recommend(Customer) : ProductSet call one of the recommendation engines GroupAdvisor recommend(Customer) ItemAdvisor recommend(Customer) This example is adapted from the book Design Patterns Java Workbook by Steven John Metsker (chapter 23). The book walks through a Java implementation of this example. call a promotion-based selector PromotionAdvisor recommend(Customer)

17 Consequences of Strategy
Benefits It is easy to add new variations of the algorithm The modules that use the Strategy do not need to be aware of changes to the Strategy implementations Things to watch out for There will be some communications overhead between the Context objects and the Strategy objects Using the Strategy pattern increases the number of objects in the system Strategy creates a simple and flexible design structure. New strategy classes can be added to an existing design – to implement new variations of some of the system’s features.

18 Facade Pattern Problem: The application needs a simple interface to a complex subsystem the subsystem might have been written by someone else you don’t want the entire development team to go back to the subsystem documentation with lots of questions Context: it is important to control the dependencies between the application and the complex subsystem – you want to reduce the effort to maintain the system Solution: Define a single Facade class the Facade class has knowledge of the internal details of the subsystem, but the Facade class provides a simple to use interface for the application each Facade public function might call many subsystem operations Facade is one of the most widely used patterns – most software developers have used it, even if they didn’t know what it was called. Some folks call a Facade a “wrapper”.

19 Facade diagram Facade class
A Facade class wraps a bunch of operations on other classes (or a bunch of legacy code operations) into a convenient package application Facade class pointers to other data objects within a subsystem get_val1() build_trans2() do_trans3() commit_trans4() scanner database interface application calls some of the Facade class operations parser formatter the Facade accesses some of the internals of a complex subsystem to implement its operations A Facade class has some interesting internal structure: the data section of a Facade class is usually more than just a simple pointer the implementation of the Facade member functions might need to interact with many classes and/or functions in the subsystem that it is hiding The Facade pattern is the most commonly used pattern for reusing or extending a non-OO legacy subsystem.

20 Planning a Facade Part of the OO design process: create a simplified model of the classes in the overall system using CRC cards (informal technique using index cards, one card per class) using UML Class Diagrams Look for a group of classes that collaborate closely together: call them a “subsystem” Try to “put the subsystem behind a wall” – define a single interface class that defines an API for the subsystem Facade is a good pattern to use in the design of a large and complex system. You can build the system as a collection of multi-class packages – each package will have one or two of its own Facade classes that the other packages that other packages are allowed to use.

21 Proxy example A Proxy object is a “stand-in” for an object that might be: located on another machine (example: CORBA objects, Java RMI) or it might be large and complicated, so you want to defer building it or it might require a special access method (to check the users’ permissions) client application network ORB (server) CORBA IDL stubs IDL skeletons Interface Repository Object Implementations CORBA example requests responses Stub objects have full public interface, but no data. They just push a message over to the server. Generated by a tool Developers fill in details In the Proxy pattern, the Proxy object doesn’t necessarily have a simple way to access the information in the class that stands behind the Proxy object: it might involve a complex communication protocol instead of just following a pointer. For example, CORBA implementations usually generate client-side “stub” classes (which are simple Proxy classes) directly from an IDL specification of a class). The operations of these stub classes will send messages to the “real” object implementations that live on a server machine. The Object Request Broker (ORB) on the client machine knows how to parse the messages from stub classes. The ORB will pick out the right operations from the CORBA-generated code (the IDL skeletons and Interface Repository) and the user-constructed code (the Object Implementations) to return the right information to the client. Examples of non-distributed-object related Proxy objects include: bitmap objects (creating or downloading a bitmap might be deferred until the application knows what section of the bitmap is needed) sparse matrix objects (you might not compute all elements of an array immediately)

22 Proxy pattern Problem: The application needs to operate on a distant object Context: Need a placeholder for an object if the actual object is far away (on another computer or on a disk), the placeholder should be in the local address space Solution: Define a Proxy class The Proxy class will have the same public interface as the real class, and when a Proxy operation is called, the internals of a Proxy object will arrange for the same function to be called on a real object You can “pretend you are calling the real object” Proxy might send interprocess or intermachine messages Proxy might resurrect an object that has been written to disk Proxy might acquire special permissions to access a protected real object Proxy classes seem like magic. You call a proxy object’s operation, and through some special magic messages are sent behind the scenes to update databases, parts of a distant object are retrieved with a series of data retrieval messages or a protected object is through the creation of an access session that automatically goes through a login and password process

23 How to tell the difference?
How can I tell which one I am using? Facade or Proxy? Both patterns are separating the implementation details from an abstract interface But the intent is different for each pattern Facade: the application wants to use services of an entire subsystem or package (usually tens or hundreds of objects in the subsystem) Facade is also a common way to interface with non-OO modules Proxy provides convenient access to an object – the object might be on disk, in another process, on another computer “Intent” is a very important idea in patterns – you always want to ask the question “what are we trying to do?”

24 Observer – a useful design technique
Observer pattern always has at least 2 classes: Subject and Observer TemperatureSensor – maintains information about the current temperature TempReportWebPage – displays temperature value on a web page Each temperature value might appear on multiple pages Update each page when the TemperatureSensor changes state temp: TemperatureSensor call Update() on each page page1: TempReportWebPage report_URL : string Update page2: TempReportWebPage page3: TempReportWebPage Observer is useful because there is often a separation between state and behavior in certain designs. If an object’s state is changed, there may be several objects that expect to be informed of that state change. Note that in this case, the “action to be taken” on a state change of TemperatureSensor usually belongs to the “observer” class (TempReportWebPage). The TemperatureSensor class doesn’t know anything about web pages – TemperatureSensor only keeps a list of other objects that depend on the state of the sensor. (Note: In the example on this slide, the TemperatureSensor object is responsible for updating multiple web pages. This is a common occurrence – you might have a system that records temperatures from various reporting stations, but the screens to “view” the data might be interested in different subsets of the reporting stations… all of the airports in a particular state, all airports serving a metropolitan area, all airports that have more than 500 flights per day, and so on.)

25 Simple class diagram for Observer
In the Observer Pattern: there are links between two kinds of concrete classes subjects and observers Each observer object (such as TempReportWebPage) needs to register by calling the Attach() operation on a subject object (like TemperatureSensor) Each observer object will have its Update() operation called whenever its subject changes state ConcreteSubject subjectState GetState() ModifyState() Attach(Observer) Detach(Observer) Notify() observers ConcreteObserver observerState Update() 1 0..* observerState = subject->GetState(); for all o in observers { o ->Update() } subjectState = newState; Notify(); Observers (TempReportWebPage objects) NJIT: 55。 This is a simplified version of the “general picture” of the Observer pattern. This pattern can be made more general by adding abstract classes… see the next page. TCNJ: 57。

26 Complete class diagram for Observer
Observer is an abstract interface that each ConcreteObserver must implement (must implement an Update() function) Observer objects still register by calling the Attach() operation on a ConcreteSubject object Each ConcreteObserver object will have its Update() operation called whenever its ConcreteSubject changes state Subject Attach(Observer) Detach(Observer) Notify() observers Observer Update() 1 0..* for all o in observers { o ->Update() } ConcreteSubject subjectState GetState() ConcreteObserver observerState Update() return subjectState observerState = subject->GetState(); This is the “general picture” of the Observer pattern (from the Design Patterns book). It has been generalized: the ConcreteSubject gets the “notification” functionality from its base class Subject. Within the implementation of the ConcreteSubject class, there will be one or more calls to the Subject::Notify() function – whenever the Subject determines that the Observers need to be notified. Observer is an “abstract class” – it defines the interface that all ConcreteObservers must implement.

27 Why update the Observer objects?
In the Observer Pattern, there are some objects that “care about” the state changes within other objects The ConcreteObserver::Update() function might do these things: repaint a user interface check for exceeding thresholds So the ConcreteObserver is a place to put operations that might clutter up a domain class example: any “View” class Or the ConcreteObserver is a place to put a command handler for a user interface class button and menu handlers can be implemented as Observers of GUI objects Observer objects are “reactive” object – they spend a lot of time “waiting for something to happen”. This is a style of programming that is very different from traditional “algorithm” style programming. A reactive application doesn’t always have a single “controlling” function – the main program may just create a bunch of Subject and Observer objects, then “start them up and let them interact.”

28 Motivation for Observer
An early OO user interface architecture: Model-View- Controller A model, is an object representing data (often data about an object in the real world) A view is some form of visualization of the state of the model. A controller offers facilities for the user to change the state of the model (clicking on buttons, sliding a slider, typing in a text box, etc.) Some elements within the View observe the Model if the Model changes state, then the View may need to update its objects and pass the changes to the user interface implementation The Model observes the Controller after the Controller accepts command input from the user, it needs to notify the Model to update its state View A 5 Z Model event proc1 event proc2 Model-View-Controller (MVC) is a classic “separation of concerns” within a design. It is possible to implement this with a single Model class, a single View class, and a single Controller class, or with each part of the architecture implemented using a number of related classes. A good concise explanation of Model-View-Controller can be found on the OO Tips website: See also Note that there are some frameworks that implement a variation of MVC: Document-View. This combines the Controller and the View into a single Document class. One popular implementation of the Document-View architecture is the Microsoft Foundation Classes (MFC). Controller

29 Observer implementation
A Subject class will usually keep a linked list of pointers to its registered Observers linked list: multiple View objects might observe the same Model, and the linked list makes it easier when one of the middle objects wants to Detach (to stop receiving notifications) each pointer in the list is of type Observer* (abstract type defining the Update() operation), because the concrete types for different observers is often quite different Is this necessary? No. In some cases, you might know that all observers have the same type. Then the list might declared to contain ConcreteObserver* pointers. In fact, the linked list could be replaced by a fixed sized pointer table or a dynamic sized array (std::vector in C++) – especially if the set of observers is relatively static In the implementation of Observer objects, there is always some kind of “indirection” going on. In traditional C and C++ programming, this is usually done using pointers. There are many modern “application frameworks” that have Observers built in – such as Java’s event model.

30 Consequences of Observer
Benefits The coupling between the Subject classes and the Observer classes is very minimal Within the implementation of the Subject class, the calls to the Update function don’t need to specify a “receiver” – the recipients are automatically managed within the pattern Things to watch out for Performance: Observer objects are usually unaware of the existence of other Observer objects, so there can sometimes be a very long chain of updates caused by a modification to one Subject Observers always create some extra complexity – it is inevitable because of the separation of functionality between the Subjects and Observers.

31 Other notes about Patterns
Who invents the patterns? No one “invents” them – Patterns are “discovered” The patterns summarize some of the design approaches that work well in a particular context If you use one of the standard design patterns – you increase the likelihood that someone else will understand your design Patterns: a set of standard “design vocabulary” How often do these problems occur? hmmm… which popular web services might use the Observer pattern? (think social networking…)

32 Analysis patterns Analysis patterns are a set of patterns that are used in doing the initial problem analysis: They help answer the question “what objects should I define in my system?” The Quantity pattern is from the book Analysis Patterns by Martin Fowler Recording measurements and manipulating results might be error-prone Each value really should be recorded with its units: A Money object will have both a number and an identifier to say which currency: [19.95, “US Dollars”]; [700, “Euros”]; [100, “Yuan”] Length and weight also need units: [100, “miles”]; [15.5, “kg”] Analysis Patterns are just like Design Patterns – they are simple solutions to recurring problems. Each Analysis Pattern has problem and a context, and it identifies certain common solutions.

33 Justification for the Quantity pattern
A frequent problem – someone tries to perform an invalid operation on two different types of quantities: adding apples to oranges, people to money, dates to time intervals conversion mistakes: adding dollars to euros, inches to feet performing an average of a mixed bag of objects (this should never be legal) Using explicit units in the design makes it easier for someone else to understand the software later what does this number mean?? The Quantity pattern is very good for building applications that will have a long lifetime – because some of the most important “documentation” is built into the application. The meaning of a Quantity object is much clearer because it contains both the value and its units.

34 Architecture patterns
You can save a lot of design work by reusing some well-tested architectures: Patterns of Software Architecture: the first book on “architecture patterns” An example: Client-Dispatcher-Server Problem: You are designing a “video on demand” service Your customers can order different movies, and you have video servers in the central office that can play the movies When requests come in, the system needs to decide which server will handle each request There is a standard “division of responsibilities” in the design Distribution of responsibilities – this is a big design problem in large systems.

35 Client-Dispatcher-Server example
initial stimulus send_request(s) A Customer wants a particular Service, so Customer::send_request() is called. This will invoke the Service (it calls the Service::receive_request() function for a specific Service object). The Service object wants either to create a new ServiceNode or (more likely) to assign an existing ServiceNode to the Customer. The ServiceNodeAssigner class makes the decision about which ServiceNode to assign and configure. c: Customer 1: receive_request(c) s: Service 1.1: sn = obtain_channel(c) :ServiceNode Assigner 1.1.2: add NodeUser(c) 1.1.1*: get Capacity_and_Load() sn: ServiceNode Benefits: easy to add new service nodes customer doesn’t need to know where servers are located 1.1.4: configure Service() Each class in this diagram has a different purpose: Customer is a class that interfaces to the system’s users ServiceNode is a class that controls the system’s hardware and services Service is a class that encapsulates each of the work items that can be requested by Customers and managed by a ServiceNode ServiceNodeAssigner is a class that helps the system make good scheduling decisions

36 Client-Dispatcher-Server example
This design uses the “Client-Dispatcher-Server” pattern: three classes share responsibility for managing communication the Server provides a set of services, but it initially registers itself with the Dispatcher the Client will invoke the services provided by one or more Servers, but it will contact the Dispatcher each time it needs a service (to help it find the right Server) the Dispatcher tracks the Servers and responds to the Clients that are trying to locate a service The design is relatively clean: Clients have a single logical point of contact the Servers don’t need to know anything about the assignment policy service nodes can be reconfigured to offer new services within the framework

37 Enterprise Architecture Patterns
Martin Fowler’s excellent book: Patterns of Enterprise Application Architecture Enterprise Applications – software that uses databases (concurrent access to persistent data) How do you write a Java application to manipulate and display data from a database? How can you make it easier to modify the application to meet new needs without breaking the existing code? Some answers: use layers, build facades, define proxies, encapsulate data records, and encapsulate transactions Enterprise Applications are business-related systems that work in the world of databases and transactions. There are a large number of standard design patterns that can help in the construction of robust applications: Communications patterns User interface management patterns Patterns that structure the interaction with the database

38 Example enterprise patterns
How do I control the formatting of my Web pages? If I want to edit the page and put hooks in for dynamic data? – use Template View (HTML page with markers for varying information) The page is a transform of domain data? – use Transform View If I need to make general “look-and-feel” changes across my web site? – use Two Step View Multiple appearances for the same logical screen? – use Two Step View How do I interact with the database? If I have a domain model that corresponds to the database tables? – use Active Record (encapsulating database access and domain logic into one class) If I have a rich domain model? – use Data Mapper If I’m using a Table Module? – use Table Data Gateway These examples are taken from the “Cheat Sheet” in the back cover of the Martin Fowler Patterns of Enterprise Application Architecture book.

39 Summary Design Patterns: an important set of object oriented design concepts these patterns are useful in many applications every pattern has a documented set of “Consequences” Some useful sources on design patterns: PDF file of this presentation:


Download ppt "Dennis Mancl dennis.mancl@alcatel-lucent.com November 2013 Design Patterns Dennis Mancl dennis.mancl@alcatel-lucent.com November 2013."

Similar presentations


Ads by Google