ООП для чайников. Паттерны проектирования. Адаптер (adapter)

С недавнего времени, мы в команде завели такую практику как обмен опытом. Сначала мы пробовали просто готовить доклады, на всякого рода интересные темы касающиеся технологий, практик и подходов. Но, этот подход не совсем себя оправдал, и мы стали готовить небольшие доклады на заранее оговоренные темы, например, — паттерны проектирования.

Идея состоит в том что мы выбираем несколько паттернов, делаем лаконичный пример использования, на каком-то языке не связанной с основной работой (php). Затем мы собираемся, показываем свои примеры, и обсуждаем конкретный паттерн и реализацию. Так у нас накопилось некоторое количество реализаций на Python, Ruby, Groovy. На самом деле, как мы потом убедились, выбор скриптового языка для иллюстрации паттерна, идея не очень хорошая, — нельзя выделить интерфейс, абстрактный класс, вследствие отсутствия строгой типизации смысл некоторых паттернов теряется, некоторые патерны трудно отличить один от другого. Наверное в дальнейшем мы ограничимся языками со строгой типизацией для паттернов, а скриптовые будем использовать для иллюстрации алгоритмов. Время покажет.

После столь долгого вступления, расскажу о первом паттерне Адаптер и примере его реализации на питоне. Этот паттерн относится к структурным паттернам (structural). Вот как он выглядит на диаграмме классов:

adapter

Этот паттерн используется в случае когда надо преобразовать интерфейс одного класса, в интерфейс другого, ожидаемого клиентом. Другими словами, — делает возможным работу классов с несовместимыми интерфейсами. В моем примере это какая-то, уже написанная и реализованная клиентская библиотека, использующая медленную библиотеку для взаимодействия с базой. новая библиотека отличается способом инициализации и вызова запросов. Используя адаптер, мы позволяем клиентской программе использовать новый движок баз данных, прозрачно для клиента, оставляя возможность использовать старый движок (если надо).

Код примера реализации паттерна:

class SlowDbEngine:
    
    def __init__(self, host, user, password, db):
        pass
    
    def runQuery(self, sql):
        return ["row1", "row2", "row3"]
     
class FastDbEngine:
    
    def __init__(self, connection):        
        pass        
    
    def query(self, sql):
        return range(3, 0, -1)
    
    def fetch(self, result):
        return "row%d" % (result.pop())
    
    def recordsCount(self, result):
        return len(result)
    
    
class DbAdapter:
        
    def __init__(self, host, user, password, db, type = "fast"):
        self._type = type
        if(type == "slow"):
            self._db = SlowDbEngine(host, user, password, db)
        else:
            self._db = FastDbEngine([host, user, password, db])
    
    def runQuery(self, sql):
        if self._type == "slow":
            return self._db.runQuery(sql)
        else:
            result = self._db.query(sql)                            
            return [self._db.fetch(result) for i in xrange(self._db.recordsCount(result))]
      
if __name__ == '__main__':   
    print(DbAdapter("localhost", "root", "password", "db").runQuery("select * from table"))

-----------------------

['row1', 'row2', 'row3']

Site Footer

Sliding Sidebar

About Me

About Me

For whom this blog for?

For those who are interested in modern Internet technologies, IT business, startups, management, quality control, personal effectiveness, motivation. Here I write about what is interesting, about problems I faced and solutions I found. I hope it will be interesting to you either.

What motivates me to write?

The desire to improve, to study deeper topics that interest me. Find people with similar problems and tasks, together look for ways out and solutions.

Feel free to contact if you have anything to say to me

Old Flash site with my artistic works and misuc.