ݺߣ

ݺߣShare a Scribd company logo
Проектирование
архитектуры приложений

      Андрей Майоров
          BYTE-force
      twitter.com/xorets
Программисты есть?
Системный подход




Niklaus Wirth       Larry Wall
Если не вы, то кот




                http://www.flickr.com/photos/deerwooduk/579761138/
Эволюция программы
Hello, World!*

// Hello World in C#
class HelloWorld
{
       static void Main()
       {
              System.Console.WriteLine("Hello, World!");
       }
}


* C#
Fortran*

C       Hello World in Fortran
        PROGRAM HELLO
        WRITE (*,100)
        STOP
    100 FORMAT (' Hello World! ' /)
        END




* В синтаксисе 1957 года
Километры кода




                 http://cluster-d.livejournal.com/435441.html
Неясно, куда класть код




                    http://www.flickr.com/photos/lofink/4501610335/
Архитектура приложения




                         «Полосатый рейс»
Универсальной архитектуры нет




                  http://mi9.com/wallpaper/transformers-hd-wallpaper_70683/
Плюшки хорошей архитектуры
• Можно развивать приложение
• Несложно поддерживать
• Все понятно
Архитектура 1.0




              http://www.fotoart.org.ua/displayimage.php?album=33&pos=7
Архитектура 1.0




                  http://tour.lipetsk-reisen.ru/archives/117
Архитектура 1.0




                  http://www.sky-towers.ru/
Архитектура 1.0




                  http://www.tournorfolk.co.uk/salhouse.html
Ограничения системы
It’s a Death Star!




        http://forum.gateworld.net/threads/82515-Proof-about-Stargate-s-relationship-to-Star-Trek-or-Star-Wars
Бета-версия




  http://acmepoug.ru/xronologiya/operacii-i-eksperimenty-na-mezhdunarodnoj-kosmicheskoj-stancii-19-iyulya-2011-goda.html
Архитектура* приложения




               * Один из срезов
Надо себя
ограничивать
Немного UML*



* Unified Modeling Language
Класс

Person
Атрибуты (свойства)

   Person
+Name
+PhoneNumber
Видимость

   Person
+Name
+PhoneNumber
-CallCount
Операции (методы)

   Person
+Name
+PhoneNumber
-CallCount
+Call()
Ассоциации

   Person                          Address
+Name            +HomeAddress +Country: string
+PhoneNumber                   +City: string
-CallCount                1..* +Street: string
+Call()                        +House: string
Наследование

   Person                           Address
+Name             +HomeAddress +Country: string
+PhoneNumber                    +City: string
-CallCount                 1..* +Street: string
+Call()                         +House: string




   Employee

+DelegateTask()
Интерфейс

   Person                            Address
+Name              +HomeAddress +Country: string
+PhoneNumber                     +City: string
-CallCount                  1..* +Street: string
+Call()                          +House: string




                                <<interface>>
   Employee
                                 IExecutor
+DelegateTask()                 +DelegateTask()
Принципы
    проектирования
(и разработки вообще)
KISS




       http://www.theconcertcreep.com/2012/03/motely-crue-kiss-expected-to-announce.html
K.I.S.S.




           http://www.sunny-cat.ru/page-id-601.html
YAGNI
 You ain’t
gonna need
    it!
DRY/DIE


Do not Repeat Yourself


Do not Repeat Yourself


  Duplication Is Evil
                         Andy Warhal
S   Single responsibility principle
O   Open/closed principle
L   Liskov substitution principle
I   Interface segregation principle
D   Dependency inversion principle
Single responsibility principle


Kаждый объект должен иметь одну
обязанность и эта обязанность должна
быть полностью инкапсулирована в класс.




SOLID
Open/closed principle


Классы должны быть открыты для
расширения, но закрыты для изменения.




SOLID
Liskov* substitution principle


Поведение класса-наследника не должно
противоречить поведению родительского
класса.




SOLID               * Барбара Лисков
Interface segregation principle


Клиенты не должны зависеть от методов,
которые они не используют




SOLID
Dependency inversion principle
Модули верхних уровней не должны
зависеть от модулей нижних уровней.
Модули должны зависеть от абстракций.

Абстракции не должны зависеть от
деталей. Детали должны зависеть от
абстракций.


SOLID
Принципы - это тест




                http://www.flickr.com/photos/jason_coleman/325107937/
Размер имеет значение




              http://www.asergeev.com/pictures/archives/compress/2011/936/20s.htm
http://hackedgadgets.com/2008/09/29/lego-v8-engine/
Bad practices
Сильная связность
                          GeoModule
     Application
                                         CountryFinder
    +GetCountry()


                          Countries

                                        GeoDataLayer

                                        +LoadCountry()




public Country GetCountry( int id )
{
  return geo.Countries.Finder.DataLayer.LoadCountry( id );
}
Глобальный контекст
                                      Subsystem3
         Subsystem1




                         OurContext                   Subsystem4

Application

+GetCountry()


                                         GeoSubsystem

                                                              GeoDataLayer
                      GeoModule   Countries   CountryFinder
                                                              +LoadCountry()
