Flashcards
Observer Pattern
Cards in this deck (30)
- 1Q: Do I always have to implement my application first, see where things are changing, and then go back and separate & encapsulate those things?A: Not always; often when you are designing an application, you anticipate those areas that are going to vary and then go ahead and build the flexibility to deal with it into your code. You’ll find that the principles and patterns can be applied at any stage of the development lifecycle
- 2Q: Do I always have to implement my application first, see where things are changing, and then go back and separate & encapsulate those things?A: Not always; often when you are designing an application, you anticipate those areas that are going to vary and then go ahead and build the flexibility to deal with it into your code. You’ll find that the principles and patterns can be applied at any stage of the development lifecycle.
- 3Q: Should we make Duck an interface too?A: Not in this case. As you’ll see once we’ve got everything hooked together, we do benefit by having Duck not be an interface and having specific ducks, like MallardDuck, inherit common properties and methods. Now that we’ve removed what varies from the Duck inheritance, we get the benefits of this structure without the problems
- 4Q: It feels a little weird to have a class that’s just a behavior. Aren’t classes supposed to represent things? Aren’t classes supposed to have both state AND behavior?A: In an OO system, yes, classes represent things that generally have both state (instance variables) and methods. And in this case, the thing happens to be a behavior. But even a behavior can still have state and methods; a flying behavior might have instance variables representing the attributes for the flying (wing beats per minute, max altitude and speed, etc.) behavior.
- 5Q: If design patterns are so great, why can’t someone build a library of them so I don’t have to?A: Design patterns are higher level than libraries. Design patterns tell us how to structure classes and objects to solve certain problems and it is our job to adapt those designs to fit our particular application.
- 6Q: Aren’t libraries and frameworks also design patterns?A: Frameworks and libraries are not design patterns; they provide specific implementations that we link into our code. Sometimes, however, libraries and frameworks make use of design patterns in their implementations. That’s great, because once you understand design patterns, you’ll more quickly understand APIs that are structured around design patterns.
- 7Q: So, there are no libraries of design patterns?A: No, but you will learn later about pattern catalogs with lists of patterns that you can apply to your applications.
- 8Q: What does this have to do with one-to-many relationships?A: With the Observer pattern, the Subject is the object that contains the state and controls it. So, there is ONE subject with state. The observers, on the other hand, use the state, even if they don’t own it. There are many observers and they rely on the Subject to tell them when its state changes. So there is a relationship between the ONE Subject to the MANY Observers.
- 9Q: How does dependence come into this?A: Because the subject is the sole owner of that data, the observers are dependent on the subject to update them when the data changes. This leads to a cleaner OO design than allowing many objects to control the same data.
- 10Q: Is update() the best place to call display?A: In this simple example it made sense to call display() when the values changed. However, you are right, there are much better ways to design the way the data gets displayed. We are going to see this when we get to the model-view-controller pattern.
- 11Q: Why did you store a reference to the Subject? It doesn’t look like you use it again after the constructor?A: True, but in the future we may want to un-register ourselves as an observer and it would be handy to already have a reference to the subject.
- 12Open for extension and closed for modification? That sounds very contradictory. How can a design be both?That’s a very good question. It certainly sounds contradictory at first. After all, the less modifiable something is, the harder it is to extend, right? As it turns out, though, there are some clever OO techniques for allowing systems to be extended, even if we can’t change the underlying code. Think about the Observer Pattern (in Chapter 2)... by adding new Observers, we can extend the Subject at any time, without adding code to the Subject. You’ll see quite a few more ways of extending behavior with other OO design techniques.
- 13Okay, I understand Observable, but how do I generally design something to be extensible, yet closed for modification?Many of the patterns give us time tested designs that protect your code from being modified by supplying a means of extension. In this chapter you’ll see a good example of using the Decorator pattern to follow the OpenClosed principle
- 14How can I make every part of my design follow the Open-Closed Principle?Usually, you can’t. Making OO design flexible and open to extension without the modification of existing code takes time and effort. In general, we don’t have the luxury of tying down every part of our designs (and it would probably be wasteful). Following the Open-Closed Principle usually introduces new levels of abstraction, which adds complexity to our code. You want to concentrate on those areas that are most likely to change in your designs and apply the principles there.
- 15How do I know which areas of change are more important?That is partly a matter of experience in designing OO systems and also a matter of knowing the domain you are working in. Looking at other examples will help you learn to identify areas of change in your own designs.
- 16I’m a little worried about code that might test for a specfic concrete component – say, HouseBlend – and do something, like issue a discount. Once I’ve wrapped the HouseBlend with decorators, this isn’t going to work anymore.That is exactly right. If you have code that relies on the concrete component’s type, decorators will break that code. As long as you only write code against the abstract component type, the use of decorators will remain transparent to your code. However, once you start writing code against concrete components, you’ll want to rethink your application design and your use of decorators.
- 17Wouldn’t it be easy for some client of a beverage to end up with a decorator that isn’t the outermost decorator? Like if I had a DarkRoast with Mocha, Soy, and Whip, it would be easy to write code that somehow ended up with a reference to Soy instead of Whip, which means it would not include Whip in the order.You could certainly argue that you have to manage more objects with the Decorator Pattern and so there is an increased chance that coding errors will introduce the kinds of problems you suggest. However, decorators are typically created by using other patterns like Factory and Builder. Once we’ve covered these patterns, you’ll see that the creation of the concrete component with its decorator is “well encapsulated” and doesn’t lead to these kinds of problems
- 18Can decorators know about the other decorations in the chain? Say, I wanted my getDecription() method to print “Whip, Double Mocha” instead of “Mocha, Whip, Mocha”? That would require that my outermost decorator know all the decorators it is wrapping.Decorators are meant to add behavior to the object they wrap. When you need to peek at multiple layers into the decorator chain, you are starting to push the decorator beyond its true intent. Nevertheless, such things are possible. Imagine a CondimentPrettyPrint decorator that parses the final decription and can print “Mocha, Whip, Mocha” as “Whip, Double Mocha.” Note that getDecription() could return an ArrayList of descriptions to make this easier
- 19Q: What’s the advantage of the Factory Method Pattern when you only have one ConcreteCreator?A: The Factory Method Pattern is useful if you’ve only got one concrete creator because you are decoupling the implementation of the product from its use. If you add additional products or change a product’s implementation, it will not affect your Creator (because the Creator is not tightly coupled to any ConcreteProduct).
- 20Q: Would it be correct to say that our NY and Chicago stores are implemented using Simple Factory? They look just like it.A: They’re similar, but used in different ways. Even though the implementation of each concrete store looks a lot like the SimplePizzaFactory, remember that the concrete stores are extending a class which has defined createPizza() as an abstract method. It is up to each store to define the behavior of the createPizza() method. In Simple Factory, the factory is another object that is composed with the PizzaStore.
- 21Q: Are the factory method and the Creator always abstract?A: No, you can define a default factory method to produce some concrete product. Then you always have a means of creating products even if there are no subclasses of the Creator
- 22Q: Each store can make four different kinds of pizzas based on the type passed in. Do all concrete creators make multiple products, or do they sometimes just make oneA: We implemented what is known as the parameterized factory method. It can make more than one object based on a parameter passed in, as you noticed. Often, however, a factory just produces one object and is not parameterized. Both are valid forms of the pattern.
- 23Q: Your parameterized types don’t seem “typesafe.” I’m just passing in a String! What if I asked for a “CalmPizza”?A: You are certainly correct and that would cause, what we call in the business, a “runtime error.” There are several other more sophisticated techniques that can be used to make parameters more “type safe”, or, in other words, to ensure errors in parameters can be caught at compile time. For instance, you can create objects that represent the parameter types, use static constants, or, in Java 5, you can use enums
- 24Q: I’m still a bit confused about the difference between Simple Factory and Factory Method. They look very similar, except that in Factory Method, the class that returns the pizza is a subclass. Can you explainA: You’re right that the subclasses do look a lot like Simple Factory, however think of Simple Factory as a one shot deal, while with Factory Method you are creating a framework that let’s the subclasses decide which implementation will be used. For example, the orderPizza() method in the Factory Method provides a general framework for creating pizzas that relies on a factory method to actually create the concrete classes that go into making a pizza. By subclassing the PizzaStore class, you decide what concrete products go into making the pizza that orderPizza() returns. Compare that with SimpleFactory, which gives you a way to encapsulate object creation, but doesn’t give you the flexibility of the Factory Method because there is no way to vary the products you’re creating
- 25Q: For such a simple pattern consisting of only one class, Singletons sure seem to have some problems.A: Well, we warned you up front! But don’t let the problems discourage you; while implementing Singletons correctly can be tricky, after reading this chapter you are now well informed on the techniques for creating Singletons and should use them wherever you need to control the number of instances you are creating.
- 26Q: Can’t I just create a class in which all methods and variables are defined as static? Wouldn’t that be the same as a Singleton?A: Yes, if your class is selfcontained and doesn’t depend on complex initialization. However, because of the way static initializations are handled in Java, this can get very messy, especially if multiple classes are involved. Often this scenario can result in subtle, hard to find bugs involving order of initialization. Unless there is a compelling need to implement your “singleton” this way, it is far better to stay in the object world
- 27Q: What about class loaders? I heard there is a chance that two class loaders could each end up with their own instance of Singleton.A: Yes, that is true as each class loader defines a namespace. If you have two or more classloaders, you can load the same class multiple times (once in each classloader). Now, if that class happens to be a Singleton, then since we have more than one version of the class, we also have more than one instance of the Singleton. So, if you are using multiple classloaders and Singletons, be careful. One way around this problem is to specify the classloader yourself.
- 28Q: I’ve always been taught that a class should do one thing and one thing only. For a class to do two things is considered bad OO design. Isn’t a Singleton violating thisA: You would be referring to the “One Class, One Responsibility” principle, and yes, you are correct, the Singleton is not only responsible for managing its one instance (and providing global access), it is also responsible for whatever its main role is in your application. So, certainly it can be argued it is taking on two responsibilities. Nevertheless, it isn’t hard to see that there is utility in a class managing its own instance; it certainly makes the overall design simpler. In addition, many developers are familiar with the Singleton pattern as it is in wide use. That said, some developers do feel the need to abstract out the Singleton functionality.
- 29Q: I wanted to subclass my Singleton code, but I ran into problems. Is it okay to subclass a Singleton?A: One problem with subclassing Singleton is that the constructor is private. You can’t extend a class with a private constructor. So, the first thing you’ll have to do is change your constructor so that it’s public or protected. But then, it’s not really a Singleton anymore, because other classes can instantiate it. If you do change your constructor, there’s another issue. The implementation of Singleton is based on a static variable, so if you do a straightforward subclass, all of your derived classes will share the same instance variable. This is probably not what you had in mind. So, for subclassing to work, implementing registry of sorts is required in the base class. Before implementing such a scheme, you should ask yourself what you are really gaining from subclassing a Singleton. Like most patterns, the Singleton is not necessarily meant to be a solution that can fit into a library. In addition, the Singleton code is trivial to add to any existing class. Last, if you are using a large number of Singletons in your application, you should take a hard look at your des
- 30Q: I still don’t totally understand why global variables are worse than a Singleton.A: In Java, global variables are basically static references to objects. There are a couple of disadvantages to using global variables in this manner. We’ve already mentioned one: the issue of lazy versus eager instantiation. But we need to keep in mind the intent of the pattern: to ensure only one instance of a class exists and to provide global access. A global variable can provide the latter, but not the former. Global variables also tend to encourage developers to pollute the namespace with lots of global references to small objects. Singletons don’t encourage this in the same way, but can be abused nonetheless.
Information
- Description
- Flashcards on Observer Pattern, created by witse cools on 03/01/2020.
- Created by
- witse cools
- Views
- 3
- Rating