SlideShare una empresa de Scribd logo
1 de 110
Descargar para leer sin conexión
Архитектура в Agile:
 компоненты и модули
   слабая связность

      Бибичев Андрей
         март 2011
@bibigine
                     Андрей Бибичев

• E-mail:       bibigone@gmail.com
• Twitter:      @bibigine
• Profile:      http://www.google.com/profiles/biBIGone
• Slideshare:   http://www.slideshare.net/bibigine
0. Проблематика
Alistair Cockburn:
 «starting with a walking skeleton,
 then evolving it iteratively»


Mary and Tom Poppendieck:
 «divisible system architecture»


Robert Martin (Uncle Bob):
 «No doubt that BDUF is harmful.
 Size matters! ‘B’ is bad, but ‘L’ is good.
 Indeed, LDUF is absolutely essential.»
Давняя мечта:
tr 'A-Z' 'a-z' <fnord.txt
 | tr -cs 'a-z' 'n' | sort | uniq
 | comm -23 - /usr/share/dict/words




    stdin      params    stdout
Эволюция
1.   goto
2.   подпрограммы
3.   динамические библиотеки
4.   классы (ООП)
5.   компоненты (COM/CORBA/…)
6.   …
Но что-то не легчает №1…




 Корнелис Киммель « Снежный ком»
Сильная связность
≈ каждый с каждым => O(N2)
Но что-то не легчает №2…




               Код-гидра:
один баг исправишь - несколько появляются
Side-эффекты
Могучий глобальный контекст
              +
  Мутабельность всего и вся
              +
Избыточная область видимости
              =
поправил здесь, отвалилось там
Но что-то не легчает №3…




        GOD-classes
WinForms.Net

   Класс Control:
100+ свойств (≈80% public)
400+ методов (≈30% public)
50+ событий (все public)
Разработчик и GOD-класс




   А вокруг пустынно и уныло…
История сложности одного файла и
распределение числа check-in по файлам




 http://michaelfeathers.typepad.com/michael_feathers
       _blog/2011/03/data-rich-development.html
Но что-то не легчает №4…




      «Рулонные функции»
«Промышленный игрокод»
http://code.google.com/p/lugaru/source/browse/Source/GameTick.cpp?r=cmake#1673




                                 …



                 10 992 – 1673 + 1 = 9 320 строк
Типичные болезни:
• Сильная связность
• Неуловимые и непознаваемые side-эффекты
• Вездесущий и всеобъемлющий глобальный
  контекст (привет любителям singletone-ов!)
• GOD-классы
• Переусложненный и запутанный workflow
• Дублирование логики
• …
Мечтали о:   А выходит так:
1. Классы и их
взаимодействие
1. Классы и их
взаимодействие
  1.0. Ремарка
Для процедурных языков
• Класс => Структура + функции для неѐ
    struct a {
                          double f(struct a* p, double k) {
        int v;
                              return p->v * p->d / k;
        double d;
                          }
    };
• Интерфейс => Структура указателей на функции
  (вспомним как работают вызовы к DLL!)
     struct i {
         f1_t f1;       typedef void (*f1_t)(int s);
         f2_t f2;       typedef double (*f2_t)();
     };
• Наследование => Композиция
    struct b {
        struct a super;
    };
1. Классы и их
  взаимодействие
1.1. Современное ООП
Длинные «руки» объекта:
                                          
если ему чего нужно, то он сам за этим тянется
Укорачиваем руки:
• Inversion-of-Control (IoC)
• Law of Demeter
• Tell, Don’t Ask
Inversion of Control (IoC)
«Consumer»
Компонент




                  SomeConsumer
Компонент
 «Provider»




                   SomeProvider
Inversion of Control (IoC)
«Consumer»
Компонент




                                 SomeConsumer
Компонент
 «Provider»




                                   «interface»
              SomeProviderImpl
                                 ISomeProvider
Inversion of Control (IoC)
«Consumer»
Компонент




                 «interface»
                                 SomeConsumer
               ISomeProvider
Компонент
 «Provider»




              SomeProviderImpl
I1

   I2
             MyClass
   I3

 Что нужно             «Торчащий»
для работы                 API
Как передать имплементации
  интерфейсов объекту класса?
