Чистый код 2/CS 2

Владимир Селюх

Разработчик ПО

Что мы сегодня обсудим?

1. Что такое хорошая архитектура и как она связана с кодом?

2. Что такое чистая архитектура и как она связана с кодом?

3. CS:

  • Развитие компьютера

  • Машина Тьюринга

  • Архитектура фон Неймана

Хорошая Архитектура

 

  • Легкость в освоении

  • Простота в разработке

  • Простота в сопровождении

  • Простота в развертывании

Хорошая Архитектура

Конечная цель хорошей архитектуры:

  • Минимизация затрат на разработку

  • Максимизация продуктивности программиста

Хорошая Архитектура

Что можно использовать в коде:

  • Принципы SOLID

  • Организовывать взаимосвязи компонентов обдуманно

  • Использовать здравый смысл

Хорошая Архитектура

Что можно использовать вне кода:

  • стремится к "чистой архитектуре"

  • уменьшить внешние зависимости(БД, микросервисы, сторонние утилиты)

  • упростить развертывание

  • использовать здравый смысл

S.O.L.I.D

Хорошая Архитектура. Код.

Принципы S.O.L.I.D:

The Single Responsibility Principle

Bad​

class Email:
    body = None
    def __init__(self, ip_address):
        self.sender = smtp.init(ip_address)
    
    def prepare_customer(self, text):
        self.body = add_customer_header_footer(text)

    def prepare_vip_customer(self, text):
        self.body = add_vip_customer_header_footer(text)
    
    def send(self, addr):
        self.sender.send(addr, self.body)

The Single Responsibility Principle

Better​

class EmailSender:
    body = None
    def __init__(self, ip_address):
        self.sender = smtp.init(ip_address)
    
    def send(self, addr, cc = None):
        if cc == None:
            self.sender.send(addr, self.body)
        self.sender.send(addr, self.body, cc=cc)

class EmailPreparer():
    def prepare_customer(self, text):
        return add_customer_header_footer(text)

    def prepare_vip_customer(self, text):
        return add_vip_customer_header_footer(text)

The Open Closed Principle

Bad​

class Gif():
    def __init__(self, height, width):
        self.height, self.width = height, width 

class Jpeg():
    def __init__(self, height, width, someshit):
        self.height = height
        self.width = width 
        self.someshit = someshit

def get_images_size_sum(images_list = None):
    sum = 0
    for img in images_list:
        if isinstance(img, Gif):
            sum += img.height*img.width*3
        if isinstance(img, Gif):
            sum += img.height*img.width*12
        else:
            # HZ some magic shit
            sum += img.height*img.width
    return sum

The Open Closed Principle

Better​

class Gif():
    def __init__(self, height, width):
        self.height, self.width = height, width
    def get_size(self):
        return self.height*self.width*3

class Jpeg():
    def __init__(self, height, width, someshit):
        self.height = height
        self.width = width 
        self.someshit = someshit
    def get_size(self):
        return self.height*self.width*12

def get_images_size_sum(images_list = None):
    sum = 0
    for img in images_list:
            sum += img.get_size()
    return sum

The Liskov Substitution Principle

Bad

class SomeController():
    def __before__(self, request):
        request.size = request.size+2
        do_something(request)
    
    def api_index(self, request):
        do_something_else(request)

class MyOwesomeConroller(SomeController):
    def __pre_before__(self, request):
        request.size = request.size+1
        do_something(request)

    def __before__(self, request):
        super(MyOwesomeConroller, self).__before__()

The Liskov Substitution Principle

Better

 

class SomeController():
    def __before__(self, request):
        request.size = request.size+2
        do_something(request)
    
    def api_index(self, request):
        do_something_else(request)

class MyOwesomeConroller(SomeController):
    def __before__(self, request):
        request.size = request.size+1
        do_something_else(request)
        super(MyOwesomeConroller, self).__before__()

The Interface Segregation Principle

Bad

 

class SomeController():
    def base_api(self, document, is_jpg, is_ajax, is_json, is_sms):
        if is_jpg:
            return jpg(document)
        elif is_ajax:
            return ajax(document)
        elif is_sms and not is_json:
            return sms(document)
        elif is_sms and is_json:
            return json_sms_to_esputnic(document)
        elif is_json:
            return json(document)
        else:
            reborn areufuknkiddingme(document)