God class




            http://www.nrk.no/kultur-og-underholdning/1.7321778
Закон Деметры
Метод М объекта О может обращаться:
  •   К самому объекту О
  •   К параметрам метода М
  •   К любому объекту, созданному методом М
  •   К методам и свойствам объекта О
  •   К глобальным переменным
Закон Деметры
Можно:

name = this.Name();
code = this.Phone.CountryCode; // Простой агрегат


Нельзя:

return geo.Countries.Finder.DataLayer.LoadCountry( id );
Закон Деметры –
метрика, а не методология
Паттерны
проектирования*


* Шаблоны проектирования
От архитектуры к архитектуре




                                                            +3
Christopher Alexander   Ward Cunningham   Kent Beck   Erich Gamma
Singleton

                             Singleton
                   +Instance: Singleton
                   +SomeOperation()
                   +AnotherOperation()




Singleton.Instance.SomeOperation();
Лишняя связность
           Client
                                   OtherClient




             Subsystem



                                  Class2
  Class1



                         Class3




  Class4
                    Class5
ç
         Client
                                 OtherClient




           Facade
           Subsystem



                                Class2
Class1



                       Class3




Class4
                  Class5
Adapter
                              <<interface>>
  DrawingEditor                  IShape
                      +BoundingBox(): Rect
                      +CreateManipulator(): IManipulator                TextView

                                                                   +GetExtent()

                                                                -text
                    Line                      TextShape

             +BoundingBox()              +BoundingBox()
             +CreateManipulator()        +CreateManipulator()




public Rect BoundingBox() {
       return text.GetExtent();
}
Abstract Factory
                             Client




WidgetFactory                    Window        Scrollbar

+CreateWindow()
+CreateScrollbar()


            GnomeWidgetFactory        GnomeWindow     GnomeScrollbar

            +CreateWindow()
            +CreateScrollbar()

             KdeWidgetFactory         KdeWindow            KdeScrollbar

            +CreateWindow()
            +CreateScrollbar()
Command

Application    Menu             MenuItem
                           *




                           <<interface>>
Document                    ICommand
                           +Execute()




              CutCommand       CopyCommand   PasteCommand

              +Execute()   +Execute()        +Execute()
Observer
                Subject                        <<interface>>
                                  +observers    IObserver
          +Attach(o: IObserver)          *
          +Detach(o: IObserver)                +Update()
          +Notify()



           ConcreteSubject                   ConcreteObserver




public void Notify() {
       foreach( var o in observers)
             o.Update();
}
Каталоги паттернов
• «Design patterns. Elements of Reusable
  Object-Oriented Software»
• Portland Pattern Repository (c2.com/ppr/)
• PatternShare (www.patternshare.org)
• etc.
DDD
    Domain Driven Design*


* Проблемно-ориентированное проектирование
Проблемная область
В каждом маленьком ребенке        Каждый новенький ребенок
И мальчишке, и девчонке           Вылезает из пеленок
Есть по двести грамм взрывчатки   И теряется повсюду
Или даже полкило!                 И находится везде!
Должен он бежать и прыгать        Он всегда куда-то мчится
Все хватать, ногами дрыгать,      Он ужасно огорчится,
А иначе он взорвется,             Если что-нибудь на свете
Трах-бабах – и нет его!           Вдруг случится без него!
Domain model
<<enumeration>>                            Ребенок
 ПолЧеловека                                                         +Ноги           Нога
+Мужчина                          +Пол: ПолЧеловека                   0..2   +Дрыгать()
+Женщина
                                                           0..1

                                                          +Ребенок
                                                                             +Одежда    0..*

                                         МаленькийРебенок                                      Одежда
 Предмет
               *                  +КоличествоВзрывчатки: float                         +ИзвлечьРебенка(сам: bool)
              -Предметы           +СтепеньОгорчения: int
                                  +ДелайЧтоДолжен()
                  0..*
                                  -Бежать()
                  -Схваченное
                                                                                                        Пеленки
                                  -Прыгать()
                                  -Хватать(предмет: Предмет)
                                  -ДрыгатьНогами()
  Место           +ГдеПотерялся
                                  -Взорваться()
              +ГдеНашелся         +СнятьОдежду()
                                                                        *
                                  +Потеряться(где: Место)               +Участники                        Событие
              +Цель
                                  +Найтись(где: Место)
                                                                                -ПоследнееПроверенное
                                  +Мчаться(куда: Место)
                                  +ПроверитьСобытия()                                                       * +События
                                  -Огорчиться(степень: int)
                                                                                                           1   +Свет

                                                                             +Свет                Свет
Процесс проектирования
Процесс проектирования
1.   Немного подумать над архитектурой
2.   Решать задачу
3.   Анализировать архитектуру
4.   Рефакторинг
5.   goto 2

                                Тесты!
Опыт решает
Ниф-Ниф – junior developer




                             © Walt Disney
Нф-Нф…




           © Walt Disney
Наф-Наф – senior




                   © Walt Disney
Спасибо за внимание


   Андрей Майоров
       BYTE-force
  xor@byte-force.com
   twitter.com/xorets

More Related Content

Проектирование архитектуры приложений