Введение в шаблоно-ориентированное проектирование
Summary
Why patterns, you may wonder. Why patterns and why not a method of object-oriented design and an introduction in one or more object-oriented languages? The answer is simple. Patterns bookmark effective design. They fill the gap between the almost infinite possibilies of object-oriented programming languages and tools and the rigor of methodical design. As Brian Foote expressed it in POPL3,
patterns are the footprints of design, paving the way for future designs. They provide a
common design vocabulary and are also helpful in documenting a framework. And, as we will see later, patterns may also act as a target for redesign, that is when the current design no longer offers the desired
functionality and flexibility.
Первые шаги
Способ описания шаблонов
Name - handle
- increases design vocabulary
Problem - when to apply
- explains the problem and the conflict
Solution - general arrangement
- design, responsibilities, collaborations
Consequences - tradeoffs
- to understand the costs and benefits
Other important entries in the pattern schema are, the
problem indicating what the patterns is all about, the
solution describing the general arrangment of the classes and objects involved, and the
consequences or tradeoffs that a particular solution entails. The actual patterns presented in GOF94 are the result of the authors' involvement in developing various GUI toolkits, in particular Interviews, Interviews, and ET++, ET, and applications such as for example interactive text and image editors. In the course of developing a toolkit or application there are many occasions for redesign.
Причины возможных изменений проектировки
- creating an object by specifying a class explicitly Abstract Factory, Factory Method, Prototype
- dependence on specific operations Chain of Responsibilty, Command
- dependence on hardware & software platforms Abstract Factory, Bridge
- dependence on object implementation or representation --Abstract Factory, Bridge, Memento, Proxy
- algorithm dependence Iterator, Strategy, Template Method, Visitor
- extending functionality by subclassing Bridge, Composite, Decorator, Observer
- tight coupling Abstract Factory, Bridge, Chain of Responsibilities, Command, Facade, Mediator, Observer
- inability to alter classes conveniently Adaptor, Decorator, Visitor
Типы шаблонов
Following GOF94, we may distinguish between creational patterns that govern the construction and management of objects, structural patterns that define the static relationships between objects, and behavioral patterns that characterize the dynamic aspects of the interaction between objects.
Creational Patterns
Design for change means to defer commitment to particular object implementations as long as possible. Due to inheritance, or rather subtyping, the client, calling a particular method, can choose the most abstract class, highest in the hierarchy. However, when it comes to creating objects, there seems to be no other choice than naming the implementation class explicitly. Wrong. Creational patterns are meant to take care of that, that is to hide the actual class used as far away as possible.
Creational Patterns
- Factory hide concrete classes
- Factory Method virtual constructors
- Prototype dynamic creation by cloning
- Singleton one instance only
Creational patterns come in various flavors. In section delegation-in-Java some example realizations were presented. The factory class, for example, is a rather static way of hiding the implementation classes. As an alternative, you may use a factory method, similar to the instance method of the singleton class.
If you prefer a more dynamic approach, the prototype pattern might be better. A prototype is an object that may be used to create copies or clones, in a similar way as instances are created from a class. However, cloning is much more dynamic, the more so if delegation is used instead of inheritance to share resources with some ancestor class. See prototypes.
The advantage of using a factory, or any of the other creational patterns, is that exchanging product families becomes very easy. Just look for example at the Java Swing library. Swing is supported under Unix, Windows and
MacOS?. The key to multiple platform support is here, indeed, the use of factories to create widgets. Factories are also essential when using CORBA, simply because calling a constructor is of no use for creating objects on a remote site.
Structural Patterns
Objects rarely live in isolation. In slide structural-patterns a selection of the structural patterns treated in GOF94 is collected. Structural patterns indicate how classes and objects may be composed to form larger structures.
Structural Patterns
- object and class composition
Pattern: Composite Alias: Part/whole Remarks: collections of components
Imagine, for example, an application for interactive text processing. Now, the Composite pattern may be used to combine text, images and also compound components, that may itself consist of other components.
Closely related to the Composite pattern is the Flyweight pattern, which is needed when the number of components grows very large. In that case, the components themselves must for obvious reasons carry as little information as possible. Context or state information must then be passed as a parameter.
To give some more examples, suppose there exists a nice library for formatting text and images, but unfortunately with only a procedural interface. Then the Adaptor pattern may be used to provide a interface that suits you, by wrapping the original library.
The Bridge pattern is in some sense related to the Factory. In order to work with a platform-independent widget library, you need, as has been explained, a factory to hide the creation of widgets, but you also need to bridge a hierarchy of platform-dependent implementation classes to the more abstract platform-independent widget set.
When creating widgets to display text or images it may be very inconvenient to create a separate class for example when adding scrolling functionality. The Decorator pattern allows you to insert additional functionality without subclassing.
Now think of a networked application, for example to be able to incorporate components that are delivered by a server. The library may provide a number of networking classes that deal with all possible communication protocols. To simplify access to these classes a Facade may be built, hiding the complexity of the original class interfaces.
Alternatively, remote components may be available through a proxy. The Proxy pattern describes how access may be regulated by an object that acts as a surrogate for the real object. Like composites and decorators, proxies may be used for recursive composition. However, proxies primarily regulate access, whereas decorators add responsibilities, and composites represent structure.
Behavioral Patterns
Our final category of patterns, behavioral patterns, concern the construction of algorithms and the assignment of responsibilities to the objects that cooperate in achieving some goal.
class-based composition
- Template Method the skeleton of an algorithm
- Interpreter to evaluate expressions
object-based composition
- Mediator provides indirection
- Chain of Responsibility connect objects to interact
- Observer to handle dependencies
Шаблон Model-View-Controller
Существует популярный шаблон проектирования Model - View - Controller. Идея его заключается в следующем. Существует модель (Model) предметной области приложения, например структура базы данных. Существуют способы отображения (View) этой модели для пользователя, например HTML-странички. Существует набор действий (Controller), которые производятся с моделью (например, изменение состояния модели, т.е. содержимого БД, или генерация HTML-кода). Обычно View реагирует на внешние события, такие как метод Post или Get из браузера пользователя, и на каждое такое внешнее воздействие определяет свою команду (Controller). На самом деле MVC немного сложнее, но в нашем случае мы возьмем только выше описанные идеи. Шаблон MVC изображен на следующем рисунке
В нашем случае событие model_was_changed не может произойти, так как события между броузером и CGI-скриптом (Controller) идут только в сторону CGI-скрипта, т.е. CGI-скрипт не может в любой момент времени сообщить пользователю о том, что была изменена модель. Не работающая связь изображена ниже.
Самая существенная ошибка, которую совершают программисты - это совмещение кода, изменяющего базу данных и генерация HTML. Предлагаю это разделить и назвать соответствующие программные модули контроллером взаимодействия с БД и котроллером генерации HTML. Ниже показано это разделение.
Первый овал - это код, который меняет состояние таблиц БД, т.е. Controller. Второй генерирует HTML, т.е. опять Controller. Третий овал с черточкой - это представление HTML в браузере на стороне пользователя, т.е. View. А Model является структурой БД, как и говорилось выше.
Шаблон Factory
Links
--
AndreyUstyuzhanin - 31 Mar 2004