Рубрики
Без рубрики

Узор репозитория с казонитом

Как реализовать шаблон репозитория с приложением Masonite. Теги с Python, Framework, Masonite, учебником.

Эта статья будет ходить, как реализовать шаблон репозитория с Масонит заявление.

«Шаблон репозитория» всегда был странным для меня и никогда не имел смысла относительно того, почему он называется репозиторий. Может быть, потому что я считаю, что имя «репозиторий» должно быть оставлено на версию контроль репозиториев Так что для меня трудно связать второе определение для репозитория слова.

Для целей этой статьи и вашей жизни движется вперед, давайте подумаем о репозитории как «Коллекция данных, которые вы можете использовать в вашем логическом слое бизнеса».

Может быть, для дальнейшего объяснения, в любом приложении 4 слоя:

  • Бизнес логический слой (контроллеры)
  • Презентационный логический слой (просмотры)
  • Слой вступления данных (модели)
  • Слой хранения данных (базы данных/mysql/postgres/etc etc)

Как правило, хорошая идея не смешивать эти слои вместе, потому что они обычно плотно пару одна реализация на другую. После написания программного обеспечения на некоторое время вы могли бы реализовать, что вы делаете это все время, импортируя модели в логику вашего контроллера.

Таким образом, большинство раз мы используем наши модели внутри наших контроллеров, просто импортируя их в файл и используя их. Допустим, мы строим программу обслуживания ведущих бизнес-ведущих услуг для нашего нынешнего работодателя:

from app import Leads

class SomeController:

    def show(self):
        leads = Leads.all()

Отлично, так что это получает все ведущие от модели ведущих. Но что, если у нас есть несколько отдельных ведущих моделей. У нас может быть что-то подобное:

from app import LocalLeads, ForeignLeads

class SomeController:

    def show(self):
        local_leads = LocalLeads.all()
        foreign_leads = ForeignLeads.where('sales_id', '>', 20).get()

Это может быть то, что нам нужно сделать в нескольких методах контроллера:

from app import LocalLeads, ForeignLeads, WallStreetLeads

class SomeController:

    def show(self):
        local_leads = LocalLeads.all()
        foreign_leads = ForeignLeads.where('sales_id', '>', 20).get()

        # More Logic Here
        ...

        return view('sales', 
            {'local': local_leads,
            'foreign': foreign_leads
            ...
            }) 

    def sales(self):
        local_leads = LocalLeads.all()
        foreign_leads = ForeignLeads.where('sales_id', '>', 20).get()

        # More Logic Here
        ...

        return view('sales', 
            {'local': local_leads,
            'foreign': foreign_leads
            }) 

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

Репозитории помогают с этим, сделав все логику вступления модели в 1 месте, мы можем делиться в любых частях нашего кода. Любые изменения, которые необходимо сделать или выполнены в репозитории, не наших контроллеров, промежуточных программ или других частей нашего кода.

Одно решение было бы поставить всю эту логику в конструктор, если они всегда одинаковы в каждом способе:

from app import LocalLeads, ForeignLeads

class SomeController:

    def __init__(self):
        self.local_leads = LocalLeads.all()
        self.foreign_leads = ForeignLeads.where('sales_id', '>', 20).get()

    def show(self):

        # More Logic Here
        ...

        return view('sales', 
            {'local': self.local_leads,
            'foreign': self.foreign_leads
            ...
            }) 

    def sales(self):

        # More Logic Here
        ...
        return view('sales', 
            {'local': self.local_leads,
            'foreign': self.foreign_leads
            ...
            }) 

Сценарий реального мира

Но вопрос заключается в том, что, если им нужно случайно на основе метода контроллера, в котором они есть. В сценарии реального мира у нас, вероятно, имеем что-то подобное, где они обычно разные:

from app import LocalLeads, ForeignLeads
class SomeController:

    def show(self):
        local_leads = LocalLeads.all()
        foreign_leads = ForeignLeads.where('sales_id', '>', 20).get()

        # More Logic Here
        ...
        return view('sales', 
            {'local': local_leads,
            'foreign': foreign_leads
            }) 

    def sales(self):
        local_leads = LocalLeads.first()
        foreign_leads = ForeignLeads.where('order_id', 2).get()

        # More Logic Here
        ...

        return view('sales', 
            {'local': local_leads,
            'foreign': foreign_leads
            }) 

Теперь мы не можем действительно абстрагироваться эти ценности. Плюс вся эта логика очень избыточная.

Это не только проблема для этого контроллера, но что, если нам нужно использовать ту же точную логику в другом контроллере? Теперь нам нужно в основном скопировать и вставлять всю логику на второй или даже третий контроллер, когда-нибудь по дороге.

Мы можем просто сделать класс репозитория. Использование Masonite мы можем добавить его в Приложение/Репозитории каталог:

app/
  http/
  repositories/
    LeadRepository.py

Давайте откроем этот репозиторий вверх и сделайте базовый класс:

class LeadRepository:

    def get_sales():
        pass

    def get_domestic_sales():
        pass

Хорошо, отлично, поэтому у нас есть репозиторий, который мы хотим получить все продажи и все внутренние продажи. Давайте попробуем абстрактно, что мы имели в нашем контроллере здесь. Для целей этого конкретного применения мы поставим каждый в словарь, потому что это может быть наше требование:

from app import LocalLeads, ForeignLeads

class LeadRepository:

    def get_sales():
        return {
            'local': LocalLeads.all(),
            'foreign': ForeignLeads.where('sales_id', '>', 20).get()
        }

    def get_domestic_only():
        return {
            'local': LocalLeads.all(),
            'foreign': ForeignLeads.where('country', 'US').get()
        }

Отлично сейчас давайте импомнем это в наш контроллер и попробуйте еще раз:

from app.repositories import LeadRepository

class SomeController:

    def __init__(self):
        self.leads = LeadsRepository()

    def show(self):
        sales = self.leads.get_sales()


        # More Logic Here
        ...

        return view('sales', 
            {'local': sales['local'],
            'foreign': sales['foreign']
            }) 


    def sales(self):
        sales = self.leads.get_domestic_only()


        # More Logic Here
        ...

        return view('sales', 
            {'local': sales['local'],
            'foreign': sales['foreign']
            }) 

Отлично это так! Репозиторий можно использовать для абстрагирования любой динамической модели, которую мы могли бы использовать в нескольких контроллерах или даже на протяжении всего нашего приложения. Теперь мы можем взять этот репозиторий и добавить его на любые контроллеры, нам это нужно, и вся логика остается в одном месте в нашем коде.

Если вам понравилась эта статья, обязательно отправляйтесь на Github repo и дать ему звезду или присоединиться к Masonite Slack Channel.

Оригинал: “https://dev.to/masonite/repository-pattern-with-masonite-4a0n”