Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Принципы и практики
разработки ПО
UML SOLID
SRP Single Responsibility Principle
OCP Open Close Principle
LSP Liskov Substi...
Motivation
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
?
Inversion of Control (IoC)
Inversion of Control (IoC)
{
}
Inversion of Control (IoC)
def download_clicks(date_from, date_to):
downloader = DiggerDownloader("https://digger.2gis.ru"...
Inversion of Control
def download_clicks(date_from, date_to, downloader):
result = downloader.download(date_from, date_to)...
Inversion of Control
def download_clicks(date_from, date_to, downloader):
result = downloader.download(date_from, date_to)...
Inversion of Control
class DiggerDownloader:
def download(self, date_from, date_to):
...
class DiggerDonwloaderMock:
def d...
SOLID principles
SOLID principles
S SRP
O OCP
L LSP
I ISP
D DIP
Single Responsibility Principle
Open-Close Principle
Liskov Substitution Pr...
Single Responsibility Principle
def download_clicks(date_from, date_to):
with Session() as session:
projects = session.get...
Single Responsibility Principle
def download_clicks(date_from, date_to):
with Session() as session:
projects = session.get...
Single Responsibility Principle
def download_clicks(date_from, date_to, downloader, config_path):
raw_clicks = downloader....
Dependency Inversion Principle
def download_clicks(date_from, date_to, downloader, config_path):
raw_clicks = downloader.d...
Interface Segregation Principle
class DiggerDownloader:
def file_download(self, link, destination):
pass
def async_downloa...
Interface Segregation Principle
class DiggerDownloader:
def file_download(self, link, destination):
pass
def async_downloa...
Interface Segregation Principle
class DiggerDownloader:
def submit_download(self, task_definition: TaskDefinition) -> Task...
Interface Segregation Principle
class DiggerDownloader:
def submit_download(self, task_definition: TaskDefinition) -> Task...
SOLID principles
S SRP
O OCP
L LSP
I ISP
D DIP
Single Responsibility Principle
Open-Close Principle
Liskov Substitution Pr...
Testing
def download_clicks(date_from, date_to, downloader, config_path):
raw_clicks = downloader.download(date_from, date...
Testing
def download_clicks(date_from, date_to, downloader, config_path):
raw_clicks = downloader.download(date_from, date...
Testing
def make_clicks(raw_clicks, factor):
result_clicks = {}
for project_id, clicks in raw_clicks.items():
for object_i...
The end
Upcoming SlideShare
Loading in …5
×

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

Lecture about software development practices and principles.

This is the first talk I gave at 2GIS internal meetup.

  • Be the first to comment

  • Be the first to like this

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

  1. 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. 2. Motivation
  3. 3. { }
  4. 4. { }
  5. 5. { }
  6. 6. { }
  7. 7. { } { } { } { }
  8. 8. { } { } { } { }
  9. 9. { } { } ?
  10. 10. Inversion of Control (IoC)
  11. 11. Inversion of Control (IoC) { }
  12. 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. 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. 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. 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. 16. SOLID principles
  17. 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. 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. 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. 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. 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. 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. 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. 24. Interface Segregation Principle class DiggerDownloader: def submit_download(self, task_definition: TaskDefinition) -> Task: pass def download(self, task_definition: TaskDefinition) -> Result: pass
  25. 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. 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. 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. 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. 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. 30. The end

×