The Interface Segregation Principle

Better

 

class SomeController():
    def jpg_api(self, document):
        return jpg(document)

    def ajax_api(self, document):
        return ajax(document)

    def json_api(self, document):
        return json(document)
    
    def sms_api(self, document, is_json):
        if not is_json:
            return sms(document)
        else:
            return json_sms_to_esputnic(document)

The Dependency Inversion Principle

Bad

 

class DBService(object):
    """DB"""

class AsteriskService(object):
    """Asterisk"""

class Client(object):
    def __init__(self):
        self.db_service = DBService()
        self.asterisk_service = AsteriskService()


if __name__ == '__main__':
    client = Client()

The Dependency Inversion Principle

Better

class DBService(object):
    """DB"""
class AsteriskService(object):
    """Asterisk"""
class Client(object):
    def __init__(self, db, asterisk):
        self.db_service = db
        self.asterisk_service = asterisk
if __name__ == '__main__':
    try:
        db = DBService()
    except:
        log("Db is only a helper. No need")
        db = None # no db its ok
    try:
        asterisk = AsteriskService()
    except:
        log("We can't work without Asterisk! So we must die")
        raise
    client = Client(db, asterisk)

Взаимосвязь компонентов

Хорошая Архитектура. Код.

Здравый смысл

Хорошая Архитектура

Что можно использовать вне кода:

  • стремится к "чистой архитектуре"

  • упростить развертывание

  • использовать здравый смысл

Хорошая Архитектура. Вне кода.

Чистая Архитектура

Хорошая Архитектура. Вне кода.

Чистая Архитектура

  1. Независимость от фреймворка.

  2. Тестируемость.

  3. Независимоcть от UI.

  4. Независимоcть от базы данных.

  5. Независимость от какого-либо внешнего сервиса.

 

Хорошая Архитектура. Вне кода.

      Развертывание:

  • kubernetes

  • docker swarm

  • verwalter 

Хорошая Архитектура. Вне кода.

Здравый смысл

CS 2

Что обсудим:

  • Как мы пришли к такой архитектуре ПК

  • Архитектура фон Неймана

  • Машина Тьюринга. Полнота по Тьюрингу.

  • Зачем ты нам все это рассказал?

От реле до транзистора

Реле

10 км

10 км

От реле до транзистора

Переключатели

От реле до транзистора

Переключатели

От реле до транзистора

Вентили

От реле до транзистора

Вентили

От реле до транзистора

Сумматор

10

Сумма

От реле до транзистора

От реле до транзистора

Сумматор(8и разрядный мультиплексор)

От реле до транзистора

Память

От реле до транзистора

Память

От реле до транзистора

Память

От реле до транзистора

Транзистор

От реле до транзистора

Транзистор

От реле до транзистора

Процессор 8 бит

Архитектура фон Неймана

Архитектура фон Неймана

Машина Тьюринга.

Полнота по Тьюрингу.

Полнота по Тьюрингу.

Характеристика исполнителя (множества вычисляющих элементов) в теории вычислимости, означающая возможность реализовать на нём любую вычислимую функцию. Другими словами, для каждой вычислимой функции существует вычисляющий её элемент (например, машина Тьюринга) или программа для исполнителя, а все функции, вычисляемые множеством вычислителей, являются вычислимыми функциями (возможно, при некотором кодировании входных и выходных данных). Wikipedia

Полнота по Тьюрингу.

1. Пишите за день свой язык программирования

2. Пишите на нем за ночь машину тьюринга

3. Пишите за неделю linux на нем

....

5. PROFIT!!!!!!!!!!!!!!

ЗАЧЕМ????

Архитектура ПК влияет на алгоритмы и реализацию

Array Search vs Binary Tree Search

O(N) vs O(logN)

Array Wins

Python Array Wins

 

 

 

 

 

Но не сильно

Источники

 

  • Чистая архитектура

  • Код. Тайный язык информатики.

  • Совершенный код

  • Чистый код

  • Программист-прагматик

  • Архитектура корпоративных программных приложений

  • Рефакторинг. Улучшение существующего кода

  • Эффективная работа с унаследованным кодом 

Чистый код 2 / CS 2 Evo SPL 2018

By Volodymyr Selyukh

Чистый код 2 / CS 2 Evo SPL 2018

  • 635