Реализация
● адаптер класса (множественное наследование
классов или интерфейсов);
● адаптер объекта (композиция).
●
Переход на использование других
(несовместимых по интерфейсу) внешних
классов не требует переделки самой
системы, достаточно заменить реализацию
соответствующих адаптеров.
Adaptee — адаптируемый: определяет
существующий интерфейс, который нуждается в
адаптации.
Adapter — адаптер: адаптирует интерфейс
Adaptee к интерфейсу Target.
std::cout << "LegacyRectangle:
create. (" << x1_ << "," << y1_ <<
") => (" << x2_ << "," << y2_ << ")" << std::endl;
}
void OldDraw() {
std::cout << "LegacyRectangle:
OldDraw.
(" << x1_ << "," << y1_ <<
") => (" << x2_ << "," << y2_ << ")" << std::endl;
}
private:
Coordinate x1_, y1_, x2_, y2_;
};
public:
RectangleAdapter(Coordinate x, Coordinate y, Dimension w, Dimension h)
: LegacyRectangle(x, y, x + w, y + h)
{
std::cout << "RectangleAdapter: create. (" << x << "," << y <<
"), width = " << w << ", height = " << h << std::endl;
}
virtual void Draw()
{
std::cout << "RectangleAdapter: draw." << std::endl;
OldDraw();
}
};
public abstract string RemoteHost
{ get; set; }
public abstract int RemotePort
{ get; set; }
public abstract void Open();
public abstract void Close();
}
ElSimpleSSHClient sshClient;
public SecureBlackboxSSHTunnelAdapter() {
sshClient = new ElSimpleSSHClient();
sshClient.UseInternalSocket = true;
}
public override void Open()
{
sshClient.Open();
}
public override void Close()
{
sshClient.Close();
}
}
}
public override string RemoteHost {
get { return sshClient.Address; }
set { sshClient.Address = value; }
}
public override int RemotePort
{
get { return sshClient.Port; }
set { sshClient.Port = value; }
}
}
●
●
относятся к какой-то конкретной предметной области
состоят из нескольких шаблонов.
Порождающие шаблоны (Creational patterns) абстрагируют процесс
инстанцирования. Они позволяют сделать систему независимой от
способа создания, композиции и представления объектов.
Структурные паттерны (Structural patterns) решают вопрос о том, как из
уже имеющихся классов и объектов оптимально получить более крупные
структуры и образования.
Паттерны поведения (Behavioral patterns) отвечают за инкапсуляцию
алгоритмов и распределение обязанностей между объектами.
Также выделяют паттерны параллельной обработки (concurrency patterns),
системные паттерны (system patterns), интеграционные паттерны (integral
patterns) и т.д.
Класс заказа содержит ссылку на продукт в поле
Product (отношение один к одному):
Мотивация
● Должен быть ровно один экземпляр некоторого
класса, легко доступный всем клиентам.
● Единственный экземпляр должен расширяться
путем порождения подклассов, и клиентам нужно
иметь возможность работать с расширенным
экземпляром без модификации своего кода.
экземпляру. Может нести ответственность
за создание собственного уникального
экземпляра.
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
}
// T является классом, имеет конструктор без параметров
{
protected Singleton() { }
private static T instance;
public static T Instance {
get {
if (instance == null)
instance = new T();
return instance;
}
}
}
public void Operation()
{
// implementation
}
}
// предотвратить создание экземпляра класса Singleton
protected Singleton() { }
// Фабрика используется для отложенной инициализации экземпляра класса
private sealed class SingletonCreator where S : class {
// Используется Reflection для создания экземпляра
// класса без публичного конструктора
private static readonly S instance = (S)typeof(S).GetConstructor(
BindingFlags.Instance | BindingFlags.NonPublic,
null, new Type[0],
new ParameterModifier[0]).Invoke(null);
public static S CreatorInstance {
get { return instance; }
}
}
public static T Instance {
get { return SingletonCreator
}
}
public class RegSingleton {
private static RegSingleton instance;
private static Dictionary new Dictionary protected RegSingleton() { } public static void Register(String name, RegSingleton instance) registry.Add(name, instance); } protected static RegSingleton Lookup(String name) return registry[name]; }
{
{
}
public class RegSingleton
{
private static RegSingleton instance;
public static RegSingleton Instance()
{
if (instance == null)
{
string name = System.GetProperty("SINGLETON_NAME");
instance = RegSingleton.Lookup(name);
}
return instance;
}
}
public class Singleton : RegSingleton
{
static Singleton()
{
new Singleton();
}
protected Singleton()
{
RegSingleton.Register(this.GetType().Name, this);
}
}
static
{
new Singleton();
}
protected Singleton()
{
RegSingleton.Register(this.getClass().getName(), this);
}
}
public:
static Singleton& Instance()
{
if (!pInstance)
pInstance = new Singleton();
return *pInstance;
}
private:
Singleton() { }
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
~Singleton() { }
static Singleton* pInstance;
};
Первое решение проблемы: Синглтон Мейерса, который
использует локальную статическую переменную:
Singleton& Singleton::Instance()
{
static Singleton obj;
return obj;
}
Первое решение проблемы висячей ссылки состоит в
создании флага destroyed и генерации исключения при
попытке доступа к уничтоженному объекту:
class Singleton {
public:
static Singleton& Instance() {
if (!pInstance) {
if (destroyed)
OnDeadReference();
else
Create();
}
return *pInstance;
}
};
}
static bool destroyed;
static Singleton * pInstance;
};
class Singleton {
static void OnDeadReference() {
Create();
// Теперь pInstance указывает на ячейку памяти, где
// ранее размешался объект
new(pInstance) Singleton();
// На месте этих данных вновь создаётся объект
atexit(KillPhoenixSingleton);
// новый объект ставится в очередь на уничтожение
destroyed = false;
}
static void KillPhoenixSingleton() {
pInstance->~Singleton();
// Избегаем освобождения памяти оператором delete
}
};
Время жизни объекта можно задать при помощи
функции SetLongevity из библиотеки Loki:
template void SetLongevity(T * object, unsigned int longevity); Данная функция гарантирует, что объект object будет
уничтожен не ранее, чем объекты с меньшей
продолжительностью жизни.
static void Create()
{
pInstance = new Singleton();
SetLongevity(pInstance, longevity);
}
static const int longevity = 2;
static Singleton * pInstance;
};
if (!pInstance) {
Lock guard(mutex);
if (!pInstance)
// Первая проверка
// Вторая проверка
pInstance = new Singleton();
}
return *pInstance;
}
private:
static Mutex mutex;
};
if (instance == null)
// Первая проверка
{
lock (syncRoot)
{
if (instance == null) // Вторая проверка
instance = new Singleton();
}
}
return instance;
}
}
Если не удалось найти и скачать презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:
Email: Нажмите что бы посмотреть