Download presentation
Presentation is loading. Please wait.
Published byReinhardt Steinmann Modified over 6 years ago
1
LECTURE 17: Design Patterns Publisher-Subscriber
Ivan Marsic Rutgers University
2
Topics Software Design Patterns – What & Why
Example Pattern: Publisher-Subscriber (a.k.a. Observer) The key idea of design patterns is reducing the coupling (the degree of dependency) between client and server objects to a minimum through abstraction. Abstract interface defines and imposes only few restrictions on the service contract. Because these contracts are high-level and abstract they can be easily met and rarely need to be changed.
3
What Developers Do With Software
(besides development) Understand (existing software) Maintain (fix bugs) Upgrade (add new features)
4
The Power of Patterns CN NIB MAP PLE
5
The Power of Patterns
6
The Power of Patterns APPLE IBM CNN
7
The Power of Patterns
8
The Power of Patterns NIB CN MAP PLE APPLE IBM CNN
There are many other potential “patterns”, but these somehow succeeded to became widely known. A pattern is a noticeable regularity in the world or in a manmade design. The elements of a pattern repeat in a predictable manner.
9
Software Design Patterns
Design Patterns help anticipate software change Change is needed to keep up with the reality Change may be triggered by changing business environment or by deciding to refactor classes that are deemed potentially problematic e.g., using quality-screening metrics (see Chapter 4) Change may have bad consequences when there are unrelated reasons to change a software module/class Unrelated reasons are usually because of unrelated responsibilities Change in code implementing one responsibility can unintentionally lead to faults in code for another responsibility Another target is complex conditional logic (If-Then-Else statements, etc.)
10
What May Change & How What changes in real world are business rules customer requests changes in software [Change in-the-large] Change in-the-small: changes in object responsibilities towards other objects Number of responsibilities Data type, or method signature Business rules Conditions for provision/fulfillment of responsibilities/services Sometimes change (in-the-small) is regular (follows simple rules), such as new object state defined, or another object needs to be notified about something ═► “patterns”
11
Object Responsibilities (toward other objects)
Knowing something (memorization of data or object attributes) Doing something on its own (computation programmed in a “method”) Business rules for implementing business policies and procedures are a special case Calling methods on dependent objects (communication by sending messages) Calling constructor methods; this is a special case because the caller must know the appropriate parameters for initialization of the new object. Human-side benefits of design patterns that are difficult to quantify: easier memorization of design (“chunking”), understanding (fewer concepts to juggle at once), and communication to other team members
12
Example Patterns for Tackling Responsibilities
Delegating “knowing” and associated “doing” responsibilities to new objects (State) Delegating “calling” responsibilities (Command, Publisher-Subscriber) Delegating non-essential “doing” responsibilities (when the key doing responsibility is incrementally enhanced with loosely-related capabilities) (Decorator) Design patterns provide systematic, tried-and- tested, heuristics for subdividing and refining object responsibilities, instead of arbitrary, ad-hoc solutions.
13
Key Issues When a pattern is needed/applicable?
How to measure if a pattern-based solution is better? When to avoid patterns because may make things worse? All of the above should be answered by comparing object responsibilities before/after a pattern is applied
14
Publisher-Subscriber Pattern
A.k.a. “Observer” Disassociates unrelated responsibilities Decrease coupling, increase cohesion Helps simplify/remove complex conditional logic and allow seamless future adding of new cases Based on “Indirect Communication” Like many other design patterns ? T F
15
Request- vs. Event-Based Comm.
Issues: Who creates the client-server dependency Who decides when to call the dependency (server/doer) Who is responsible for code changes or new dependencies Client knows who to call, when, and with what parameters: Doer (server) keeps asking and receives information when available: Doer (in advance of need) expresses interest in information and waits to be notified when available: query (1) order: subscribe() Client order Server Info Src Doer Info Src Doer info The communication is “indirect” in the sense that the relationship between the client and server objects is loose—they know very little about each other decoupling. Order: doSomething( info ) Request: getInfo() (2) event( info ) (a) (b) (c) (tight coupling) (loose coupling) Direct Communication Indirect Comm. Directly ordering the server what to do or demanding information from a source Indirectly notifying (via event dispatch) the registered doers to do their work (unknown to the event publisher
16
“Before” == A Scenario Suitable for Applying the Pub-Sub Pattern
Event Detector DoerType1 DoerType2 … … … detectEvent() tellMeWhatToDo() … tellMeWhatToDo() … … Doer1.tellMeWhatToDo() Doer2.tellMeWhatToDo() … … … … Responsibilities Doing: Detect events Calling dependencies: Tell Doer-1 what to do Tell Doer-2 what to do unrelated! unrelated reasons to change the Event Detector: When event detection needs to change or extend When new doer types need to be told what to do
17
“After” == Responsibilities After Applying the Pub-Sub Pattern
Publisher Subscriber subscribers : List … … detectEvent() receive(Event) … … subscriber.receive(Event) … … The Publisher “knows” generic/abstract Subscribers, which is much less to know than their concrete classes. For example, if we are told that a Java object is of type java.lang.Object, this reveals almost nothing. Narrowing down object’s type to the specific class requires more and more knowledge about it. Another example: just knowing that when one has toothache (“event”), just call (any) dentist (“doer”), instead of having to call a specific dentist (described by name, contact information, working hours, etc.). When a new type of Subscriber is implemented, only its code needs to be written, but the existing code (including the Publisher) does not need to change. An object of this new subscriber type will be added to the Publisher’s list of Subscribers. … Unrelated responsibilities of the Event Detector (now Publisher) are dissociated: When event detection needs to change or extend change Publisher When new doer types need to be added add an new Subscriber type (Subscribers need not be told what to do – they know what to do when a given event occurs!
18
Labor Division (1) developer X developer Y Before: Class A (and developer X) is affected by anything related to class B Class A B Who develops developer X developer Y Who knows which methods of B to call, when, how — Who makes changes when classes of type B modified or new sub-types added
19
Labor Division (2) After: Separation of developers’ duties
developer X developer Y After: Separation of developers’ duties Developer Y is completely responsible for class B Class A B Who develops developer X developer Y Who knows which methods of B to call, when, how — Who makes changes when classes of type B modified or new sub-types added
20
Publisher-Subscriber Pattern
Focused on detecting & dispatching events The focus in on the “Publisher” object and the “environment” that it is observing for “events” Example key events in safe home access case study: Entered key is valid Entered key is invalid Instead of making decisions & issuing orders to Doers/Subscribers Notify doers/subscribers when the information/event of their interest becomes available, without knowing what for or how this information will be used Works in both directions: Client-side events (user interaction by the initiating actor) Server-side events (participating-actors/“environment” monitoring)
21
Publisher-Subscriber Pattern
Controller (receives key-code) Key Checker (checks key validity, i.e., classifies: valid/invalid) Publishes the classification result to “subscribers” Lock Control Light Control Alarm Control Do the work based on the received event SUBSCRIBERS ( Assumed, during initialization: Subscribers subscribe for Events ≡ dependency graph construction )
22
Pub-Sub Pattern (a) (b)
23
Unlock Use Case From Chapter 2
This IF-THEN-ELSE must be changed when a new device type is introduced We built an undue complexity into the Controller while striving to preserve high degree of specialization for all other objects. [[ Note: GUI aspects are treated separately. ]]
24
Refactoring to Publisher-Subscriber
Conditional logic is decided here, at design time, instead of run time 1. Subscribe for appropriate events Event type Subscriber Pub Sub-1 keyIsValid LockCtrl, LightCtrl Sub-n keyIsInvalid AlarmCtrl itIsDarkInside LightCtrl . Pub Sub-1 Sub-n No need to consider the “appropriateness” of calling the “servers” 2. When event occurs: (a) Detect occurrence: keyIsValid / keyIsInvalid (b) Notify only the subscribers for the detected event class Design-time decisions are better than runtime decisions, because they can be easier checked if they “work” (before the product is developed & deployed) If a new device is added -- just write a new class; NO modification of the Publisher! Complexity due to decision making cannot disappear; It is moved to the design stage, which is early and easier to handle. The designer’s choice is then hard-coded, instead of checking runtime conditions.
25
Pub-Sub: Unlock Use Case
This IF-THEN-ELSE needs NOT be changed when a new device type is introduced This class’s developer is not involved in new subscriber development & deployment
26
From Hub-and-Spokes (Star) to Token Passing (Cascading) Architecture
Before: After: Pub-Sub reduced the class coupling: (dependency on an abstract type implies reduced coupling)
27
Design Patterns: Dependency Injection
Custodian 1: initialize the pattern Instantiation of the Design Pattern dependency injection 2: hand over the initialized pattern Client collection of objects working to provide service 3: ask for service Alternative names for Custodian are Assembler or Initializer
28
Pub-Sub: Initialization
29
Practical Issues Do not design for patterns first
Reaching any kind of solution is the priority; solution optimization should be secondary Refactor the initial solution to patterns E.g., to reduce the complexity of the program’s conditional logic Important to achieve a tradeoff between rapidly progressing towards the system completion versus perfecting the existing work Uncritical use of patterns may yield worse solutions!
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.