Курсовые - Интернет-каталог косметики

Применение шаблона проектирования практических решений

6 Применение шаблона проектирования практических решений

 

Шаблон проектирования (design patterns) – это многократно используемые решения распространённых проблем, возникающих при разработке программного обеспечения.

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

Что бы программист ни разрабатывал, на каком бы языке он ни писал, если он стремится к хорошему коду, он будет использовать шаблоны проектирования. Он стремится повторно воспользоваться решениями, которые оказались удачливыми ранее.

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

 В зависимости от назначения выделяют:

1. Структурные шаблоны (structural patterns) – показывают, как объекты и классы объединяются для образования сложных структур.

2. Порождающие шаблоны (creational patterns) – контролируют процесс создания и жизненный цикл объектов.

3. Шаблоны поведения (behavioral patterns) – используются для организации, управления и объединения различных вариантов поведения объектов.

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

Практические решения, в свою очередь, подразделяются на порождающие паттерны, структурные паттерны и паттерны поведения.

1) Порождающие паттерны или паттерны создания объектов: абстрактная фабрика, одиночка, прототип, строитель, фабричный метод.

Первая группа - это creational паттерны. Они в той или иной степени работают с механизмами создания объектов.

Singleton - обеспечиваем существование в системе ровно одного экземпляра некоторого класса;

Factory Method - делегируем процесс создания объектов классам-наследникам;

Prototype - клонируем объекты на основании некоторого базового объекта;

Builder - отделяем процесс создания комплексного объекта от его представления;

Abstract Factory - описываем сущность для создания целых семейств взаимосвязанных объектов.

2) Структурные паттерны: адаптер, декоратор, заместитель, компоновщик, мост, приспособленец, фасад. Они описывают создание более сложных объектов, либо упрощают работу с другими объектами сисетмы.

Adapter - на основании некоторого класса создаем необходимый клиенту интерфейс;

Facade - описываем унифицированный интерфейс для облегчения работы с набором подсистем;

Composite - работаем с базовыми исоставными объектами единым образом;

Decorator - динамически добавляем новую функциональность некоторому объекту, сохраняя его интерфейс;

Proxy - создаем объект, который перехватывает вызовы к другому объекту;

Bridge - разделяем абстракцию от интерфейса, позволяя им меняться независимо;

Flyweight - эффективно работаем с огромным количеством схожих объектов.

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

Они определяют эффективные способы взаимодействия различных объектов в системе.

Strategy - описываем набор взаимозаменяемых алгоритмов с единым интерфейсом;

Iterator - обеспечиваем доступ к коллекциям объектов без раскрытия внутреннего устройства этих коллекций;

Observer - создаем объект для отслеживания изменений в подсистеме и нотификации других подсистем;

Memento - сохраняем внутреннее состояние объекта для последующего использования без нарушения инкапсуляции;

Command - описываем объект, представляющий собой некоторое действие, которое можно выполнить в необходимый момент;

Interpreter - определяем способ вычисления выражений некоторого языка;

Mediator - создаем объект, которые регулирует взаимодействие между набором подсистем;

State - позволяем объекту менять свое поведение при изменении его внутреннего состояния;

Template method - описываем алгоритм, возлагая реализацию некоторых частей алгоритма на подклассы;

Visitor - отделяем алгоритм от структуры, с которыми алгоритм работает;

Chain of responsibility - пропускаем некоторый запрос через набор обработчиков событий, до тех пор пока запрос не будет обработан.

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

Сразу же стоит указать на ограничения по их применению.

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

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

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

 

 

 

6.1 CRUD

 

Create, Read, Update and Delete (создание, чтение, обновление и удаление)

Рассмотрим разработку CRUD по пунктам.

1 Маршрутизация (Get-данные)

Прописываем команду

rails generate controller Products create

Это создаст нам контроллер в папке app/controllers/products.rb и в нём будет метод index. И папку для отображения view/products и в ней можно создать имя совпадающие с методом чтобы он использовался автоматический, в нашем случаи создастся create.html.rb (.html.rb используется для view engine в RoR). В нашем случаи библиотека spree сделал всё это за нас командами, описанными выше и создала папкм view/spree (admin – для страниц администратора и другие страницы для общего отображения обычным пользователям).

2 Создание форм

Создана форма в app/view/spree/admin/products/new.html.erb. В которой мы используем хелпер form_for для создания формы.

Код:

new.html.rb

 

