четверг, 19 июня 2008 г.

Шаблоны проектирования. Глава 1.

Здесь буду высказывать свое мнение и реализацию относительно некоторых паттернов проектирования.
Итак, поехали.

Шаблоны проектирования (паттерн, pattern) — это эффективные способы решения характерных задач проектирования, в частности проектирования компьютерных программ. Паттерн не является законченным образцом проекта, который может быть прямо преобразован в код, скорее это описание или образец для того, как решить задачу, таким образом, чтобы это можно было использовать в различных ситуациях.
http://ru.wikipedia.org/wiki/Шаблоны_проектирования

В принципе вопросов по поводу определения не возникает. Интересно, что подразумевают люди, когда в резюме пишут "Владею шаблонами проектирования"? Имхо как по мне сей факт мало о чем говорит. Ведь можно наизусть зазубрить все 73 шаблона (я столько насчитал) и абсолютно не применять их на практике, либо применять там, где это не нужно (так называемая “избыточная сложность”). А можно и без знания того или иного шаблона своим умом дойти до эффективного решения. Ну да ладно это вопрос таланта, опыта и .т.д. Другой вопрос, что человек, который знаком с сабжем при решении реальной задачи, возможно, вспомнит о том или ином шаблоне и попросту не будет изобретать велосипед (но тут таки опять таки больше вопрос в том уместно ли сей шаблон применять). Так что фразу "Владею шаблонами проектирования" я бы перефразировал в “Знаком с шаблонами проектирования и знаю, в какой ситуации, какой применять”.

Лирическое отступление закончил. Начну пожалуй обзор.

Delegation pattern/Шаблон делегирования
Довольно полезный шаблон позволяющий решить проблему множественного наследования. Суть в том, чтобы передать реализацию того или иного метода связанному объекту.

Реализация 1.
unit DelegationPattern;

interface
uses SysUtils;

type

IDelegateInterface = interface ['{37573FCA-5D5B-4340-9D64-5CB61F672BB6}']
  procedure Method1;
  procedure Method2;
end;

TClassA = class(TInterfacedObject, IDelegateInterface)
public
  procedure Method1;
  procedure Method2;
end;

TClassB = class(TInterfacedObject, IDelegateInterface)
public
  procedure Method1;
  procedure Method2;
end;

TClassDel = class(TInterfacedObject, IDelegateInterface)
private
  FInterface: IDelegateInterface;
public
  procedure Method1;
  procedure Method2;
  procedure ToClassA;
  procedure ToClassB;
end;

implementation

{ TClassA }

procedure TClassA.Method1;
begin
  Writeln('TClassA.Method1');
end;

procedure TClassA.Method2;
begin
  Writeln('TClassA.Method2');
end;

{ TClassB }

procedure TClassB.Method1;
begin
  Writeln('TClassB.Method1');
end;

procedure TClassB.Method2;
begin
  Writeln('TClassB.Method1');
end;

{ TClassDel }

procedure TClassDel.Method1;
begin
  FInterface.Method1;
end;

procedure TClassDel.Method2;
begin
  FInterface.Method2;
end;

procedure TClassDel.ToClassA;
begin
  FInterface := TClassA.Create;
end;

procedure TClassDel.ToClassB;
begin
  FInterface := TClassB.Create;
end;

end.

В принципе в данном примере все прозрачно, с помощью методов TClassDel.ToClassA и TClassDel.ToClassB меняем ссылку на базовый класс, в котором и содержится необходимая реализация.

Реализация 2
type
IImplInterface = interface['{96387A25-C8F4-4275-A553-802F9955CF62}']
  procedure P1;
  procedure P2;
end;

TImplClass = class
  procedure P1;
  procedure P2;
end;

TMyImplClass = class(TInterfacedObject, IImplInterface)
  FMyImplClass : TImplClass;
  property  MyImplClass: TImplClass  read FMyImplClass implements IImplInterface;
  procedure IImplInterface.P1 = MyP1;
  procedure MyP1;
  procedure MyProc;
end;

implementation

{ TImplClass }

procedure TImplClass.P1;
begin
  Writeln('TMyImplClass.P1');
end;

procedure TImplClass.P2;
begin
  Writeln('TMyImplClass.P2');
end;

{ TMyImplClass }

procedure TMyImplClass.MyP1;
begin
  Writeln('TMyClass.MyP1');
end;

procedure TMyImplClass.MyProc;
begin
  Writeln('TMyClass.MyProc');
end;

Также есть класс отвечающий за реализацию. С помощью procedure IImplInterface.P1 = MyP1; можно переопределить метод TImplClass тоесть в моем понимании некий аналог виртуальных методов.

Functional design/Шаблон функционального дизайна

Функциональный дизайн гарантирует, что каждый модуль компьютерной программы имеет только одну обязанность и исполняет её с минимумом побочных эффектов на другие части программы.

Вроде бы это и так понятно. Как говорится нужно отделять “Мух от котлет”. У Мартина в “Быстрая разработка программ: принципы, примеры, практика” на эту тему много чего написано.

Immutable

Идея в использовании неизменяемых объектов. Вполне может быть в некоторых ситуациях полезна. Хотя я не вижу сложности в том, чтобы создать такой объект. Представляю себе это примерно так:

type
TImmutable = class
private
  FData: string;
public
  procedure Write;
  constructor Create(Data: string);
  protected
  property Data: string read FData;
end;

implementation

{ TImmutable }

procedure TImmutable.Write;
begin
  Writeln(FData);
end;

constructor TImmutable.Create(Data: string);
begin
  FData := Data;
end;

Комментариев нет: