Agenda
What are patterns?
Types of patterns
Examples: commonly used patterns
References
Design
patterns
2
What are patterns?
Optimized, reusable solutions to the
programming problems that we encounter
every day.
It is not a class or a library that we can
simply plug into our system.
It's not language-specific.
Design
patterns
3
Why do we need it?
It gives developers a common vocabulary to
talk about software solutions.
Reduces development time as known
solutions are used instead of reinventing the
wheel.
Tried and tested solutions
Design
patterns
4
Who made them?
Christopher Alexander
(architect)
published in 1977
”Gang of Four”
(computer scientists)
published in 1994
…
Design
patterns
5
Types of patterns
There are three basic kinds of design patterns:
structural
creational
behavioural
Design
patterns
7
Creational patterns
Design
patterns
8
Deal with object
creation mechanisms, trying to create
objects in a manner suitable to the
situation.
Abstract factory
Builder
Factory method
Prototype
Singleton
Behavioral patterns
Design
patterns
9
Behavioural patterns are used in
communications between entities.
Make it easier and more flexible for
these entities to communicate.
Template method
Iterator
Strategy
Command
Chain of responsibility
Momento
Mediator
Observer
Visitor
Interpreter
State
Null object
Factory method. Code snippet (2)
Design
patterns
28
Create families of related
or dependent objects.
Design
patterns
29
Abstract vs method vs simple
Factory Method pattern is a simplified version of Abstract
Factory pattern.
Factory Method pattern is responsible of creating products
that belong to one family, while Abstract Factory pattern
deals with multiple families of products.
Simple factory is an ideology not pattern.
Design
patterns
30
Bridge vs Adapter
Bridge decouples an abstraction from its
implementation so that the two can vary
independently.
Fill the difference
The Adapter pattern is used so that two
unrelated interfaces can work together
Design
patterns
31
Refactoring to “Bridge”
Before refactoring:
After refactoring:
The Bridge pattern is an application of the
old advice, "prefer composition over
inheritance".
It becomes handy when you must subclass
different times in ways that are orthogonal with
one another.
Say you must implement a hierarchy of colored
shapes. You wouldn't subclass Shape with
Rectangle and Circle and then subclass
Rectangle with RedRectangle, BlueRectangle
and GreenRectangle and the same for Circle,
would you? You would prefer to say that each
Shape has a Color and to implement a hierarchy
of colors, and that is the Bridge Pattern.
Design
patterns
32
Adapter
A legacy Rectangle component's display()
method expects to receive "x, y, w, h"
parameters. But the client wants to pass
"upper left x and y" and "lower right x and
y".
This incongruity can be reconciled by
adding an additional level of indirection –
i.e. an Adapter object.
So old component is plugged into to a new sys
Design
patterns
33
Template method vs Strategy
We use the Template Method when we
have a long, complicated algorithm that
can be decomposed into a series of
discreet steps.
Fill the difference
Strategy pattern is used when we have
multiple algorithm for a specific task and
client decides the actual implementation to
be used at runtime.
Design
patterns
34
Template method
A Template method
pattern provides a skeleton
for performing any sort of
algorithm or an operation,
and it allows the sub-
classes to re-define part of
the logic.
References
Design
patterns
36
1. Head First Design Patterns by Eric Freeman, Elisabeth
Robson, Bert Bates, Kathy Sierra
2. Design Patterns: Elements of Reusable Object-Oriented
Software by Gang of Four
3. Refactoring to Patterns by Joshua Kerievsky
Design
patterns
42
Builder
specifies an abstract interface for creating
parts of a Product object
Concrete Builder
constructs and assembles parts of the
product by implementing the Builder
interface
defines and keeps track of the
representation it creates
provides an interface for retrieving the
product
Director
constructs an object using the Builder
interface
Product
represents the complex object under
construction.
Builder (UML)
Flightweight. When should we
use it?
Design
patterns
44
When:
o Need to create a large number of objects
o Because of the large number when memory cost is a constraint.
o When most of the object attributes can be made external and shared.
o Same object will be used repeatedly.
For example:
Imagine we have a text editor. If we create an object for every character in a file,
think of it how many objects we will create for a long document. What will be the
application performance.
Flightweight. UML
Design
patterns
45
Flyweight
Declares an interface through which flyweights
can receive
Concrete Flyweight
Implements the Flyweight interface and stores
intrinsic state.
Flyweight Factory
The factory creates and manages flyweight
objects.
Flightweight. Object properties.
Design
patterns
46
Object properties
Intrinsic Extrinsic
Intrinsic - naturally belongs to the
'Fly Weight' object and thus should
be permanent or immutable
(internal) or context free.
Extrinsic - state that belongs to the
context of the object (external) or
unique to that instance.
Design
patterns
50
Caretaker
Responsible for keeping the memento.
Originator
Creates a memento object capturing the
originators internal state.
Memento
Stores internal state of the Originator object.
Momento (UML)
Null object. UML
Abstract Class
Defines abstract primitive operations that
concrete implementations have to define.
Real Class
A real implementation of the Abstract Class
performing some real actions.
Null Class
An implementation which do nothing of the
abstract class, in order to provide a non-null
object to the client.
Client
Gets an implementation of the abstract class
and uses it. It doesn't really care if the
implementation is a null object or an real object
Design
patterns
53
Notas do Editor
Design patterns are optimized, reusable solutions to the programming problems that we encounter every day. A design pattern is not a class or a library that we can simply plug into our system; it's much more than that. It is a template that has to be implemented in the correct situation. It's not language-specific either. A good design pattern should be implementable in most—if not all—languages, depending on the capabilities of the language. Most importantly, any design pattern can be a double-edged sword— if implemented in the wrong place, it can be disastrous and create many problems for you. However, implemented in the right place, at the right time, it can be your savior.
Benefits of Patterns
Benefits of knowing and using design patters
are several. Patterns are known solution for
building software systems. They can reduce
development time as known solutions are used
instead of reinventing the wheel. It is also a
benefit to use known solutions that are tried
and tested. Finally, patterns make the
communication of development teams easier.
Design patterns have their roots in the work of Christopher Alexander, a civil engineer who wrote about his experience in solving design issues as they related to buildings and towns. It occurred to Alexander that certain design constructs, when used time and time again, lead to the desired effect. He documented and published the wisdom and experience he gained so that others could benefit. About 15 years ago, software professionals began to incorporate Alexander's principles into the creation of early design pattern documentation as a guide to novice developers. This early work led others to also write about design patterns and culminated in the publication of Design Patterns: Elements of Reusable Object-Oriented Software in 1995 by Eric Gamma, Richard Helm, Ralph Johnson, and John Vlissides.
Много паттернов и не пытайтесь их все запомнить.
Порождающие паттерны, предназначенные для создания новых объектов в системе.
Структурные паттерны, решающие задачи компоновки системы на основе классов и объектов.
Паттерны поведения, предназначенные для распределения обязанностей между объектами в системе.
Работа с аудиторией
volatile – говорит о том, что если некий поток изменяет это поле, то на данный момент времени никакой другой поток не может менять значение этой переменной. Также это говорит о том, что в любой момент времени значение этой переменной одинаково для любого потока и соответствует последнему изменению. То есть любой поток напрямую тыркается именно в "подлинную" переменную.
Serialization has a special hook it uses - a private method on the class being instantiated called readResolve() - which is meant to supply a 'hook' for a class developer to ensure that they have a say in what object is returned by serialization.
Такой метод потокопезопасен, краток, но без ленивой инициализации.
Второй вопрос
Второй вопрос
Второй вопрос
Второй вопрос
Второй вопрос
Второй вопрос
Второй вопрос
In Abstract Factory we define an interface which will create families of related or dependent objects. In simple words, interface will expose multiple methods each of which will create some object. Again, here method return types will be generic interfaces. All this objects will together become the part of some important functionality.
Приспособленец - паттерн, структурирующий объекты таким образом, что из них инстанцируется всего лишь ограниченный необходимый набор экземпляров вместо всего боль
http://codelab.ru/pattern/flyweight/
шого множества.
Flyweight is used when there is a need to create high number of objects of almost similar nature.
High number of objects consumes high memory and flyweight design pattern gives a solution to reduce the load on memory by sharing objects.
Для того, чтоб воспользоваться паттерном Приспособленец, нужно разделить атрибуты на два типа: Intrinsic – параметры, которые не зависят от контекста, и они не изменяемые и Extrinsic - передаются извне и принадлежат контексту.
Необходимо сохранять, фиксировать и восстанавливать внутреннее состояние объекта не нарушая инкапсуляцию. http://habrahabr.ru/sandbox/39499/
У нас есть главный объект, который имеет внутреннее состояние, именуемый ”Создатель” (Originator).
Так же у нас есть объект, который может выполнять определенные действия над “Создателем” (при этом внутреннее состояние “Создателя” может изменяться) и имеет возможность сохранять и восстанавливать состояние “Создателя”, когда ему это необходимо. Этот класс именуется “Опекун”(Caretaker).
Для того, что бы “Опекун” смог запомнить внутреннее состояние “Создателя”, он запрашивает у него объект, содержащий необходимые данные, именуемый “Хранитель” (Memento).
http://www.journaldev.com/1734/memento-design-pattern-in-java-example-tutorial
Представьте, что у вас есть задача выкопать яму, по алгоритму у вас есть землекоп. Аналог нулл-а — отсутствие землекопа. Если его нет, то да, я хочу, чтобы вся задача прервалась, это исключение. Я не хочу тихого выполнения, будто бы землекоп есть, но яма не выкопана. Вы скажете, что такие ситуации тоже отслеживаются в функциональных языках. Но, позвольте, какая тогда разница: проверяю я нулл или еще что-либо? Хорошо это или плохо, но проверка на нулл иногда обладает семантикой, а не является просто проверкой на присутствие объекта. Да в любом языке программирования вместо нулл-а можно возвращать фиктивное пустое значение (Null object шаблон), но хорошо подумайте, стоит ли это делать: явную ошибку проще отловить, чем неявную.