четверг, 5 марта 2015 г.

Полезные ссылки


Сайт, посвященный объектно-ориентированному анализу, проектированию и программированию: 
http://ooad.asf.ru/Patterns.aspx


Признаки плохого кода:

среда, 4 марта 2015 г.

ПАТТЕРН КОМАНДА (COMMAND)

Паттерн Команда можно описать так... Есть пульт с кнопками. Нажатие на кнопку запускает выполнение абстрактной команды. Наследуемый класс от команды содержит в себе методы, которые управляют изменениями состояния объекта (например, этот класс включает и выключает свет).

Паттерн Команда инкапсулирует запрос в виде объекта, делая возможной параметризацию клиенстких объектов с другими запросами, организацию очереди или регистрацию запросов, а также поддержку отмены операций.


//  интерфейс комманды
    interface eiCommand
    {
        void Execute();
    }


// реализация класса управления коммандами
    class SimpleRemoteControl
    {
        private eiCommand slot;

        public SimpleRemoteControl()
        {

        }

        public void setCommand(eiCommand prmCommand)
        {
            slot = prmCommand;
        }

        public void buttonWasPresed()
        {
            slot.Execute();
        }
    }

//  конкретный класс объекта свет
    class Light
    {
        internal void on()
        {
            Console.WriteLine("Light is On");
            //throw new NotImplementedException();
        }
    }


// конкретный класс команды
    class ecLightOnCommand : eiCommand
    {
        private Light light;

        public ecLightOnCommand(Light prmLight)
        {
            this.light = prmLight;
        }

        public void Execute()
        {
            this.light.on();
        }
    }

// запускаем код 
        static void Main(string[] args)
        {
            SimpleRemoteControl remote = new SimpleRemoteControl();
            
            Light light = new Light();
            ecLightOnCommand lightOn = new ecLightOnCommand(light);

            GarageDoor garageDoor = new GarageDoor();
            ecGarageDoorOpenCommand garageDoorOpen = new ecGarageDoorOpenCommand(garageDoor);

            remote.setCommand(lightOn);
            remote.buttonWasPresed();

            remote.setCommand(garageDoorOpen);
            remote.buttonWasPresed();
        }

вторник, 3 марта 2015 г.

ПАТТЕРН ДЕКОРАТОР (DECORATOR)

Паттерн Декоратор можно описать так:

  • Берем объект "Кофе";
  • Декорируем его объектом "Сахар";
  • Декорируем его объектом "Молоко";
  • Вызываем метод cost и пользуемся делегированием для прибавления стоимости дополнений.
Паттерн Декоратор динамически наделяет объект новыми возможностями и является гибкой альтернативой субклассированию в области расширения функциональности.


// декорируемый объект
    abstract class ecDrink
    {
        public string _description = "Unknown beverage";

        public virtual string getDescription()
        {
            return _description;
        }

        public abstract double cost();

    }


// декоратор
    abstract class ecCondimentDecorator : ecDrink
    {

    }

//  конкретный класс декорируемого объекта
    class ecEspresso : ecDrink
    {
        public ecEspresso()
        {
            _description = "Espresso";
        }

        public override double cost()
        {
            return 1.99;
        }
    }


// конкретный класс декоратора
    class ecMocha : ecCondimentDecorator
    {
        private ecDrink drink;

        public ecMocha(ecDrink prmDrink)
        {
            this.drink = prmDrink;
        }


        public override string getDescription()
        {
            return drink.getDescription() + ", Mocha";
        }

        public override double cost()
        {
            return .20 + drink.cost();
        }
    }

понедельник, 2 марта 2015 г.

РЕАЛИЗАЦИЯ ПАТТЕРНА НАБЛЮДАТЕЛЬ (OBSERVER) НА СОБЫТИЯХ C#

Классический паттерн Наблюдатель имеет сильную связь между объектами, которую можно развязать использую встроенные события в c#.



// интерфейс издателя
    public delegate void eiSubjectEventHandler(eiSubject subject);

    public interface eiSubject
    {
        event eiSubjectEventHandler OnUpdate;

        void GenereteEventUpdate();

    }

