Advertisement
Advertisement

More Related Content

Advertisement

More from Alexander Granin(20)

Recently uploaded(20)

Advertisement

Принципы и практики разработки ПО / Principles and practices of software development

  1. Принципы и практики разработки ПО UML SOLID SRP Single Responsibility Principle OCP Open Close Principle LSP Liskov Substitution Principle ISP Interface Segregation Principle DIP Dependency Injection Principle Encapsulation Inheritance Polymorphism AbstractionG.R.A.S.P. Inversion of Control
  2. Motivation
  3. { }
  4. { }
  5. { }
  6. { }
  7. { } { } { } { }
  8. { } { } { } { }
  9. { } { } ?
  10. Inversion of Control (IoC)
  11. Inversion of Control (IoC) { }
  12. Inversion of Control (IoC) def download_clicks(date_from, date_to): downloader = DiggerDownloader("https://digger.2gis.ru", "user", "pass") result = downloader.download(date_from, date_to) return make_clicks(result) def main(): clicks = download_clicks("01.01.2001", "01.03.2001") do_something(clicks)
  13. Inversion of Control def download_clicks(date_from, date_to, downloader): result = downloader.download(date_from, date_to) return make_clicks(result) def main(): downloader = DiggerDownloader("https://digger.2gis.ru", "user", "pass") clicks = download_clicks("01.01.2001", "01.03.2001", downloader) do_something(clicks)
  14. Inversion of Control def download_clicks(date_from, date_to, downloader): result = downloader.download(date_from, date_to) return make_clicks(result) def main(): downloader = DiggerDownloader("https://digger.2gis.ru", "user", "pass") clicks = download_clicks("01.01.2001", "01.03.2001", downloader) do_something(clicks) def test_download_clicks(): test_downloader = DiggerDownloader("https://test_digger.local", "user", "pass") clicks = download_clicks("01.01.2001", "01.03.2001", test_downloader) assert(len(clicks) > 0)
  15. Inversion of Control class DiggerDownloader: def download(self, date_from, date_to): ... class DiggerDonwloaderMock: def download(self, date_from, date_to): return [("branch", 1, 1020), ("street", 2, 4)] def test_download_clicks(): test_downloader = DiggerDownloaderMock() clicks = download_clicks("01.01.2001", "01.03.2001", test_downloader) assert(len(clicks) > 0)
  16. SOLID principles
  17. SOLID principles S SRP O OCP L LSP I ISP D DIP Single Responsibility Principle Open-Close Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle
  18. Single Responsibility Principle def download_clicks(date_from, date_to): with Session() as session: projects = session.get("http://search.2gis.one/projects") with open("config.json") as cfg: config = json.load(cfg) downloader = DiggerDownloader("https://digger.2gis.ru", "user", "pass") raw_clicks = downloader.download(date_from, date_to) result_clicks = {} for project_id, clicks in raw_clicks.items(): for object_id, count in clicks.items(): if object_id in result_clicks: result_clicks[object_id] += config['factor'] * count else: result_clicks[object_id] = config['factor'] * count return (result_clicks, projects)
  19. Single Responsibility Principle def download_clicks(date_from, date_to): with Session() as session: projects = session.get("http://search.2gis.one/projects") with open("config.json") as cfg: config = json.load(cfg) downloader = DiggerDownloader("https://digger.2gis.ru", "user", "pass") raw_clicks = downloader.download(date_from, date_to) result_clicks = {} for project_id, clicks in raw_clicks.items(): for object_id, count in clicks.items(): if object_id in result_clicks: result_clicks[object_id] += config['factor'] * count else: result_clicks[object_id] = config['factor'] * count return (result_clicks, projects)
  20. Single Responsibility Principle def download_clicks(date_from, date_to, downloader, config_path): raw_clicks = downloader.download(date_from, date_to) with open(config_path) as cfg: config = json.load(cfg) return make_clicks(raw_clicks, config['factor']) def make_clicks(raw_clicks, factor): result_clicks = {} for project_id, clicks in raw_clicks.items(): for object_id, count in clicks.items(): if object_id in result_clicks: result_clicks[object_id] += config['factor'] * count else: result_clicks[object_id] = config['factor'] * count return result_clicks
  21. Dependency Inversion Principle def download_clicks(date_from, date_to, downloader, config_path): raw_clicks = downloader.download(date_from, date_to) with open(config_path) as cfg: config = json.load(cfg) return make_clicks(raw_clicks, config['factor']) class DiggerDownloader: def download(self, date_from, date_to): ... def main(): downloader = DiggerDownloader("https://digger.2gis.ru", "user", "pass") clicks = download_clicks("01.01.2001", "01.03.2001", downloader, "config.json") do_something(clicks)
  22. Interface Segregation Principle class DiggerDownloader: def file_download(self, link, destination): pass def async_download_by_sql(self, params): pass def download_by_sql(self, sql, date_from, date_to, out_file): pass def task_add(self, sql, date_from, date_to): pass def task_wait(self, task_id): pass def task_get(self, task_id): pass
  23. Interface Segregation Principle class DiggerDownloader: def file_download(self, link, destination): pass def async_download_by_sql(self, params): pass def download_by_sql(self, sql, date_from, date_to, out_file): pass def task_add(self, sql, date_from, date_to): pass def task_wait(self, task_id): pass def task_get(self, task_id): pass
  24. Interface Segregation Principle class DiggerDownloader: def submit_download(self, task_definition: TaskDefinition) -> Task: pass def download(self, task_definition: TaskDefinition) -> Result: pass
  25. Interface Segregation Principle class DiggerDownloader: def submit_download(self, task_definition: TaskDefinition) -> Task: pass def download(self, task_definition: TaskDefinition) -> Result: pass class Task: def wait(self, timeout): pass def status(self) -> Status: pass def result(self) -> Result: pass
  26. SOLID principles S SRP O OCP L LSP I ISP D DIP Single Responsibility Principle Open-Close Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle
  27. Testing def download_clicks(date_from, date_to, downloader, config_path): raw_clicks = downloader.download(date_from, date_to) with open(config_path) as cfg: config = json.load(cfg) return make_clicks(raw_clicks, config['factor'])
  28. Testing def download_clicks(date_from, date_to, downloader, config_path): raw_clicks = downloader.download(date_from, date_to) with open(config_path) as cfg: config = json.load(cfg) return make_clicks(raw_clicks, config['factor']) def test_download_clicks(): test_downloader = DiggerDownloaderMock() clicks = download_clicks("01.01.2001", "01.03.2001", test_downloader, "config.json") assert(len(clicks) > 0)
  29. Testing def make_clicks(raw_clicks, factor): result_clicks = {} for project_id, clicks in raw_clicks.items(): for object_id, count in clicks.items(): if object_id in result_clicks: result_clicks[object_id] += config['factor'] * count else: result_clicks[object_id] = config['factor'] * count return result_clicks def test_make_clicks_no_data(): clicks = make_clicks({}, 1) assert(len(clicks) == 0)
  30. The end
Advertisement