Tdd + Ddd + Mvp + Go F + Po Eaa = Love

2,659 views

Published on

http://agiledays.ru

Published in: Business, Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,659
On SlideShare
0
From Embeds
0
Number of Embeds
1,218
Actions
Shares
0
Downloads
55
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • Call to action:Применение использованных нами практик позволит вам успешно завершить проектТехническая основа agile на платформе MS
  • ОценкиMS подтверждают
  • ПрименяемeXtreme Programming (XP)ScrumKanban
  • Нужно объяснить, почему мы компетентны говорить на заявленную тему. Блин, этот слайд нужно переделать совсем.
  • Спросить у Дарлин разрешения на фотографию
  • Перевести
  • ООПМоделирование реального мираГруппы взаимосвязанных объектов -> паттерны
  • ООПМоделирование реального мираГруппы взаимосвязанных объектов -> паттерны
  • Нужно объяснить, почему мы компетентны говорить на заявленную тему. Блин, этот слайд нужно переделать совсем.
  • Tdd + Ddd + Mvp + Go F + Po Eaa = Love

    1. 1. DDD + TDD + MVP + GoF + PoEAA= Love!<br />Евгений Сорокин<br />Антон Бевзюк<br />9декабря 2009<br />
    2. 2. Содержание<br />Intro<br />DDD<br />MVP/MVVM<br />TDD<br />DSL<br />GoF/PoEAA<br />…<br />Profit!<br />
    3. 3. Intro<br />
    4. 4. Кто мы такие?<br />Программируем<br />Руководимразработкой<br />Обучаемстудентовсотрудников<br />
    5. 5. Портфолио отдела<br />Бизнес-приложения<br />7 лет в Agile<br />20 человек<br />.NET<br />SAP<br />Business Intelligence<br />
    6. 6. Самый большой agile-проект<br />32 проекта<br />140 000 строк кода<br />5000+ юнит тестов<br />
    7. 7. DDDDomain-Driven Design<br />
    8. 8. Почему DDD<br />Сложный бизнес процесс<br />
    9. 9. DDD<br />Общий язык<br />Выделенный домен<br />
    10. 10. Стандартный DDD<br />
    11. 11. Зависит от технологии<br />Не зависит от технологии<br />
    12. 12. Дизайн<br />Клиент<br />Сервер<br />UI<br />WebService<br />Application<br />Presentation<br />Application<br />Domain<br />Infrastructure<br />Infrastructure<br />DB<br />
    13. 13. Что дает DDD<br />«Чистый» домен<br />Инкапсуляция доменной логики<br />И еще кое-что...<br />
    14. 14.
    15. 15. MVP /MVVMModel-View-Presenter / Model-View-ViewModel<br />
    16. 16. Тестирование GUI<br />GUI есть везде<br />Важная часть приложения<br />
    17. 17. Методы тестирования GUI<br />Ручное<br />Автоматическое <br />LoadRunner<br />TestComplete<br />Юнит-тестирование<br />
    18. 18. Passive View<br />View<br />Presenter<br />Model<br />
    19. 19. Пример<br />
    20. 20. IManagerView<br />public interface IManagerView {<br /> List&lt;Manager&gt; Managers { set; }<br /> Manager SelectedManager { get; set; }<br /> List&lt;Employee&gt; Employees { set; }<br /> Notification Add { set; }<br /> Notification Edit { set; }<br /> Notification Delete { set; }<br /> Notification Save { set; }<br />}<br />
    21. 21. ManagerPresenterTests<br />[TestMethod]<br />public void CanAddEmployee() {<br />var view = new ManagerViewFake();<br />var presenter = new ManagerPresenter(view);<br />var manager = Persist.Manager();<br />view.SelectedManager = manager;<br />view.Add();<br />Assert.AreEqual(1, view.Employees.Count);<br />}<br />
    22. 22. ManagerPresenter<br />private void IManagerView view;<br />…<br />public void OnAdd() {<br />SelectedManager.Employees.Add(new Employee());<br /> Rebind();<br />}<br />…<br />private void Rebind() {<br />view.Managers = Managers;<br />view.SelectedManager = SelectedManager;<br />view.Employees = SelectedManager.Employees;<br />}<br />
    23. 23. ManagerView<br />public class ManagerView : IManagerView {<br /> public List&lt;Employee&gt; Employees {<br /> set {<br />employeesListView.DataSource = value;<br /> }<br /> }<br /> …<br /> public Notification Add { get; set; }<br /> …<br /> private void addButton_click(…) {<br /> Add();<br /> }<br />}<br />
    24. 24. Model-View-ViewModel<br />Binding<br />View<br />ViewModel<br />Model<br />
    25. 25. ManagerViewModelTests<br />[TestMethod]<br />public void AddEmployee() {<br />varviewModel = new ManagerViewModel();<br />var manager = Create.Manager();<br />viewModel.Managers = new [] {manager};<br />viewModel.SelectedManager = manager;<br />viewModel.Add();<br />Assert.AreEqual(1, viewModel.Employees.Count);<br />}<br />
    26. 26. ManagerViewModel<br />public class ManagerViewModel {<br /> List&lt;Manager&gt; Managers { get; private set; }<br /> Manager SelectedManager { get; set; }<br /> List&lt;Employee&gt; Employees { <br /> get { return SeelctedManager.Employees; } <br /> }<br />…<br /> Notification Add { get; private set; }<br />…<br /> private void OnAdd() {<br />SelectedManager.Employees.Add(new Employee());<br /> }<br />}<br />
    27. 27. ManagerView<br />
    28. 28. Что дает MVP/MVVM<br />Тестирование Presentation<br />
    29. 29. TDDTest-Driven Development<br />
    30. 30. Мифы о TDD<br /><ul><li>Юнит тесты == TDD
    31. 31. TDD == объем работы * 2
    32. 32. TDD == 100% тестовое покрытие
    33. 33. TDD == серебряная пуля</li></li></ul><li>RED/GREEN/REFACTOR<br />Подумай.<br />Напиши тест<br />Начало<br />Скомпилируй<br />Рефакторинг<br />Запусти все тесты <br />и убедись, <br />что они прошли<br />Исправь <br />ошибки<br />5 мин<br />Запусти все тесты <br />и убедись, <br />что они упали<br />Напиши код<br />
    34. 34. Тестируем все<br />Код<br />Конфигурацию<br />Хранимые процедуры<br />GUI binding<br />
    35. 35. Тестируем код<br />[TestMethod]<br />public void CanConvertMoney() {<br />var service = new ExchangeRatesServiceFake()<br /> .UsdCosts(1, &quot;USD&quot;)<br /> .UsdCosts(29M, &quot;RUR&quot;);<br />var money = new Money(5, &quot;RUR&quot;);<br />Assert.AreEqual(<br /> new Money(5/29M, &quot;USD&quot;), <br />money.Convert(&quot;USD&quot;, service));<br />}<br />
    36. 36. Тестируем конфигурацию<br />
    37. 37. Тестируем конфигурацию<br />[TestMethod]<br />public void CorrectConnectionString() {<br />vardataContext = new DataContext();<br />StringAssert.Contains(<br />“Correct connection string”, dataContext.Connection.ConnectionString, “Please change connection string in DataContext to ConnectionString.&quot;);<br />}<br />
    38. 38. Тестируем хранимые процедуры<br />[TestMethod]<br />public void GetYearSales() {<br />DataContextUtils.Insert(new order {<br />order_date = &quot;2009-01-01&quot;,<br />order_items = {<br /> new order_item {amount = 5, price = 10.00M},<br /> new order_item {amount = 2, price = 20.00M},<br /> });<br />var sales = DataContext.pr_get_year_sales(2009).Single();<br />Assert.AreEqual(7, sales.total_amount);<br />Assert.AreEqual(5*10M + 2*20M, sales.total_sum);<br />}<br />
    39. 39. Тестируем GUI binding<br />
    40. 40. Тестируем GUI binding<br />public void EmployeeViewBindingsAreOk() {<br />var expected = new[] {<br /> new BindingData(&quot;managers&quot;, &quot;DataMember&quot;, &quot;Managers&quot;, typeof (EmployeeViewModel)),<br /> new BindingData(“managers&quot;, &quot;SelectedItem&quot;, &quot;SelectedManager&quot;, typeof (EmployeeViewModel)),<br /> new BindingData(&quot;employees&quot;, &quot;DataMember&quot;, &quot;Employees&quot;, typeof (EmployeeViewModel)),<br /> new BindingData(&quot;add&quot;, &quot;Action&quot;, &quot;CreateEmployee&quot;, typeof (EmployeeViewModel)),<br /> new BindingData(&quot;edit&quot;, &quot;Action&quot;, &quot;EditEmployee&quot;, typeof (EmployeeViewModel)),<br /> new BindingData(&quot;delete&quot;, &quot;Action&quot;, &quot;DeleteEmployee&quot;, typeof (EmployeeViewModel)),<br /> new BindingData(&quot;save&quot;, &quot;Action&quot;, &quot;Save&quot;, typeof (EmployeeViewModel)),<br /> };<br />var view = new EmployeeView();<br />BindingAssert.Matches(expected, view);<br />}<br />
    41. 41. Имена тестов<br />[TestClass]<br />EmployeePresenterTests {<br /> [TestMethod]CanSelectEmployee(){…}<br />[TestMethod]ItWorksTest(){…}<br />}<br />
    42. 42. Имена тестов<br />[TestClass]<br />WhenAddEmployee {<br /> [TestMethod]AddedEmployeeSelectedByDefault(){…}<br />}<br />
    43. 43. Что дает TDD<br />Простота<br />Гибкость<br />Поддерживаемость<br />Тестируемость<br />5000+ тестов за 1 минуту<br />
    44. 44. DSLDomain Specific Language<br />
    45. 45. DSL<br />new DateTime(2009, 11, 12)<br />12.11.of2009();<br />public static DateTime of2009(this double ddMM) {<br />var day = (int) Math.Round(ddMM, 0);<br />var month = (int) Math.Round(ddMM*100, 0) - day * 100;<br /> return new DateTime(2009, month, day);<br />}<br />
    46. 46. DSL<br />var month = new CalendarMonth(2009, 10);<br />var month = Oct.of2009();<br />internal static class Oct {<br /> public static CalendarMonth of2009 {<br /> get { <br /> return new CalendarMonth(2009, 10); <br /> }<br /> }<br />}<br />
    47. 47. DSL<br />var customer = new Customer();<br />customer.Name = “VasyaPupkin”;<br />var order = new Order();<br />order.Customer = customer;<br />order.Date = new DateTime(2009, 10, 11);<br />varorderItem = new orderItem(); <br />orderItem.Product = new Product(“Chips”);<br />orderItem.Amount = 3;<br />orderItem.Price = 45.30;<br />order.Items.Add(orderItem);<br />orderItem.Product = new Product(“Beer”);<br />orderItem.Amount = 3;<br />orderItam.Price = 20.50;<br />order.Items.Add(orderItem);<br />
    48. 48. DSL<br />var order = new OrderBuilder()<br /> .WithCustomer(“VasyaPupkin”)<br /> .WithDate(11.10.of2009())<br /> .WithLineItem()<br /> .WithProduct(“Chips”)<br /> .WithAmount(3)<br /> .WithPrice(45.30)<br /> .WithLineItem()<br /> .WithProduct(“Beer”)<br /> .WithAmount(3)<br /> .WithPrice(20.50)<br /> .GetResult();<br />
    49. 49. GoF / PoEAAGang of Four / Patterns of Enterprise Application Architecture<br />
    50. 50. Зачем паттерны?<br />
    51. 51. Спецификация<br />Динамические фильтры<br />InfrastructureFacade.Get&lt;T&gt;( Specification&lt;T&gt; specification)<br />Дублирование условий<br />
    52. 52. Спецификация<br />// if order is critical<br />if (order.Amount &gt;= 1000000) {<br /> …<br />}<br />
    53. 53. Спецификация<br />public class CriticalOrder {<br /> public boolIsSatisfiedBy(Order order) {<br /> return order.Amount &gt;= 1000000;<br /> }<br />}<br />
    54. 54. Спецификация<br />public class CriticalOrder {<br /> private readonlyintminimalAmount;<br /> public CriticalOrder(intminimalAmount) {<br />this.minimalAmount = minimalAmount;<br /> }<br /> public boolIsSatisfiedBy(Order order) {<br /> return order.Customer.Type ==<br />CustomerType.KeyCustomer &&<br />order.Amount &gt;= minimalAmount;<br /> }<br />}<br />
    55. 55. Композитные спецификации<br />var specification =<br />new CriticalOrder(<br />CustomerType.KeyCustomer, <br />200000) &<br />new SoldTo(new Country(&quot;Russia&quot;)) &<br />new AsOf(2009);<br />
    56. 56. Что дают шаблоны<br />Повторное использование<br />Расширяемость<br />Гибкость<br />SOLID<br />
    57. 57. Profit!<br />
    58. 58. Результатыдля разработчиков<br />Хорошая оценка Microsoft<br />Тестируемость<br />Поддерживаемость<br />Гибкость дизайна<br />Концептуальная целостность<br />Повторное использование<br />
    59. 59. Результаты для бизнеса<br />Нет регрессионных багов<br />Гибкость требований<br />Быстрая разработка<br />Легкость при обсуждении требований<br />
    60. 60. Резюме<br />DDD<br />MVP/MVVM<br />TDD<br />DSL<br />GoF/PoEAA<br />…<br />Profit!<br />
    61. 61. ?<br />
    62. 62. Антон Бевзюк<br />Anton.Bevzjuk@intel.com<br />Евгений Сорокин<br />Evgeny.Sorokin@intel.com<br />Для журналистов:<br />parus@intel.com<br />
    63. 63.
    64. 64. Backup<br />
    65. 65. Не все гладко<br />Передача другой команде<br />Производительность<br />Безопасность<br />Тяжелый solution<br />
    66. 66. MSBuild<br />Deploy<br />Сборка приложения<br />Прогон тестов<br />Деплой файлов<br />Запуск SQLScript<br />Разные конфигурации для DEV/CONS/PROD<br />Nightly Build<br />Метрики<br />CheckIn<br />Рассылка результатов<br />
    67. 67. Continuous Integration<br />MSBuild<br />Частый деплой<br />Разные environments<br />Безопасность<br />
    68. 68. ClickOnce<br />
    69. 69. ReSharper<br />
    70. 70. Комментарии<br />Их нет!<br />
    71. 71. Самый большой agile-проект<br />2 года<br />Разработчики<br />

    ×