// реализация класса издателя
    class ecSubject : eiSubject
    {
        private event eiSubjectEventHandler _OnUpdate = null;
        public event eiSubjectEventHandler OnUpdate
        {
            add
            {
                lock (this)
                {
                    _OnUpdate -= value;
                    _OnUpdate += value;
                }
            }
            remove { lock (this) { _OnUpdate -= value; } }
        }

        public void GenereteEventUpdate()
        {
            eiSubjectEventHandler handler = _OnUpdate;

            if (handler != null)
            {
                handler(this);
            }
        }

    }

// реализация интерфейса подписчика
    public interface eiObserver
    {
        void DoOnUpdate(eiSubject subject);

    }

// реализация класса подписчика
    class ecObserver : eiObserver
    {
        public virtual void DoOnUpdate(eiSubject subject)
        {
        }
    }


Это мой эксперементальный вариант.

ПАТТЕРН OBSERVER (ПАТТЕРН НАБЛЮДАТЕЛЬ)

Паттерн очень часто описывают как модель "издатель-подписчик".

  • Издатель открывает свое дело и начинает выпускать газету.
  • Вы оформляете подписку у этого издателя. Каждый раз когда выходит новый номер, он доставляется вам пока действует подписка.
  • Если вы больше не хотите получить газеты, вы прекращаете подписку.


Паттерн  Наблюдатель определяет отношение "один-ко-многим" между объектами таким образом, что при изменении состояния одного объекта происходит автоматическое оповещение и обновление всех зависимых.




четверг, 26 февраля 2015 г.

ПАТТЕРН SINGLETON (ПАТТЕРН ОДИНОЧКА)

Как мне показалось у паттерна Одиночка самая простая реализация.

Паттерн Одиночка гарантирует, что класс имеет только один экземпляр, и предоставляет глобальную точку доступа к этому экземпляру.

В данной реализации сам класс контролирует создание экземпляра, запрещая создание дополнительных экземпляров.


class Singleton {

    // запрещаем создание объекта через операцию new
    protected Singleton () {}
    
    // статичная переменная, которая и есть наш единственный экземпляр
    private static Singleton _instance;

    //  доступ к созданию осуществляется только через статичную функцию GetInstance
    public static Singleton GetInstance(){
         if(null == _instance){
             _instance = new Singleton();
         }
         return _instance;
    }
}


ПАТТЕРНЫ ПРОЕКТИРОВАНИЯ

Месяца два назад я приступила к изучению паттернов проектирования.
Первая книга которую я начала читать была "Design Patterns: Elements Of Reusable Object Oriented Software" от "банды четырех". Для новичка она тяжелая для восприятия и увы я ее еще не дочитала. Но недавно я наткнулась на книгу "Head First Design Patterns" E.Freeman. Советую ее прочесть ее для начала.



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

Общие сведения



