Дизайн ООПправила хорошего тона. SOLID.                                Щербинин Александр                                u...
Объектно ориентированное проектирование    •   проектирование - суть программирования    •   ваш код - проектная документа...
Ароматы дизайнаили как распознать загнивающий код
Ароматы дизайна
Ароматы дизайна•   непрозрачность
Ароматы дизайна•   непрозрачность    -   сложность для понимания, запутанность
Ароматы дизайна•   непрозрачность    -   сложность для понимания, запутанность•   жесткость
Ароматы дизайна•   непрозрачность    -   сложность для понимания, запутанность•   жесткость    -   сложность внесения изме...
Ароматы дизайна•   непрозрачность    -   сложность для понимания, запутанность•   жесткость    -   сложность внесения изме...
Ароматы дизайна•   непрозрачность    -   сложность для понимания, запутанность•   жесткость    -   сложность внесения изме...
Ароматы дизайна•   непрозрачность    -   сложность для понимания, запутанность•   жесткость    -   сложность внесения изме...
Ароматы дизайна
Ароматы дизайна•   неподвижность
Ароматы дизайна•   неподвижность    -   сложно выделить части дизайна в отдельные        компоненты
Ароматы дизайна•   неподвижность    -   сложно выделить части дизайна в отдельные        компоненты•   вязкость
Ароматы дизайна•   неподвижность    -   сложно выделить части дизайна в отдельные        компоненты•   вязкость    -   сло...
Ароматы дизайна•   неподвижность    -   сложно выделить части дизайна в отдельные        компоненты•   вязкость    -   сло...
Ароматы дизайна
Ароматы дизайна•   ненужная сложность
Ароматы дизайна•   ненужная сложность    -   наблюдается overhead, наличие множества        неиспользуемых элементов
Ароматы дизайна•   ненужная сложность    -   наблюдается overhead, наличие множества        неиспользуемых элементов    - ...
Ароматы дизайна•   ненужная сложность    -   наблюдается overhead, наличие множества        неиспользуемых элементов    - ...
Ароматы дизайна•   ненужная сложность    -   наблюдается overhead, наличие множества        неиспользуемых элементов    - ...
SOLID
SOLID•   Single responsibility principle•   Open/closed principle•   Liskov substitution principle•   Interface segregatio...
Single responsibility principle      Принцип единственной обязанности
SRPПринцип единственной обязанности
SRP      Принцип единственной обязанности•   у класса должна быть только одна причина для    изменения
SRP      Принцип единственной обязанности•   у класса должна быть только одна причина для    изменения•   то есть у класса...
SRP      Принцип единственной обязанности•   у класса должна быть только одна причина для    изменения•   то есть у класса...
SRP       Принцип единственной обязанностиclass Modem  def dial(number)  end                    1-я обязанность  def hangu...
SRP               Принцип единственной обязанностиmodule ConnectionInterface  def dial(number)  end  def hangup           ...
SRP        Принцип единственной обязанности                 class Modem                   def dial(number)                ...
SRP  Принцип единственной обязанностиclass Basket  def calculate      бизнес-логика  end  def store  end              логи...
SRPПринцип единственной обязанности
SRP      Принцип единственной обязанности•   не совмещайте бизнес-логику с логикой    приложения
SRP      Принцип единственной обязанности•   не совмещайте бизнес-логику с логикой    приложения•   если вам очень-очень н...
Open/closed principle   Принцип открытости/закрытости
OCPПринцип открытости/закрытости
OCP        Принцип открытости/закрытости•   программные сущности должны быть открыты для    расширения, но закрыты для мод...
OCP        Принцип открытости/закрытости•   программные сущности должны быть открыты для    расширения, но закрыты для мод...
OCP        Принцип открытости/закрытости•   программные сущности должны быть открыты для    расширения, но закрыты для мод...
OCP       Принцип открытости/закрытостиЗадача: необходимо рисовать геометрические фигуры(круги и квадраты) в графическом и...
OCP            Принцип открытости/закрытости             wrong       (высокая жесткость)Circle = Struct.new(:radius, :cent...
OCP            Принцип открытости/закрытости             wrong                                    better       (высокая же...
OCPПринцип открытости/закрытости
OCP        Принцип открытости/закрытости•   не существует моделей, универсальных во всех    контекстах
OCP        Принцип открытости/закрытости•   не существует моделей, универсальных во всех    контекстах•   защищайся только...
OCP        Принцип открытости/закрытости•   не существует моделей, универсальных во всех    контекстах•   защищайся только...
OCP        Принцип открытости/закрытости•   не существует моделей, универсальных во всех    контекстах•   защищайся только...
OCP        Принцип открытости/закрытости•   не существует моделей, универсальных во всех    контекстах•   защищайся только...
Liskov substitution principle       Принцип подстановки Лисков
LSPПринцип подстановки Лисков
LSP          Принцип подстановки Лисков•   должна быть возможность вместо базового типа    подставить любой его подтип
LSP          Принцип подстановки Лисков•   должна быть возможность вместо базового типа    подставить любой его подтип•   ...
LSP          Принцип подстановки Лисков•   должна быть возможность вместо базового типа    подставить любой его подтип•   ...
LSPПринцип подстановки Лисков
LSP             Принцип подстановки Лисковclass Rectangle  def width    return @width  end  def height    return @height  ...
LSP             Принцип подстановки Лисковclass Rectangle                 class Square < Rectangle  def width             ...
LSP             Принцип подстановки Лисковclass Rectangle                 class Square < Rectangle  def width             ...
LSP             Принцип подстановки Лисковclass Rectangle                                          class Square < Rectangl...
LSPПринцип подстановки Лисков
LSP          Принцип подстановки Лисков•   проектирование по контракту (пред- и пост- условия)
LSP          Принцип подстановки Лисков•   проектирование по контракту (пред- и пост- условия)•   производный класс не дол...
LSP          Принцип подстановки Лисков•   проектирование по контракту (пред- и пост- условия)•   производный класс не дол...
Interface segregation principle       Принцип разделения интерфейсов
ISPПринцип разделения интерфейсов
ISP       Принцип разделения интерфейсов•   клиент не должен вынужденно зависеть от элементов    интерфейса, которые он не...
ISP       Принцип разделения интерфейсов•   клиент не должен вынужденно зависеть от элементов    интерфейса, которые он не...
ISP       Принцип разделения интерфейсов•   клиент не должен вынужденно зависеть от элементов    интерфейса, которые он не...
ISP                       Принцип разделения интерфейсовclass ServiceClient  def send_data; end  def flush; endendclass Ht...
ISP                       Принцип разделения интерфейсовclass ServiceClient                                 class ServiceC...
ISP          Принцип разделения интерфейсовКак разделять?
ISP          Принцип разделения интерфейсовКак разделять?   •   делегация
ISP          Принцип разделения интерфейсовКак разделять?   •   делегация   •   множественное наследование
Dependency-inversion principle        Принцип инверсии зависимости
DIPПринцип инверсии зависимости
DIP         Принцип инверсии зависимости•   модули верхнего уровня не должны зависеть от    модулей нижнего уровня. И те и...
DIP         Принцип инверсии зависимости•   модули верхнего уровня не должны зависеть от    модулей нижнего уровня. И те и...
DIP         Принцип инверсии зависимости•   модули верхнего уровня не должны зависеть от    модулей нижнего уровня. И те и...
DIP                         Принцип инверсии зависимости      доclass Program  def self.run    reporter = Reporter.new    ...
DIP                         Принцип инверсии зависимости      до                                           class Programcl...
DIP                         Принцип инверсии зависимости      до                                                 после    ...
DIP     Принцип инверсии зависимостидо
DIP     Принцип инверсии зависимостидо                       после
Советую прочитать
Советую прочитать•   GRASP - General Responsibility Assignment Software    Patterns
Советую прочитать•   GRASP - General Responsibility Assignment Software    Patterns•   Принципы, паттерны, и методики гибк...
Советую прочитать•   GRASP - General Responsibility Assignment Software    Patterns•   Принципы, паттерны, и методики гибк...
Советую прочитать•   GRASP - General Responsibility Assignment Software    Patterns•   Принципы, паттерны, и методики гибк...
Советую прочитать•   GRASP - General Responsibility Assignment Software    Patterns•   Принципы, паттерны, и методики гибк...
That’s allВопросы?              Щербинин Александр              undev.ru                twitter.com/realmyst              ...
Upcoming SlideShare
Loading in...5
×

Объектно ориентированный дизайн

800

Published on

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
800
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
22
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Объектно ориентированный дизайн

    1. 1. Дизайн ООПправила хорошего тона. SOLID. Щербинин Александр undev.ru
    2. 2. Объектно ориентированное проектирование • проектирование - суть программирования • ваш код - проектная документация продукта • задача проектирования - управление сложностью проекта
    3. 3. Ароматы дизайнаили как распознать загнивающий код
    4. 4. Ароматы дизайна
    5. 5. Ароматы дизайна• непрозрачность
    6. 6. Ароматы дизайна• непрозрачность - сложность для понимания, запутанность
    7. 7. Ароматы дизайна• непрозрачность - сложность для понимания, запутанность• жесткость
    8. 8. Ароматы дизайна• непрозрачность - сложность для понимания, запутанность• жесткость - сложность внесения изменений
    9. 9. Ароматы дизайна• непрозрачность - сложность для понимания, запутанность• жесткость - сложность внесения изменений - простое изменение вызывает каскад зависимых правок
    10. 10. Ароматы дизайна• непрозрачность - сложность для понимания, запутанность• жесткость - сложность внесения изменений - простое изменение вызывает каскад зависимых правок• хрупкость
    11. 11. Ароматы дизайна• непрозрачность - сложность для понимания, запутанность• жесткость - сложность внесения изменений - простое изменение вызывает каскад зависимых правок• хрупкость - исправление одной проблемы влечет появление множества новых
    12. 12. Ароматы дизайна
    13. 13. Ароматы дизайна• неподвижность
    14. 14. Ароматы дизайна• неподвижность - сложно выделить части дизайна в отдельные компоненты
    15. 15. Ароматы дизайна• неподвижность - сложно выделить части дизайна в отдельные компоненты• вязкость
    16. 16. Ароматы дизайна• неподвижность - сложно выделить части дизайна в отдельные компоненты• вязкость - сложно сохранить дизайн при изменении
    17. 17. Ароматы дизайна• неподвижность - сложно выделить части дизайна в отдельные компоненты• вязкость - сложно сохранить дизайн при изменении - решить задачу правильно сложнее, чем сделать “хак”
    18. 18. Ароматы дизайна
    19. 19. Ароматы дизайна• ненужная сложность
    20. 20. Ароматы дизайна• ненужная сложность - наблюдается overhead, наличие множества неиспользуемых элементов
    21. 21. Ароматы дизайна• ненужная сложность - наблюдается overhead, наличие множества неиспользуемых элементов - возникает, когда разработчик пытается предугадать последующие изменения
    22. 22. Ароматы дизайна• ненужная сложность - наблюдается overhead, наличие множества неиспользуемых элементов - возникает, когда разработчик пытается предугадать последующие изменения• ненужные повторения
    23. 23. Ароматы дизайна• ненужная сложность - наблюдается overhead, наличие множества неиспользуемых элементов - возникает, когда разработчик пытается предугадать последующие изменения• ненужные повторения - один и тот же код с минимальными изменениями копируется снова и снова
    24. 24. SOLID
    25. 25. SOLID• Single responsibility principle• Open/closed principle• Liskov substitution principle• Interface segregation principle• Dependency inversion principle
    26. 26. Single responsibility principle Принцип единственной обязанности
    27. 27. SRPПринцип единственной обязанности
    28. 28. SRP Принцип единственной обязанности• у класса должна быть только одна причина для изменения
    29. 29. SRP Принцип единственной обязанности• у класса должна быть только одна причина для изменения• то есть у класса должна быть только одна обязанность
    30. 30. SRP Принцип единственной обязанности• у класса должна быть только одна причина для изменения• то есть у класса должна быть только одна обязанность• сильное сцепление (high cohesion, см. GRASP)
    31. 31. SRP Принцип единственной обязанностиclass Modem  def dial(number)  end 1-я обязанность  def hangup управление соединением  end  def send(char)  end 2-я обязанность  def recv передача данных  endend
    32. 32. SRP Принцип единственной обязанностиmodule ConnectionInterface  def dial(number)  end  def hangup class Modem  end   include ConnectionInterfaceend   include DataChannelInterface endmodule DataChannelInterface  def send(char)  end  def recv  endend
    33. 33. SRP Принцип единственной обязанности class Modem   def dial(number)   end 1-я обязанность управление соединением   def hangup   end   def send(char)   end 2-я обязанность передача данных   def recv   end endЕсли необходимо изменить только процесс соединения - то дизайн становится жестким, и нужно разделять обязанностиЕсли изменяется одновременно и процесс соединения, и процессотправки - то разделение повлечет за собой излишнюю сложность
    34. 34. SRP Принцип единственной обязанностиclass Basket  def calculate бизнес-логика  end  def store  end логика приложенияend
    35. 35. SRPПринцип единственной обязанности
    36. 36. SRP Принцип единственной обязанности• не совмещайте бизнес-логику с логикой приложения
    37. 37. SRP Принцип единственной обязанности• не совмещайте бизнес-логику с логикой приложения• если вам очень-очень нужно совместить обязанности - не создавайте зависимостей
    38. 38. Open/closed principle Принцип открытости/закрытости
    39. 39. OCPПринцип открытости/закрытости
    40. 40. OCP Принцип открытости/закрытости• программные сущности должны быть открыты для расширения, но закрыты для модификации
    41. 41. OCP Принцип открытости/закрытости• программные сущности должны быть открыты для расширения, но закрыты для модификации• открыты для расширения - мы можем изменить состав модуля, добавив новое поведение
    42. 42. OCP Принцип открытости/закрытости• программные сущности должны быть открыты для расширения, но закрыты для модификации• открыты для расширения - мы можем изменить состав модуля, добавив новое поведение• закрыты для модификации - расширение модуля не связано с изменением его исходного кода (уменьшаем жесткость)
    43. 43. OCP Принцип открытости/закрытостиЗадача: необходимо рисовать геометрические фигуры(круги и квадраты) в графическом интерфейсе.
    44. 44. OCP Принцип открытости/закрытости wrong (высокая жесткость)Circle = Struct.new(:radius, :center)# рисуем кругdef draw_circle  #endSquare = Struct.new(:side, :top_left)# рисуем квадратdef draw_square  #end# рисуем список фигурdef draw_all_shapes(shapes)  shapes.each do |shape|    case shape.class      when Circle; draw_circle(shape)      when Square; draw_square(shape)    end  endend
    45. 45. OCP Принцип открытости/закрытости wrong better (высокая жесткость)Circle = Struct.new(:radius, :center) class Shape   def draw# рисуем круг     # interfacedef draw_circle   end  # endend class Circle < ShapeSquare = Struct.new(:side, :top_left)   def draw     # implement# рисуем квадрат   enddef draw_square end  #end class Square < Shape   def draw# рисуем список фигур     # implementdef draw_all_shapes(shapes)   end  shapes.each do |shape| end    case shape.class      when Circle; draw_circle(shape) def draw_all_shapes(shapes)      when Square; draw_square(shape)   shapes.each do |shape|    end     shape.draw  end   endend end
    46. 46. OCPПринцип открытости/закрытости
    47. 47. OCP Принцип открытости/закрытости• не существует моделей, универсальных во всех контекстах
    48. 48. OCP Принцип открытости/закрытости• не существует моделей, универсальных во всех контекстах• защищайся только от наиболее вероятных изменений
    49. 49. OCP Принцип открытости/закрытости• не существует моделей, универсальных во всех контекстах• защищайся только от наиболее вероятных изменений• не беги вперед и не перегружай код абстракциями (помни про ненужную сложность)
    50. 50. OCP Принцип открытости/закрытости• не существует моделей, универсальных во всех контекстах• защищайся только от наиболее вероятных изменений• не беги вперед и не перегружай код абстракциями (помни про ненужную сложность)• “Обманул меня раз - позор тебе. Обманул два - позор мне”
    51. 51. OCP Принцип открытости/закрытости• не существует моделей, универсальных во всех контекстах• защищайся только от наиболее вероятных изменений• не беги вперед и не перегружай код абстракциями (помни про ненужную сложность)• “Обманул меня раз - позор тебе. Обманул два - позор мне”• отказ от абстракции так же важен, как и ее ввод
    52. 52. Liskov substitution principle Принцип подстановки Лисков
    53. 53. LSPПринцип подстановки Лисков
    54. 54. LSP Принцип подстановки Лисков• должна быть возможность вместо базового типа подставить любой его подтип
    55. 55. LSP Принцип подстановки Лисков• должна быть возможность вместо базового типа подставить любой его подтип• поведение наследуемых классов не должно противоречить поведению, заданному базовым классом
    56. 56. LSP Принцип подстановки Лисков• должна быть возможность вместо базового типа подставить любой его подтип• поведение наследуемых классов не должно противоречить поведению, заданному базовым классом• LSP - важнейший критерий оценки качества при построении иерархий наследования
    57. 57. LSPПринцип подстановки Лисков
    58. 58. LSP Принцип подстановки Лисковclass Rectangle  def width    return @width  end  def height    return @height  end  def width=(number)    @width = number  end  def height=(number)    @height = number  endend
    59. 59. LSP Принцип подстановки Лисковclass Rectangle class Square < Rectangle  def width   def width=(number)    return @width     @width = number  end     @height = number   end  def height    return @height   def height=(number)  end     @width = number     @height = number   end  def width=(number) end    @width = number  end  def height=(number)    @height = number  endend
    60. 60. LSP Принцип подстановки Лисковclass Rectangle class Square < Rectangle  def width   def width=(number)    return @width     @width = number  end     @height = number   end  def height    return @height   def height=(number)  end     @width = number     @height = number   end  def width=(number) end    @width = number  end  def height=(number)    @height = number  end def foo(rectangle)end   rectangle.width = 5   rectangle.height = 7 end
    61. 61. LSP Принцип подстановки Лисковclass Rectangle class Square < Rectangle  def width   def width=(number)    return @width     @width = number  end     @height = number   end  def height    return @height   def height=(number)  end     @width = number     @height = number  # assert((width == number) && (height = old.height))   end  def width=(number) end    @width = number  end  def height=(number)    @height = number  end def foo(rectangle)end   rectangle.width = 5   rectangle.height = 7 end
    62. 62. LSPПринцип подстановки Лисков
    63. 63. LSP Принцип подстановки Лисков• проектирование по контракту (пред- и пост- условия)
    64. 64. LSP Принцип подстановки Лисков• проектирование по контракту (пред- и пост- условия)• производный класс не должен исключать функциональность базового класса
    65. 65. LSP Принцип подстановки Лисков• проектирование по контракту (пред- и пост- условия)• производный класс не должен исключать функциональность базового класса• если классы имеют некоторую общую обязанность - возможно имеет смысл провести факторизацию
    66. 66. Interface segregation principle Принцип разделения интерфейсов
    67. 67. ISPПринцип разделения интерфейсов
    68. 68. ISP Принцип разделения интерфейсов• клиент не должен вынужденно зависеть от элементов интерфейса, которые он не использует
    69. 69. ISP Принцип разделения интерфейсов• клиент не должен вынужденно зависеть от элементов интерфейса, которые он не использует• “жирные” интерфейсы - плохо
    70. 70. ISP Принцип разделения интерфейсов• клиент не должен вынужденно зависеть от элементов интерфейса, которые он не использует• “жирные” интерфейсы - плохо• интерфейс считается “жирным”, когда между его методами слабая сцепленность (см. GRASP)
    71. 71. ISP Принцип разделения интерфейсовclass ServiceClient  def send_data; end  def flush; endendclass HttpServiceClient < ServiceClient  def send_data    # implement  end  def flush    # пустой метод, остаток от интерфейса  endendclass BufferingHttpServiceClient < ServiceClient  def send_data    # another implement  end  def flush    # implement  endend
    72. 72. ISP Принцип разделения интерфейсовclass ServiceClient class ServiceClient  def send_data; end   def send_data; end  def flush; end endend class BufferingServiceClient < ServiceClientclass HttpServiceClient < ServiceClient   def flush; end  def send_data end    # implement  end class HttpServiceClient < ServiceClient  def flush   def send_data    # пустой метод, остаток от интерфейса     # implement  end   endend endclass BufferingHttpServiceClient < ServiceClient class BufferingHttpServiceClient < BufferingServiceClient  def send_data   def send_data    # another implement     # another implement  end   end  def flush   def flush    # implement     # implement  end   endend end
    73. 73. ISP Принцип разделения интерфейсовКак разделять?
    74. 74. ISP Принцип разделения интерфейсовКак разделять? • делегация
    75. 75. ISP Принцип разделения интерфейсовКак разделять? • делегация • множественное наследование
    76. 76. Dependency-inversion principle Принцип инверсии зависимости
    77. 77. DIPПринцип инверсии зависимости
    78. 78. DIP Принцип инверсии зависимости• модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те и другие должны зависеть от абстракций
    79. 79. DIP Принцип инверсии зависимости• модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те и другие должны зависеть от абстракций• абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций
    80. 80. DIP Принцип инверсии зависимости• модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те и другие должны зависеть от абстракций• абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций• если коротко: зависеть надо от абстракций
    81. 81. DIP Принцип инверсии зависимости доclass Program  def self.run    reporter = Reporter.new    reporter.send_reports()  endendclass Reporter  def initialize    @builder = ReportBuilder.new    @sender = EmailReportSender.new  end  def send_reports    reports = @builder.create_reports()    reports.each do |report|      @sender.send(report)    end  endendProgram.run
    82. 82. DIP Принцип инверсии зависимости до class Programclass Program   def self.run  def self.run # builder, sender - реализации соответствующих интерфейсов    reporter = Reporter.new     builder = ReportBuilder.new    reporter.send_reports()     sender = EmailReportSender.new  end     reporter = Reporter.new(builder, sender)end     reporter.send_reports()   endclass Reporter end  def initialize    @builder = ReportBuilder.new class Reporter    @sender = EmailReportSender.new   def initialize(builder, sender)  end     @builder = builder     @sender = sender  def send_reports   end    reports = @builder.create_reports()    reports.each do |report|   def send_reports      @sender.send(report)     reports = @builder.create_reports()    end     reports.each do |report|  end       @sender.send(report)end     end   endProgram.run end Program.run
    83. 83. DIP Принцип инверсии зависимости до после class Programclass Program   def self.run  def self.run # builder, sender - реализации соответствующих интерфейсов    reporter = Reporter.new     builder = ReportBuilder.new    reporter.send_reports()     sender = EmailReportSender.new  end     reporter = Reporter.new(builder, sender)end     reporter.send_reports()   endclass Reporter end  def initialize    @builder = ReportBuilder.new class Reporter    @sender = EmailReportSender.new   def initialize(builder, sender)  end     @builder = builder     @sender = sender  def send_reports   end    reports = @builder.create_reports()    reports.each do |report|   def send_reports      @sender.send(report)     reports = @builder.create_reports()    end     reports.each do |report|  end       @sender.send(report)end     end   endProgram.run end Program.run
    84. 84. DIP Принцип инверсии зависимостидо
    85. 85. DIP Принцип инверсии зависимостидо после
    86. 86. Советую прочитать
    87. 87. Советую прочитать• GRASP - General Responsibility Assignment Software Patterns
    88. 88. Советую прочитать• GRASP - General Responsibility Assignment Software Patterns• Принципы, паттерны, и методики гибкой разработки на языке C#. // Р. С. Мартин, М. Мартин.
    89. 89. Советую прочитать• GRASP - General Responsibility Assignment Software Patterns• Принципы, паттерны, и методики гибкой разработки на языке C#. // Р. С. Мартин, М. Мартин.• Шаблоны корпоративных приложений. // М. Фаулер
    90. 90. Советую прочитать• GRASP - General Responsibility Assignment Software Patterns• Принципы, паттерны, и методики гибкой разработки на языке C#. // Р. С. Мартин, М. Мартин.• Шаблоны корпоративных приложений. // М. Фаулер• Предметно-ориентированное проектирование (DDD). Структуризация сложных систем. // Э. Эванс
    91. 91. Советую прочитать• GRASP - General Responsibility Assignment Software Patterns• Принципы, паттерны, и методики гибкой разработки на языке C#. // Р. С. Мартин, М. Мартин.• Шаблоны корпоративных приложений. // М. Фаулер• Предметно-ориентированное проектирование (DDD). Структуризация сложных систем. // Э. Эванс• Паттерны проектирования. // GoF
    92. 92. That’s allВопросы? Щербинин Александр undev.ru twitter.com/realmyst github.com/realmyst
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×