• Dependency Injection через конструктор
     MyClass {
          MyClass(I1 o1, I2 o2) { … }   
• DI через свойство/set-метод
     MyClass {
          setI1(I1 o1) { … }            
• Service Locator
     o1 = MegaContext.resolve<I1>();
                                        
Law of Demeter
Any method of an object should only
call methods belonging to:
• itself.
• any parameters that were passed in to
  the method.
• any objects it created.
• any composite objects.
Следствия
:
• Global context (включая Service Locator)
      MegaContext.Singletone.get<IService>().do()
• Цепочки вызовов
      field.getSmth().getSmthElse().Prop.Count



:
• True singletone (e.g. Null Objet)
А работа с фабрикой?
   void doSmth(ISomeFactory someFactory) {
       ISome some = someFactory.createSome();
       some.act();

      // someFactory.createSome().act();


• Казалось бы, работа с фабрикой нарушает
  принцип Диметры

• Относитесь к фабрике как к переопределению
  оператора new. Тогда всѐ становится
  нормально: «any objects it created»
Tell, Don’t Ask
Procedural code gets information then
makes decisions. Object-oriented code
tells objects to do things.

— Alec Sharp
void myFunc(Obj obj) {
    if (!obj.init()) throw new …;
    String id = obj.getId();
    log.write(“starting transaction with “ + id);
    if (obj.supportTransaction()) {
        if (!obj.startTransaction()) throw new …;
        Photo photo = obj.GetPhoto();
        if (!analyzePhoto(photo)) {
            obj.rollback();
            obj.kill();
        } else {
            obj.act();
        }
    }
}
me: Привет!
obj: Хай!
/* me: Ага, ответила, значит продолжаем разговор */
me: Как тебя зовут?
obj: Саша
me: Саша – красивое имя!
/* me: Блин, мужик или баба?! */
me: А полное имя Александр или Александра?
obj: Александра
/* me: Ура! Баба! */
me: Здорово! Давай куда-нить сходим?
obj: Давай. Только куда?
me: В клуб. Только как я тебя узнаю? Пришли фотку
obj: Держи
/* me: Фу */
me: == disconnected ==
Минусы «чата»:
• Сложный интерфейс
• Тесная связность => С высокой вероятностью
  придется согласованно править в двух местах
• Попахивает нарушением инкапсуляции
Инкапсулировать в
       другом месте
interface IObj {
    void performInTransaction(Callback action);
}



Где риализовывать:
• Либо в классе, с которым мы общаемся
• Либо сделать специализированный wrapper
Декларативный стиль в
    императивных языках

•   Иди на кухню
•   Возьми чашку
•   Налей туда заварки
                         • Мне бы чаю
•   Добавь кипятку
•   Две ложки сахара
•   Поставь на блюдце
•   Принеси мне
Дуализм:
    интерфейс vs. данные
              class MyDoc {
                  MyDoc(ICurrentDateProvider cdp) {
                      docDate = cdp.get();
                      …
Документ          }
Дата док-та
    …
              class MyDoc {
                  MyDoc(Date date) {
                      docDate = date;
                      …
                  }
Требования к такому
     «транспортному» классу:
• Как и интерфейс должен
  «жить и мыслиться» вместе с тем
  классом, который его использует
• Минималистичный
 (только те данные, которые нужны)
• Immutable
• Должны легко конструироваться в любом
  состоянии (для тестирования – a la Mock в
 случае интерфейсов)
• Сериализуемые (для транспорта)
Это как карпускулярно-
  волновой дуализм




 Иногда удобнее так, иногда сяк.
  Полезно владеть и тем и тем.
Лучше сильно не увлекаться:

• Anemic Model
 http://martinfowler.com/bliki/AnemicDomainModel.html
1. Классы и их
    взаимодействие
1.2. MVP и Entity-Repository
Классика жанра
• Model-View-Presenter (MVP)
• Entity-Repository
Presentation           Appl. Logic   Domain




               IView
   View                  Presenter   Model




 SomeControl
Как декомпозировать
  сложную форму?
Event Aggregator
 aka Message Bus
См. http://martinfowler.com/eaaDev/EventAggregator.html
1. Классы и их
  взаимодействие
1.3. Про наследование
Наследование –
тоже вид зависимости,
  причем опасный

          A




          B
1. Общие для нескольких классов
  helper-методы и данные к ним


               BaseQuery




   EntityQuery<T>          Query
Base
           Class




ClassA   ClassB
class Mission {
    protected string Id { get; set; }

    protected DateTime WhatTimeIsItNow() {
        // ...
    }
}

class FlyOnTheMoon : Mission {
    EngineCommand DetermineNextAction() {
        // ...
        var time = WhatTimeIsItNow();
        // ...
    }
}

class SleepInTheBed : Mission {
    bool ShouldIWakeUp() {
        // ...
        var time = WhatTimeIsItNow();
        // ...
    }
}
Характерные признаки
• Как правило, наследников мало
• Не предполагается написание «своих»
  наследников
  o базовый класс сурово заточен под нужды своих конкретных
    наследников и не предполагает других наследников

• Сам базовый класс нигде в API не фигурирует
  o его использование лишено смысла!

• При правках в наследниках очень часто
  приходится подкручивать в базовом классе
2. Расширение функциональности
 за счет перекрытия виртуальных
         protected-методов

             Control
          OnMouseMove()



            МуControl
          OnMouseMove()
Умный и
мощный класс
(«на все случаи
   жизни»)




      Его
    исполь-
    зование
Характерные признаки
• Виртуальные методы, которые активно
  перекрываются в наследниках
• Сам базовый класс инкапсулирует какую-то
  общую «идею» (обобщенный алгоритм,
  обобщенный компонент), которая лишена
  смысла без «правильного» перекрытия
  виртуальных методов
• Часто сочетается с (1)
• Массивными override-ами можно
  чуть менее чем полностью изменить поведение
  базового класса
3. Отражение отношения
      «является» (is)
               Человек
              Дышать()



    Мужчина              Женщина

Бриться()           Рожать()
ПитьПиво()          Готовить()
СмотретьФутбол()    Убираться()
ClassB

ClassA



     BaseClass
      
The Liskov Substitution
      Principle (LSP)
If for each object o1 of type S there is an
object o2 of type T such that for all
programs P defined in terms of T, the
behavior of P is unchanged when o1 is
substituted for o2 then S is a subtype of T.
                                       1988
GIVEN

   S         o1


                              P(arg: T)
   T         o2



                   WHEN

o1 o2 : P ResultOf[P(o1)]  ResultOf[P(o2)]

                   THEN

             T                 S
Это проясняет отношение
     «является» (is)
       Rectangle
        Width
        Height




        Square     При присваивании
                    Width синхронно
                   меняется Height и
                       наоборот
Design-by-Contract
• Контракт базового класса не
  должен нарушаться наследниками

            Rectangle
              Width
              Height



             Square     При присваивании
                         Width синхронно
                        меняется Height и
                            наоборот
Как быть?
• Interface over Inheritance
• Composition over Inheritance
• Delegation over Inheritance
1. Классы и их
     взаимодействие
1.4. Design by Contract (DbC)
Просто
                 сигнатуры
                методов не
               хватает, чтобы
                описать API
                    (как
I1
                требуемое,
I2                 так и
     MyClass   предоставляе
I3                 мое)
Три кита DbC:
                               Rectangle
• Пред-условия                   Width
   Пример:   w >= 0              Height
                                 Angle
• Пост-условия                setWidth(w)
   Пример:   Width == w
             Height == OldValue(Height)
• Инварианты
   Пример:   Angle == 90
Инструментарий
• Java: cofoja (by google)
                           @Requires({
                             "h >= 0",
                             "h <= 23"
                           })
                           @Ensures("getHour() == h")
                           void setHour(int h);



• C#: CodeContracts (by MS research)
                     [ContractClassFor(typeof(IMy))]
                     sealed class ContractForMy : IMy {
                         void setHour(int h) {
                             Contract.Requires(h >= 0);
                             Contract.Requires(h <= 23);
                             Contract.Ensures(Hour == h);
                         }
Полезен не статический анализ (он у всех хромает),
    а то, что разработчик думает о контракте
               и явно декларирует его
1. Классы и их
взаимодействие
  1.5. Что еще
Избавление от if-ов
•   State
•   Strategy
•   Null-Object
•   Specification
2. Модуль
За всж приходиться платить:




    Лазанья-код (aka пахлава-код)
Добавление атрибута
          сущности:

1. СУБД: поле в таблице
2. Репозиторий (как минимум метаданные Hibernate)
3. [in-memory репозиторий]
4. Сущность
5. Data Transfer Object (DTO)
6. Presenter (N штук)
7. View (N штук)
8. А еще unit-тесты 
Как выкручиваться?
• Функциональное программирование
 o Задачи трансформации и обработки данных


• Аспектно-ориентированное
  программирование
 o Журналирование, проверка прав, валидация …


• Декларативное программирование,
  DSL
 o Всѐ остальное рутинное 
Пример 1:
         IView
View              Presenter                Model




       Model-View-ViewModel
                    View
View    magic                              Model
                    Model

        Декларативное описание привязки свойств
           и событий контролов к свойствам и
                 командам ViewModel
Пример 2:
• Типовой атрибут:
  o   Метаданные, описывающие тип значения
  o   Метаданные, описывающие хранение
  o   Метаданные, описывающие способ редактирования на UI
  o   [Метаданные, описывающие права доступа]
  o   [Метаданные, описывающие кеширование]


• По ним «генерируется»:
  o   Обновление структуры БД
  o   Кусок кода сущности
  o   Реализация в классе репозитория
  o   Реализация GUI -контрола
Способы генерации:
• Runtime
• Post-compile time (e.g. code-rewrite)
• Additional code generation
Мета-программирование:
• Нельзя сильно увлекаться –
  появляется своя слабо познаваемая эклектика
  и “зюко-хрючный” синтаксис

• Тяжело обеспечить адекватным
  инструментарием для удобной работы с
  метаданными

• Должна быть возможность всегда просто
  вставить императивный код (Ant vs. Scons)
DSL: JetBrains MPS
Пока больше распространены:

• Java: Groovy
• .Net: Boo
3. Взаимодействие
     модулей
Проще всего так:
 App. Logic   App. Logic




  Domain       Domain




 DBMS “A”     DBMS “B”



 Модуль 1     Модуль 2
Ущербность такого подхода
      поняли давно
  и используют сервисы



      и всѐ это загажено
   маркетинговым булшитом 
Приемы проектирования
       аналогичны:
• Контракт на API (интерфейс) +
  Data Contract

• Подсистемы-адаптеры

• Шина
Серьезное «НО»:


Abstraction Penalty
Примеры борьбы:
• Накладные расходы на транспорт
 o SOAP => REST


• Распределенные транзакции
 o Double-check commit => Идемпотентные операции




          упрощение абстракций!
Идемпотентные операции:
• Повторный вызов ничего не ломает и
  ничего не дублирует
  o Просто выполняет действие, если до этого оно почему-
    то не было завершено
  o Если же операция уже была выполнена, то ничего не
    делая, возвращает результат еѐ выполнения


• Очень легко реализуется
  o Желающим расскажу отдельно 
4. Итог
Зачем всж так сложно?!
• Основная ценность – работающий код!

• Если вы практикуете unit-тестинг, то следующая
  ценность – тестопригодный код

• Чтобы не накапливать технический долг и не
  становиться заложником кода –
  понятный и сопровождаемый код


      код, который легко сопровождать и развивать,
         писать сложнее и дольше, чем просто
                    работающий код
макет / мини-тула   что-то большое
Если вы согласны
      потратить доп.усилия:
1. Research / Алгоритмика / Высокие тех. риски:

                     Слабо связный,            Ясный и
Работающий
                     тестопригодный             чистый
    код
                       код [+ тесты]              код


2. Уже есть опыт (по аналогии) / Если вы очень крутой:
           Слабо связный,                Ясный и
           тестопригодный                 чистый
             код [+ тесты]                  код
Agile как Буддизм
•   S.O.L.I.D. принципы
•   закон Деметры + Tell, don’t ask
•   DbC
•   Composition/Delegation over Inheritance
•   функциональное программирование
•   мета-программирование и DSL
•   REST
•   индемпотентные сервисы
•   …
              Это не заповеди
    Это направления возможных улучшений
Спасибо за внимание!

         Вопросы?

         bibigone@gmail.com
               @bibigine
http://www.google.com/profiles/biBIGone
   http://www.slideshare.net/bibigine

Más contenido relacionado

La actualidad más candente

Лекция 6_принципы ООП : инкапсуляция, наследование
Лекция 6_принципы ООП : инкапсуляция, наследованиеЛекция 6_принципы ООП : инкапсуляция, наследование
Лекция 6_принципы ООП : инкапсуляция, наследованиеmetaform
 
Работа с БД в Java
Работа с БД в JavaРабота с БД в Java
Работа с БД в Javametaform
 
Классы и объекты в Java
Классы и объекты в JavaКлассы и объекты в Java
Классы и объекты в Javametaform
 
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.Igor Shkulipa
 
C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.Igor Shkulipa
 
Классы и объекты в Java
Классы и объекты в JavaКлассы и объекты в Java
Классы и объекты в Javametaform
 
C++ STL & Qt. Занятие 07.
C++ STL & Qt. Занятие 07.C++ STL & Qt. Занятие 07.
C++ STL & Qt. Занятие 07.Igor Shkulipa
 
JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.Igor Shkulipa
 
работа с потоками ввода вывода
работа с потоками ввода выводаработа с потоками ввода вывода
работа с потоками ввода выводаmetaform
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.Igor Shkulipa
 
C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.Igor Shkulipa
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5Technopark
 
Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.Anton Moiseenko
 
C# Desktop. Занятие 07.
C# Desktop. Занятие 07.C# Desktop. Занятие 07.
C# Desktop. Занятие 07.Igor Shkulipa
 
"Analysis and Design Principles within OOP. Inheritance forbiddance problem i...
"Analysis and Design Principles within OOP. Inheritance forbiddance problem i..."Analysis and Design Principles within OOP. Inheritance forbiddance problem i...
"Analysis and Design Principles within OOP. Inheritance forbiddance problem i...Fwdays
 
принципы ооп и программирование классов в C#
принципы ооп и программирование классов в C#принципы ооп и программирование классов в C#
принципы ооп и программирование классов в C#bolevik
 
Java осень 2014 занятие 3
Java осень 2014 занятие 3Java осень 2014 занятие 3
Java осень 2014 занятие 3Technopark
 
JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.Igor Shkulipa
 
2014-08-02 01 Егор Непомнящих. jWidget - очередной MV*-фреймворк
2014-08-02 01 Егор Непомнящих. jWidget - очередной MV*-фреймворк2014-08-02 01 Егор Непомнящих. jWidget - очередной MV*-фреймворк
2014-08-02 01 Егор Непомнящих. jWidget - очередной MV*-фреймворкОмские ИТ-субботники
 

La actualidad más candente (20)

Лекция 6_принципы ООП : инкапсуляция, наследование
Лекция 6_принципы ООП : инкапсуляция, наследованиеЛекция 6_принципы ООП : инкапсуляция, наследование
Лекция 6_принципы ООП : инкапсуляция, наследование
 
Работа с БД в Java
Работа с БД в JavaРабота с БД в Java
Работа с БД в Java
 
Классы и объекты в Java
Классы и объекты в JavaКлассы и объекты в Java
Классы и объекты в Java
 
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.
 
C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.
 
Классы и объекты в Java
Классы и объекты в JavaКлассы и объекты в Java
Классы и объекты в Java
 
JRebel
JRebelJRebel
JRebel
 
C++ STL & Qt. Занятие 07.
C++ STL & Qt. Занятие 07.C++ STL & Qt. Занятие 07.
C++ STL & Qt. Занятие 07.
 
JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.
 
работа с потоками ввода вывода
работа с потоками ввода выводаработа с потоками ввода вывода
работа с потоками ввода вывода
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.
 
C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5
 
Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.
 
C# Desktop. Занятие 07.
C# Desktop. Занятие 07.C# Desktop. Занятие 07.
C# Desktop. Занятие 07.
 
"Analysis and Design Principles within OOP. Inheritance forbiddance problem i...
"Analysis and Design Principles within OOP. Inheritance forbiddance problem i..."Analysis and Design Principles within OOP. Inheritance forbiddance problem i...
"Analysis and Design Principles within OOP. Inheritance forbiddance problem i...
 
принципы ооп и программирование классов в C#
принципы ооп и программирование классов в C#принципы ооп и программирование классов в C#
принципы ооп и программирование классов в C#
 
Java осень 2014 занятие 3
Java осень 2014 занятие 3Java осень 2014 занятие 3
Java осень 2014 занятие 3
 
JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.
 
2014-08-02 01 Егор Непомнящих. jWidget - очередной MV*-фреймворк
2014-08-02 01 Егор Непомнящих. jWidget - очередной MV*-фреймворк2014-08-02 01 Егор Непомнящих. jWidget - очередной MV*-фреймворк
2014-08-02 01 Егор Непомнящих. jWidget - очередной MV*-фреймворк
 

Destacado

Обзор Feature-Driven Development и Domain-Driven Design
Обзор Feature-Driven Development и Domain-Driven DesignОбзор Feature-Driven Development и Domain-Driven Design
Обзор Feature-Driven Development и Domain-Driven DesignAndrey Bibichev
 
О текстовом вводе замолвите слово
О текстовом вводе замолвите словоО текстовом вводе замолвите слово
О текстовом вводе замолвите словоAndrey Bibichev
 
Пользовательский автоматизм
Пользовательский автоматизмПользовательский автоматизм
Пользовательский автоматизмAndrey Bibichev
 
Usability-for-programmers
Usability-for-programmersUsability-for-programmers
Usability-for-programmersAndrey Bibichev
 
Фрактальная природа IT-проектов (блиц)
Фрактальная природа IT-проектов (блиц)Фрактальная природа IT-проектов (блиц)
Фрактальная природа IT-проектов (блиц)Andrey Bibichev
 
Быстрое введение в TDD от А до Я
Быстрое введение в TDD от А до ЯБыстрое введение в TDD от А до Я
Быстрое введение в TDD от А до ЯAndrey Bibichev
 
О usability водопроводных кранов
О usability водопроводных крановО usability водопроводных кранов
О usability водопроводных крановAndrey Bibichev
 
Role of MySQL in Data Analytics, Warehousing
Role of MySQL in Data Analytics, WarehousingRole of MySQL in Data Analytics, Warehousing
Role of MySQL in Data Analytics, WarehousingVenu Anuganti
 
Geeks vs Managers (part 2)
Geeks vs Managers (part 2)Geeks vs Managers (part 2)
Geeks vs Managers (part 2)Andrey Bibichev
 
Designing Scalable Data Warehouse Using MySQL
Designing Scalable Data Warehouse Using MySQLDesigning Scalable Data Warehouse Using MySQL
Designing Scalable Data Warehouse Using MySQLVenu Anuganti
 

Destacado (17)

Обзор Feature-Driven Development и Domain-Driven Design
Обзор Feature-Driven Development и Domain-Driven DesignОбзор Feature-Driven Development и Domain-Driven Design
Обзор Feature-Driven Development и Domain-Driven Design
 
Geeks vs Managers
Geeks vs ManagersGeeks vs Managers
Geeks vs Managers
 
Agile: Think different
Agile: Think differentAgile: Think different
Agile: Think different
 
О текстовом вводе замолвите слово
О текстовом вводе замолвите словоО текстовом вводе замолвите слово
О текстовом вводе замолвите слово
 
Пользовательский автоматизм
Пользовательский автоматизмПользовательский автоматизм
Пользовательский автоматизм
 
Puasson burning
Puasson burningPuasson burning
Puasson burning
 
Mockist vs Classicist
Mockist vs ClassicistMockist vs Classicist
Mockist vs Classicist
 
Usability-for-programmers
Usability-for-programmersUsability-for-programmers
Usability-for-programmers
 
Фрактальная природа IT-проектов (блиц)
Фрактальная природа IT-проектов (блиц)Фрактальная природа IT-проектов (блиц)
Фрактальная природа IT-проектов (блиц)
 
Быстрое введение в TDD от А до Я
Быстрое введение в TDD от А до ЯБыстрое введение в TDD от А до Я
Быстрое введение в TDD от А до Я
 
Tdd and decomposition
Tdd and decompositionTdd and decomposition
Tdd and decomposition
 
DDD Workshop
DDD WorkshopDDD Workshop
DDD Workshop
 
О usability водопроводных кранов
О usability водопроводных крановО usability водопроводных кранов
О usability водопроводных кранов
 
Role of MySQL in Data Analytics, Warehousing
Role of MySQL in Data Analytics, WarehousingRole of MySQL in Data Analytics, Warehousing
Role of MySQL in Data Analytics, Warehousing
 
Domain Event - The Hidden Gem of DDD
Domain Event - The Hidden Gem of DDDDomain Event - The Hidden Gem of DDD
Domain Event - The Hidden Gem of DDD
 
Geeks vs Managers (part 2)
Geeks vs Managers (part 2)Geeks vs Managers (part 2)
Geeks vs Managers (part 2)
 
Designing Scalable Data Warehouse Using MySQL
Designing Scalable Data Warehouse Using MySQLDesigning Scalable Data Warehouse Using MySQL
Designing Scalable Data Warehouse Using MySQL
 

Similar a Архитектура в Agile: слабая связность

JavaScript design patterns overview
JavaScript design patterns overview JavaScript design patterns overview
JavaScript design patterns overview Kseniya Redunova
 
Проектирование архитектуры приложений
Проектирование архитектуры приложенийПроектирование архитектуры приложений
Проектирование архитектуры приложенийAndrew Mayorov
 
Фундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоФундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоStanfy
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПzfconfua
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПKirill Chebunin
 
Convert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at VizorConvert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at VizorDevGAMM Conference
 
разработка бизнес приложений (8)
разработка бизнес приложений (8)разработка бизнес приложений (8)
разработка бизнес приложений (8)Alexander Gornik
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013ScalaNsk
 
разработка бизнес приложений (7)
разработка бизнес приложений (7)разработка бизнес приложений (7)
разработка бизнес приложений (7)Alexander Gornik
 
"Рекомендации по проектированию API" — Марина Степанова, Яндекс
"Рекомендации по проектированию API" — Марина Степанова, Яндекс"Рекомендации по проектированию API" — Марина Степанова, Яндекс
"Рекомендации по проектированию API" — Марина Степанова, ЯндексYandex
 
Синяя Борода. История одного проекта.
Синяя Борода. История одного проекта.Синяя Борода. История одного проекта.
Синяя Борода. История одного проекта.Andrew Mayorov
 
Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Как пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на SwiftКак пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на SwiftAnton Loginov
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Sergey Platonov
 
"Рекомендации по проектированию API". Марина Степанова, Яндекс
"Рекомендации по проектированию API". Марина Степанова, Яндекс"Рекомендации по проектированию API". Марина Степанова, Яндекс
"Рекомендации по проектированию API". Марина Степанова, ЯндексYandex
 
ук 03.001.02 2011
ук 03.001.02 2011ук 03.001.02 2011
ук 03.001.02 2011etyumentcev
 
Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Yandex
 
Opensource на .NET
Opensource на .NETOpensource на .NET
Opensource на .NETlugnsk
 

Similar a Архитектура в Agile: слабая связность (20)

JavaScript design patterns overview
JavaScript design patterns overview JavaScript design patterns overview
JavaScript design patterns overview
 
Проектирование архитектуры приложений
Проектирование архитектуры приложенийПроектирование архитектуры приложений
Проектирование архитектуры приложений
 
Фундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоФундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел Тайкало
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОП
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОП
 
Convert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at VizorConvert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at Vizor
 
разработка бизнес приложений (8)
разработка бизнес приложений (8)разработка бизнес приложений (8)
разработка бизнес приложений (8)
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013
 
разработка бизнес приложений (7)
разработка бизнес приложений (7)разработка бизнес приложений (7)
разработка бизнес приложений (7)
 
"Рекомендации по проектированию API" — Марина Степанова, Яндекс
"Рекомендации по проектированию API" — Марина Степанова, Яндекс"Рекомендации по проектированию API" — Марина Степанова, Яндекс
"Рекомендации по проектированию API" — Марина Степанова, Яндекс
 
Refactoring
RefactoringRefactoring
Refactoring
 
Синяя Борода. История одного проекта.
Синяя Борода. История одного проекта.Синяя Борода. История одного проекта.
Синяя Борода. История одного проекта.
 
Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложений
 
Как пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на SwiftКак пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на Swift
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
"Рекомендации по проектированию API". Марина Степанова, Яндекс
"Рекомендации по проектированию API". Марина Степанова, Яндекс"Рекомендации по проектированию API". Марина Степанова, Яндекс
"Рекомендации по проектированию API". Марина Степанова, Яндекс
 
BDD
BDDBDD
BDD
 
ук 03.001.02 2011
ук 03.001.02 2011ук 03.001.02 2011
ук 03.001.02 2011
 
Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"
 
Opensource на .NET
Opensource на .NETOpensource на .NET
Opensource на .NET
 

Más de Andrey Bibichev

Natural User Interface (WUDRU-2011)
Natural User Interface (WUDRU-2011)Natural User Interface (WUDRU-2011)
Natural User Interface (WUDRU-2011)Andrey Bibichev
 
Проектирование больших ИС в Agile (статья)
Проектирование больших ИС в Agile (статья)Проектирование больших ИС в Agile (статья)
Проектирование больших ИС в Agile (статья)Andrey Bibichev
 
Проектирование больших ИС в Agile
Проектирование больших ИС в AgileПроектирование больших ИС в Agile
Проектирование больших ИС в AgileAndrey Bibichev
 
Enterprise Level Agile The Art Of Start
Enterprise Level Agile   The Art Of StartEnterprise Level Agile   The Art Of Start
Enterprise Level Agile The Art Of StartAndrey Bibichev
 
Humane Interface (Гуманный интерфейс)
Humane Interface (Гуманный интерфейс)Humane Interface (Гуманный интерфейс)
Humane Interface (Гуманный интерфейс)Andrey Bibichev
 
Безудержный рефакторинг: как не убиться об стену
Безудержный рефакторинг: как не убиться об стенуБезудержный рефакторинг: как не убиться об стену
Безудержный рефакторинг: как не убиться об стенуAndrey Bibichev
 
Практика внедрения Scrum (статья)
Практика внедрения Scrum (статья)Практика внедрения Scrum (статья)
Практика внедрения Scrum (статья)Andrey Bibichev
 
Практика внедрения Scrum
Практика внедрения ScrumПрактика внедрения Scrum
Практика внедрения ScrumAndrey Bibichev
 
Аналитик в Agile (статья)
Аналитик в Agile (статья)Аналитик в Agile (статья)
Аналитик в Agile (статья)Andrey Bibichev
 
А какой у вас Agile: свежевыжатый или порошковый?
А какой у вас Agile: свежевыжатый или порошковый?А какой у вас Agile: свежевыжатый или порошковый?
А какой у вас Agile: свежевыжатый или порошковый?Andrey Bibichev
 
Аналитик в Agile (SEF-09)
Аналитик в Agile (SEF-09)Аналитик в Agile (SEF-09)
Аналитик в Agile (SEF-09)Andrey Bibichev
 

Más de Andrey Bibichev (12)

Natural User Interface (WUDRU-2011)
Natural User Interface (WUDRU-2011)Natural User Interface (WUDRU-2011)
Natural User Interface (WUDRU-2011)
 
Augmented Reality
Augmented RealityAugmented Reality
Augmented Reality
 
Проектирование больших ИС в Agile (статья)
Проектирование больших ИС в Agile (статья)Проектирование больших ИС в Agile (статья)
Проектирование больших ИС в Agile (статья)
 
Проектирование больших ИС в Agile
Проектирование больших ИС в AgileПроектирование больших ИС в Agile
Проектирование больших ИС в Agile
 
Enterprise Level Agile The Art Of Start
Enterprise Level Agile   The Art Of StartEnterprise Level Agile   The Art Of Start
Enterprise Level Agile The Art Of Start
 
Humane Interface (Гуманный интерфейс)
Humane Interface (Гуманный интерфейс)Humane Interface (Гуманный интерфейс)
Humane Interface (Гуманный интерфейс)
 
Безудержный рефакторинг: как не убиться об стену
Безудержный рефакторинг: как не убиться об стенуБезудержный рефакторинг: как не убиться об стену
Безудержный рефакторинг: как не убиться об стену
 
Практика внедрения Scrum (статья)
Практика внедрения Scrum (статья)Практика внедрения Scrum (статья)
Практика внедрения Scrum (статья)
 
Практика внедрения Scrum
Практика внедрения ScrumПрактика внедрения Scrum
Практика внедрения Scrum
 
Аналитик в Agile (статья)
Аналитик в Agile (статья)Аналитик в Agile (статья)
Аналитик в Agile (статья)
 
А какой у вас Agile: свежевыжатый или порошковый?
А какой у вас Agile: свежевыжатый или порошковый?А какой у вас Agile: свежевыжатый или порошковый?
А какой у вас Agile: свежевыжатый или порошковый?
 
Аналитик в Agile (SEF-09)
Аналитик в Agile (SEF-09)Аналитик в Agile (SEF-09)
Аналитик в Agile (SEF-09)
 

Архитектура в Agile: слабая связность

  • 1. Архитектура в Agile: компоненты и модули слабая связность Бибичев Андрей март 2011
  • 2. @bibigine Андрей Бибичев • E-mail: bibigone@gmail.com • Twitter: @bibigine • Profile: http://www.google.com/profiles/biBIGone • Slideshare: http://www.slideshare.net/bibigine
  • 4. Alistair Cockburn: «starting with a walking skeleton, then evolving it iteratively» Mary and Tom Poppendieck: «divisible system architecture» Robert Martin (Uncle Bob): «No doubt that BDUF is harmful. Size matters! ‘B’ is bad, but ‘L’ is good. Indeed, LDUF is absolutely essential.»
  • 6. tr 'A-Z' 'a-z' <fnord.txt | tr -cs 'a-z' 'n' | sort | uniq | comm -23 - /usr/share/dict/words stdin params stdout
  • 7. Эволюция 1. goto 2. подпрограммы 3. динамические библиотеки 4. классы (ООП) 5. компоненты (COM/CORBA/…) 6. …
  • 8. Но что-то не легчает №1… Корнелис Киммель « Снежный ком»
  • 9.
  • 11. Но что-то не легчает №2… Код-гидра: один баг исправишь - несколько появляются
  • 12.
  • 13. Side-эффекты Могучий глобальный контекст + Мутабельность всего и вся + Избыточная область видимости = поправил здесь, отвалилось там
  • 14. Но что-то не легчает №3… GOD-classes
  • 15.
  • 16. WinForms.Net Класс Control: 100+ свойств (≈80% public) 400+ методов (≈30% public) 50+ событий (все public)
  • 17. Разработчик и GOD-класс А вокруг пустынно и уныло…
  • 18. История сложности одного файла и распределение числа check-in по файлам http://michaelfeathers.typepad.com/michael_feathers _blog/2011/03/data-rich-development.html
  • 19. Но что-то не легчает №4… «Рулонные функции»
  • 21.
  • 22.
  • 23. Типичные болезни: • Сильная связность • Неуловимые и непознаваемые side-эффекты • Вездесущий и всеобъемлющий глобальный контекст (привет любителям singletone-ов!) • GOD-классы • Переусложненный и запутанный workflow • Дублирование логики • …
  • 24.
  • 25. Мечтали о: А выходит так:
  • 26. 1. Классы и их взаимодействие
  • 27. 1. Классы и их взаимодействие 1.0. Ремарка
  • 28. Для процедурных языков • Класс => Структура + функции для неѐ struct a { double f(struct a* p, double k) { int v; return p->v * p->d / k; double d; } }; • Интерфейс => Структура указателей на функции (вспомним как работают вызовы к DLL!) struct i { f1_t f1; typedef void (*f1_t)(int s); f2_t f2; typedef double (*f2_t)(); }; • Наследование => Композиция struct b { struct a super; };
  • 29. 1. Классы и их взаимодействие 1.1. Современное ООП
  • 30. Длинные «руки» объекта:  если ему чего нужно, то он сам за этим тянется
  • 31. Укорачиваем руки: • Inversion-of-Control (IoC) • Law of Demeter • Tell, Don’t Ask
  • 32. Inversion of Control (IoC) «Consumer» Компонент SomeConsumer Компонент «Provider» SomeProvider
  • 33. Inversion of Control (IoC) «Consumer» Компонент SomeConsumer Компонент «Provider» «interface» SomeProviderImpl ISomeProvider
  • 34. Inversion of Control (IoC) «Consumer» Компонент «interface» SomeConsumer ISomeProvider Компонент «Provider» SomeProviderImpl
  • 35. I1 I2 MyClass I3 Что нужно «Торчащий» для работы API
  • 36. Как передать имплементации интерфейсов объекту класса? • Dependency Injection через конструктор MyClass { MyClass(I1 o1, I2 o2) { … }  • DI через свойство/set-метод MyClass { setI1(I1 o1) { … }  • Service Locator o1 = MegaContext.resolve<I1>(); 
  • 37. Law of Demeter Any method of an object should only call methods belonging to: • itself. • any parameters that were passed in to the method. • any objects it created. • any composite objects.
  • 38.
  • 39. Следствия : • Global context (включая Service Locator) MegaContext.Singletone.get<IService>().do() • Цепочки вызовов field.getSmth().getSmthElse().Prop.Count : • True singletone (e.g. Null Objet)
  • 40. А работа с фабрикой? void doSmth(ISomeFactory someFactory) { ISome some = someFactory.createSome(); some.act(); // someFactory.createSome().act(); • Казалось бы, работа с фабрикой нарушает принцип Диметры • Относитесь к фабрике как к переопределению оператора new. Тогда всѐ становится нормально: «any objects it created»
  • 41. Tell, Don’t Ask Procedural code gets information then makes decisions. Object-oriented code tells objects to do things. — Alec Sharp
  • 42. void myFunc(Obj obj) { if (!obj.init()) throw new …; String id = obj.getId(); log.write(“starting transaction with “ + id); if (obj.supportTransaction()) { if (!obj.startTransaction()) throw new …; Photo photo = obj.GetPhoto(); if (!analyzePhoto(photo)) { obj.rollback(); obj.kill(); } else { obj.act(); } } }
  • 43. me: Привет! obj: Хай! /* me: Ага, ответила, значит продолжаем разговор */ me: Как тебя зовут? obj: Саша me: Саша – красивое имя! /* me: Блин, мужик или баба?! */ me: А полное имя Александр или Александра? obj: Александра /* me: Ура! Баба! */ me: Здорово! Давай куда-нить сходим? obj: Давай. Только куда? me: В клуб. Только как я тебя узнаю? Пришли фотку obj: Держи /* me: Фу */ me: == disconnected ==
  • 44. Минусы «чата»: • Сложный интерфейс • Тесная связность => С высокой вероятностью придется согласованно править в двух местах • Попахивает нарушением инкапсуляции
  • 45. Инкапсулировать в другом месте interface IObj { void performInTransaction(Callback action); } Где риализовывать: • Либо в классе, с которым мы общаемся • Либо сделать специализированный wrapper
  • 46. Декларативный стиль в императивных языках • Иди на кухню • Возьми чашку • Налей туда заварки • Мне бы чаю • Добавь кипятку • Две ложки сахара • Поставь на блюдце • Принеси мне
  • 47. Дуализм: интерфейс vs. данные class MyDoc { MyDoc(ICurrentDateProvider cdp) { docDate = cdp.get(); … Документ } Дата док-та … class MyDoc { MyDoc(Date date) { docDate = date; … }
  • 48. Требования к такому «транспортному» классу: • Как и интерфейс должен «жить и мыслиться» вместе с тем классом, который его использует • Минималистичный (только те данные, которые нужны) • Immutable • Должны легко конструироваться в любом состоянии (для тестирования – a la Mock в случае интерфейсов) • Сериализуемые (для транспорта)
  • 49. Это как карпускулярно- волновой дуализм Иногда удобнее так, иногда сяк. Полезно владеть и тем и тем.
  • 50. Лучше сильно не увлекаться: • Anemic Model http://martinfowler.com/bliki/AnemicDomainModel.html
  • 51. 1. Классы и их взаимодействие 1.2. MVP и Entity-Repository
  • 53. Presentation Appl. Logic Domain IView View Presenter Model SomeControl
  • 54.
  • 55.
  • 56.
  • 57. Как декомпозировать сложную форму?
  • 58.
  • 59. Event Aggregator aka Message Bus
  • 61.
  • 62. 1. Классы и их взаимодействие 1.3. Про наследование
  • 63. Наследование – тоже вид зависимости, причем опасный A B
  • 64. 1. Общие для нескольких классов helper-методы и данные к ним BaseQuery EntityQuery<T> Query
  • 65. Base Class ClassA ClassB
  • 66. class Mission { protected string Id { get; set; } protected DateTime WhatTimeIsItNow() { // ... } } class FlyOnTheMoon : Mission { EngineCommand DetermineNextAction() { // ... var time = WhatTimeIsItNow(); // ... } } class SleepInTheBed : Mission { bool ShouldIWakeUp() { // ... var time = WhatTimeIsItNow(); // ... } }
  • 67. Характерные признаки • Как правило, наследников мало • Не предполагается написание «своих» наследников o базовый класс сурово заточен под нужды своих конкретных наследников и не предполагает других наследников • Сам базовый класс нигде в API не фигурирует o его использование лишено смысла! • При правках в наследниках очень часто приходится подкручивать в базовом классе
  • 68. 2. Расширение функциональности за счет перекрытия виртуальных protected-методов Control OnMouseMove() МуControl OnMouseMove()
  • 69. Умный и мощный класс («на все случаи жизни») Его исполь- зование
  • 70. Характерные признаки • Виртуальные методы, которые активно перекрываются в наследниках • Сам базовый класс инкапсулирует какую-то общую «идею» (обобщенный алгоритм, обобщенный компонент), которая лишена смысла без «правильного» перекрытия виртуальных методов • Часто сочетается с (1) • Массивными override-ами можно чуть менее чем полностью изменить поведение базового класса
  • 71. 3. Отражение отношения «является» (is) Человек Дышать() Мужчина Женщина Бриться() Рожать() ПитьПиво() Готовить() СмотретьФутбол() Убираться()
  • 72. ClassB ClassA BaseClass
  • 73.  
  • 74. The Liskov Substitution Principle (LSP) If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T. 1988
  • 75.
  • 76. GIVEN S o1 P(arg: T) T o2 WHEN o1 o2 : P ResultOf[P(o1)]  ResultOf[P(o2)] THEN T S
  • 77. Это проясняет отношение «является» (is) Rectangle Width Height Square При присваивании Width синхронно меняется Height и наоборот
  • 78. Design-by-Contract • Контракт базового класса не должен нарушаться наследниками Rectangle Width Height Square При присваивании Width синхронно меняется Height и наоборот
  • 79. Как быть? • Interface over Inheritance • Composition over Inheritance • Delegation over Inheritance
  • 80. 1. Классы и их взаимодействие 1.4. Design by Contract (DbC)
  • 81. Просто сигнатуры методов не хватает, чтобы описать API (как I1 требуемое, I2 так и MyClass предоставляе I3 мое)
  • 82. Три кита DbC: Rectangle • Пред-условия Width Пример: w >= 0 Height Angle • Пост-условия setWidth(w) Пример: Width == w Height == OldValue(Height) • Инварианты Пример: Angle == 90
  • 83. Инструментарий • Java: cofoja (by google) @Requires({ "h >= 0", "h <= 23" }) @Ensures("getHour() == h") void setHour(int h); • C#: CodeContracts (by MS research) [ContractClassFor(typeof(IMy))] sealed class ContractForMy : IMy { void setHour(int h) { Contract.Requires(h >= 0); Contract.Requires(h <= 23); Contract.Ensures(Hour == h); }
  • 84. Полезен не статический анализ (он у всех хромает), а то, что разработчик думает о контракте и явно декларирует его
  • 85. 1. Классы и их взаимодействие 1.5. Что еще
  • 86. Избавление от if-ов • State • Strategy • Null-Object • Specification
  • 88. За всж приходиться платить: Лазанья-код (aka пахлава-код)
  • 89. Добавление атрибута сущности: 1. СУБД: поле в таблице 2. Репозиторий (как минимум метаданные Hibernate) 3. [in-memory репозиторий] 4. Сущность 5. Data Transfer Object (DTO) 6. Presenter (N штук) 7. View (N штук) 8. А еще unit-тесты 
  • 90. Как выкручиваться? • Функциональное программирование o Задачи трансформации и обработки данных • Аспектно-ориентированное программирование o Журналирование, проверка прав, валидация … • Декларативное программирование, DSL o Всѐ остальное рутинное 
  • 91. Пример 1: IView View Presenter Model Model-View-ViewModel View View magic Model Model Декларативное описание привязки свойств и событий контролов к свойствам и командам ViewModel
  • 92.
  • 93. Пример 2: • Типовой атрибут: o Метаданные, описывающие тип значения o Метаданные, описывающие хранение o Метаданные, описывающие способ редактирования на UI o [Метаданные, описывающие права доступа] o [Метаданные, описывающие кеширование] • По ним «генерируется»: o Обновление структуры БД o Кусок кода сущности o Реализация в классе репозитория o Реализация GUI -контрола
  • 94. Способы генерации: • Runtime • Post-compile time (e.g. code-rewrite) • Additional code generation
  • 95. Мета-программирование: • Нельзя сильно увлекаться – появляется своя слабо познаваемая эклектика и “зюко-хрючный” синтаксис • Тяжело обеспечить адекватным инструментарием для удобной работы с метаданными • Должна быть возможность всегда просто вставить императивный код (Ant vs. Scons)
  • 99. Проще всего так: App. Logic App. Logic Domain Domain DBMS “A” DBMS “B” Модуль 1 Модуль 2
  • 100. Ущербность такого подхода поняли давно и используют сервисы и всѐ это загажено маркетинговым булшитом 
  • 101. Приемы проектирования аналогичны: • Контракт на API (интерфейс) + Data Contract • Подсистемы-адаптеры • Шина
  • 103. Примеры борьбы: • Накладные расходы на транспорт o SOAP => REST • Распределенные транзакции o Double-check commit => Идемпотентные операции упрощение абстракций!
  • 104. Идемпотентные операции: • Повторный вызов ничего не ломает и ничего не дублирует o Просто выполняет действие, если до этого оно почему- то не было завершено o Если же операция уже была выполнена, то ничего не делая, возвращает результат еѐ выполнения • Очень легко реализуется o Желающим расскажу отдельно 
  • 106. Зачем всж так сложно?! • Основная ценность – работающий код! • Если вы практикуете unit-тестинг, то следующая ценность – тестопригодный код • Чтобы не накапливать технический долг и не становиться заложником кода – понятный и сопровождаемый код код, который легко сопровождать и развивать, писать сложнее и дольше, чем просто работающий код
  • 107. макет / мини-тула что-то большое
  • 108. Если вы согласны потратить доп.усилия: 1. Research / Алгоритмика / Высокие тех. риски: Слабо связный, Ясный и Работающий тестопригодный чистый код код [+ тесты] код 2. Уже есть опыт (по аналогии) / Если вы очень крутой: Слабо связный, Ясный и тестопригодный чистый код [+ тесты] код
  • 109. Agile как Буддизм • S.O.L.I.D. принципы • закон Деметры + Tell, don’t ask • DbC • Composition/Delegation over Inheritance • функциональное программирование • мета-программирование и DSL • REST • индемпотентные сервисы • … Это не заповеди Это направления возможных улучшений
  • 110. Спасибо за внимание! Вопросы? bibigone@gmail.com @bibigine http://www.google.com/profiles/biBIGone http://www.slideshare.net/bibigine