В качестве основы проектирования информационных систем применяются "типовые решения" или "шаблоны проектирования" (Patterns).
Шаблоны проектирования (паттерн, design pattern) – это многократно применяемая архитектурная конструкция, предоставляющая решение общей проблемы проектирования в рамках конкретного контекста и описывающая значимость этого решения [22].
Паттерн не является законченным образцом проекта, который может быть прямо преобразован в код, скорее это описание или образец для того, как решить задачу, таким образом, чтобы это можно было использовать в различных ситуациях. Объектно-ориентированные шаблоны зачастую показывают отношения и взаимодействия между классами или объектами, без определения того, какие конечные классы или объекты приложения будут использоваться. Алгоритмы не рассматриваются как шаблоны, так как они решают задачи вычисления, а не проектирования.
В 1970-е годы архитектор Кристофер Александр составил набор шаблонов проектирования [23]. В области архитектуры эта идея не получила такого развития, как позже в области программной разработки. Согласно определению Кристофера Александера: "Каждое типовое решение описывает некую повторяющуюся проблему и ключ к ее разгадке, причем таким образом, что вы можете пользоваться этим ключом многократно, ни разу не придя к одному и тому же результату" [18].
В 1987 году Кент Бэк и Вард Каннигем взяли идеи Александра и разработали шаблоны применительно к разработке программного обеспечения для разработки графических оболочек на языке Smalltalk.
В 1988 году Эрих Гамма начал писать докторскую диссертацию при Цюрихском университете об общей переносимости этой методики на разработку программ.
В 1989-1991 годах Джеймс Коплин трудился над разработкой идиом для программирования на C++ и опубликовал в 1991 году книгу Advanced C++ Idioms. В этом же году Эрих Гамма заканчивает свою докторскую диссертацию и переезжает в США, где в сотрудничестве с Ричардом Хелмом, Ральфом Джонсоном и Джоном Влиссидсом публикует книгу Design Patterns – Elements ofReusable Object-Oriented Software [24]. В этой книге описаны 23 шаблона проектирования. Также команда авторов этой книги известна общественности под названием Банда четырех (Gang of Four, часто сокращается до GoF). Именно эта книга стала причиной роста популярности шаблонов проектирования.
Другим видным деятелем в области проектирования программных систем, который поддержал использование паттернов, является Мартин Фаулер, написавший книгу "Архитектура корпоративных программных приложений" (Patterns of Enterprise Application Architecture). Как отметил Мартин Фаулер в своей книге "собираясь воспользоваться типовыми решениями, не забывайте, что они только отправная точка, а не пункт назначения" [18].
В книге Крейга Лармана "Применение UML и шаблонов проектирования" описано 9 шаблонов GRASP (General Responsibility Assignment Software Patterns, общие образцы распределения обязанностей) – паттернов, используемых в объектно-ориентированном проектировании для решения общих задач по назначению обязанностей классам и объектам. Каждый из них помогает решить некоторую проблему, возникающую при объектно-ориентированном анализе, и которая возникает практически в любом проекте по разработке программного обеспечения.
Главная польза каждого отдельного шаблона состоит в том, что он описывает решение целого класса абстрактных проблем. Также тот факт, что каждый шаблон имеет свое имя, облегчает дискуссию об абстрактных структурах данных (ADT) между разработчиками, так как они могут ссылаться на известные шаблоны. Таким образом, за счет шаблонов производится унификация терминологии, названий модулей и элементов проекта.
Правильно сформулированный шаблон проектирования позволяет, отыскав удачное решение, пользоваться им снова и снова.
Однако иногда шаблоны консервируют громоздкую и малоэффективную систему понятий, разработанную узкой группой. Когда количество шаблонов возрастает, превышая критическую сложность, исполнители начинают игнорировать шаблоны и всю систему, с ними связанную. Нередко шаблонами заменяется отсутствие или недостаточность документации в сложной программной среде.
Есть мнение, что слепое применение шаблонов из справочника, без осмысления причин и предпосылок выделения каждого отдельного шаблона, замедляет профессиональный рост программиста, так как подменяет творческую работу механическим подставлением шаблонов. Люди, придерживающиеся данного мнения, считают, что знакомиться со списками шаблонов надо тогда, когда "дорос" до них в профессиональном плане – и не раньше. Хороший критерий нужной степени профессионализма – выделение шаблонов самостоятельно, на основании собственного опыта. При этом, разумеется, знакомство с теорией, связанной с шаблонами, полезно на любом уровне профессионализма и направляет развитие программиста в правильную сторону. Сомнению подвергается только использование шаблонов "по справочнику".
Шаблоны могут пропагандировать плохие стили разработки приложений, и зачастую слепо применяются.
Шаблоны проектирования классифицируют следующим образом [1825]:
  • Паттерны проектирования классов/объектов
    • Структурные паттерны проектирования классов/объектов
      • Адаптер (Adapter) – GoF
      • Декоратор (Decorator) или Оболочка (Wrapper) – GoF
      • Заместитель (Proxy) или Суррогат (Surrogate) – GoF
      • Информационный эксперт (Information Expert)- GRASP
      • Компоновщик (Composite) – GoF
      • Мост (Bridge), Handle (описатель) или Тело (Body) – GoF
      • Низкая связанность (Low Coupling) – GRASP
      • Приспособленец (Flyweight) – GoF
      • Устойчивый к изменениям (Protected Variations) – GRASP
      • Фасад (Facade) – GoF
    • Паттерны проектирования поведения классов/объектов
      • Интерпретатор (Interpreter ) – GoF
      • Итератор (Iterator) или Курсор (Cursor) – GoF
      • Команда (Command), Действие (Action) или Транзакция (Транзакция) – GoF
      • Наблюдатель (Observer), Опубликовать – подписаться (Publish – Subscribe) или Delegation Event Model – GoF
      • Не разговаривайте с неизвестными (Don't talk to strangers) – GRASP
      • Посетитель (Visitor) – GoF
      • Посредник (Mediator) – GoF
      • Состояние (State) – GoF
      • Стратегия (Strategy) – GoF
      • Хранитель (Memento) – GoF
      • Цепочка обязанностей (Chain of Responsibility) – GoF
      • Шаблонный метод (Template Method) – GoF
      • Высокое зацепление (High Cohesion) – GRASP
      • Контроллер (Controller) – GRASP
      • Полиморфизм (Polymorphism) – GRASP
      • Искусственный (Pure Fabrication) – GRASP
      • Перенаправление (Indirection) – GRASP
    • Порождающие паттерны проектирования
      • Абстрактная фабрика (Abstract Factory, Factory), др. название Инструментарий (Kit) – GoF
      • Одиночка (Singleton) – GoF
      • Прототип (Prototype) – GoF
      • Создатель экземпляров класса (Creator) – GRASP
      • Строитель (Builder) – GoF
      • Фабричный метод (Factory Method) или Виртуальный конструктор (Virtual Constructor) – GoF
    • Архитектурные системные паттерны
    • Структурные паттерны
      • Репозиторий
      • Клиент/сервер
      • Обьектно – ориентированный, Модель предметной области (Domain Model), модуль таблицы (Data Mapper)
      • Многоуровневая система (Layers) или абстрактная машина
      • Потоки данных (конвейер или фильтр)
    • Паттерны управления
      • Паттерны централизованного управления
        • Вызов – возврат (сценарий транзакции – частный случай)
        • Диспетчер
      • Паттерны управления, основанные на событиях
        • Передача сообщений
        • Управляемый прерываниями
      • Паттерны, обеспечивающие взаимодействие с базой данных
        • Активная запись (Active Record)
        • Единица работы (Unit Of Work)
        • Загрузка по требованию (Lazy Load)
        • Коллекция объектов (Identity Map)
        • Множество записей (Record Set)
        • Наследование с одной таблицей (Single Table Inheritance)
        • Наследование с таблицами для каждого класса (Class Table Inheritance)
        • Оптимистическая автономная блокировка (Optimistic Offline Lock)
        • Отображение с помощью внешних ключей
        • Отображение с помощью таблицы ассоциаций (Association Table Mapping)
        • Пессимистическая автономная блокировка (Pessimistic Offline Lock)
        • Поле идентификации (Identity Field)
        • Преобразователь данных (Data Mapper)
        • Cохранение сеанса на стороне клиента (Client Session State)
        • Cохранение сеанса на стороне сервера (Server Session State)
        • Шлюз записи данных (Row Data Gateway)
        • Шлюз таблицы данных (Table Data Gateway)
      • Паттерны, предназначенные для представления данных в Web
        • Модель-представление-контроллер (Model View Controller)
        • Контроллер страниц (Page Controller)
        • Контроллер запросов (Front Controller)
        • Представление по шаблону (Template View)
        • Представление с преобразованием (Transform View)
        • Двухэтапное представление (Two Step View)
        • Контроллер приложения (Application Controller)
    • Паттерны интеграции корпоративных информационных систем
      • Структурные паттерны интеграции
        • Взаимодействие "точка – точка"
        • Взаимодействие "звезда" (интегрирующая среда)
        • Смешанный способ взаимодействия
      • Паттерны по методу интеграции
        • Интеграция систем по данным (data-centric)
        • Функционально-центрический (function-centric) подход
        • Объектно-центрический (object-centric)
        • Интеграция на основе единой понятийной модели предметной области (concept-centric)
      • Паттерны интеграции по типу обмена данными
        • Файловый обмен
        • Общая база данных
        • Удаленный вызов процедур
        • Обмен сообщениями
Также на сегодняшний день существует ряд других шаблонов [22]:

  • Carrier Rider Mapper, предоставление доступа к хранимой информации;
  • аналитические шаблоны, описывают основной подход для составления требований для программного обеспечения (requirement analysis) до начала самого процесса программной разработки;
  • коммуникационные шаблоны, описывают процесс общения между отдельными участниками/сотрудниками организации;
  • организационные шаблоны, описывают организационную иерархию предприятия/фирмы;
  • Анти-паттерны (Anti-Design-Patterns) описывают как не следует поступать при разработке программ, показывая характерные ошибки в дизайне и в реализации;
  • и др.