<%= form_for [:admin, @product], html: { multipart: true } do |f| %>

  <fieldset data-hook="new_product">

    <%= f.field_container :name, class: ['form-group'] do %>

      <%= f.label :name, Spree.t(:name) %> <span class="required">*</span>

      <%= f.text_field :name, class: 'form-control title', required: :required %>

      <%= f.error_message_on :name %>

    <% end %>

 

    <div data-hook="new_product_attrs" class="row">

      <% unless @product.has_variants? %>

        <div data-hook="new_product_sku" class="col-xs-12 col-md-4">

          <%= f.field_container :sku, class: ['form-group'] do %>

            <%= f.label :sku, Spree.t(:sku) %>

            <%= f.text_field :sku, size: 16, class: 'form-control' %>

            <%= f.error_message_on :sku %>

          <% end %>

        </div>

      <% end %>

 

      <div data-hook="new_product_prototype" class="col-xs-12 col-md-4">

        <%= f.field_container :prototype, class: ['form-group'] do %>

          <%= f.label :prototype_id, Spree.t(:prototype) %>

          <%= f.collection_select :prototype_id, Spree::Prototype.all, :id, :name, {include_blank: true}, {class: 'select2'} %>

        <% end %>

      </div>

 

      <div data-hook="new_product_price" class="col-xs-12 col-md-4">

        <%= f.field_container :price, class: ['form-group'] do %>

          <%= f.label :price, Spree.t(:master_price) %> <span class="required">*</span>

          <%= f.text_field :price, value: number_to_currency(@product.price, unit: ''), class: 'form-control', required: :required %>

          <%= f.error_message_on :price %>

        <% end %>

      </div>

 

      <div data-hook="new_product_available_on" class="col-xs-12 col-md-4">

        <%= f.field_container :available_on, class: ['form-group'] do %>

          <%= f.label :available_on, Spree.t(:available_on) %>

          <%= f.error_message_on :available_on %>

          <%= f.text_field :available_on, class: 'datepicker form-control' %>

        <% end %>

      </div>

 

      <div data-hook="new_product_shipping_category" class="col-xs-12 col-md-4">

        <%= f.field_container :shipping_category, class: ['form-group'] do %>

          <%= f.label :shipping_category_id, Spree.t(:shipping_categories) %><span class="required">*</span>

          <%= f.collection_select(:shipping_category_id, @shipping_categories, :id, :name, { include_blank: Spree.t('match_choices.none') }, { class: 'select2', required: :required }) %>

          <%= f.error_message_on :shipping_category_id %>

        <% end %>

      </div>

 

    </div>

 

    <div data-hook="product-from-prototype" id="product-from-prototype">

      <%= render file: 'spree/admin/prototypes/show' if @prototype %>

    </div>

 

    <%= render partial: 'spree/admin/shared/new_resource_links' %>

 

  </fieldset>

<% end %>

 

3 Создание миграции в spree

Миграция, модель созданы в разделе  4.

Для создания миграций в RoR можно использовать команду rails migration:create название_миграции
Для миграции необходимо выполнить команду rails db:migrate
Всю схему бд можно найти в db/schema.rb и все миграции в папке db/migrations

4 Работа c мультиязычностью

Для настройки русского интерфейса надо использовать файл config/application.rb:

Код application.rb

require_relative 'boot'

 

require 'rails/all'

 

# Require the gems listed in Gemfile, including any gems

# you've limited to :test, :development, or :production.

Bundler.require(*Rails.groups)

 

module ECommerce

  class Application < Rails::Application

   

    config.to_prepare do

      # Load application's model / class decorators

      Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c|

        Rails.configuration.cache_classes ? require(c) : load(c)

      end

 

      # Load application's view overrides

      Dir.glob(File.join(File.dirname(__FILE__), "../app/overrides/*.rb")) do |c|

        Rails.configuration.cache_classes ? require(c) : load(c)

      end

    end

 

    # Initialize configuration defaults for originally generated Rails version.

    config.load_defaults 5.1

    config.i18n.default_locale = :ru

 

    # Settings in config/environments/* take precedence over those specified here.

    # Application configuration should go into files in config/initializers

    # -- all .rb files in that directory are automatically loaded.

  end

end

 

 

Для создания мультиязычных фраз используем встроенную в rails библиотеку i18n и файлы с переводом размещаем в config/locales/ru.yml. Все фразы указываются в натации yml
ru:

  hello: 'Привет'

         Для вставки такой фразии надо в папке view прописать в файле: Spree.t('hello') (функция t означает в RoR translite).

5 Создание ссылок

Для работы с ссылками в rails используется хелпер link в который мы передаём название роута (rails создаёт их автоматический при генерации ресурсов). Пример:
<%= link_to Spree.t(:products), spree.admin_products_url %>  # Создаст ссылку на роут admin/product_url

6 Использование partials в шаблонах html

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

<%= render partial: 'spree/admin/shared/error_messages', locals: { target: @product } %>

Будет использовать код для отображения ошибок

Код 'spree/admin/shared/error_messages'

<% if target && target.errors.any? %>

  <div id="errorExplanation" class="errorExplanation alert alert-danger" data-hook>

    <p>

      <strong><%= Spree.t(:errors_prohibited_this_record_from_being_saved, count: target.errors.size) %>:</strong><br/>

    </p>

    <ul class="ul-with-markup">

     <% target.errors.full_messages.each do |msg| %>

       <li><%= msg %></li>

     <% end %>

    </ul>

  </div>

<% end %>

 

Демонстрация работы

Добавили товар, с именем ESS Палетка теней для век:

Рисунок 6.1.1 – Добавление товара

В базе добавился данный товар с id=25.

Рисунок 6.1.2 – База данных

При нажатии кнопки «Удалить» данный товар удаляется с базы данных и со страницы сайта.

При нажатии кнопки «Редактировать» отображается следующее окно:

Рисунок 6.1.3 – Редактирование товара

Количество комментариев: 0

Для того, чтобы оставить коментарий необходимо зарегистрироваться