冒险村20 - Design Pattern(1) - Decorator

20 - Design Pattern(1) - Decorator

Decorator pattern 的原理是,增加一个修饰类包裹原来的 class,包裹的方式是在修饰类的构造函数中将原来的类以参数的形式传入。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。修饰类必须和原来的类有相同的接口。

直接来看如何使用:

Create app/decorators folder

并在 folder 下可以先建立以下两个档案,稍後会来修改内容

  • base_decorator.rb
  • user_decorator.rb

Add decorate to ApplicationHelper

新增一个共用的方法取名为 decorate,可以方便之後在 controller 直接 helpers.decorate
来将重复的 code 整理起来,当然也会有不符合规则的时候,所以允许带入 args。

  # frozen_string_literal: true
  module ApplicationHelper
    def decorate(model, decorate_class = nil)
      (decorate_class || "#{model.class}Decorator".constantize).new(model)
    end
  end

Add app > decorators > base_decorator.rb

这边将为 decorator 的父层。主要重点是继承在 SimpleDelegator 下,这个看文件其实满好理解的。

  # frozen_string_literal: true
  class BaseDecorator < SimpleDelegator
    def decorate(model, decorate_class = nil)
      ApplicationController.helpers.decorate(model, decorate_class)
    end
  end

Add app > decorators > user_decorator.rb

可以将 view 的逻辑丢到 decorator 内,简单以 User 常有的 first_name, last_name 来说,在 DB 内存成两个栏位,不过画面上通常都会是想要直接显示两个栏位加起来作为使用者的名称,这时候只要在 view 直接 @xxx.full_name 即可。

  # frozen_string_literal: true
  class UserDecorator < BaseDecorator
    def full_name
      "#{first_name} #{last_name}"
    end
  end

Init instance variable

  # frozen_string_literal: true
  class UsersController < ApplicationController
    def show
      @user_decorator = helpers.decorate(current_user)
    end

    private

    def current_user
      User.find(params[:id])
    end
  end

View

  # show.html.erb
  <%= @user_decorator.full_name %>
  <%= @user_decorator.email %>

参考资料

My blog


<<:  TailwindCSS 从零开始 - 价目表卡片实战 - 首页标题样式

>>:  DAY 23 Big Data 5Vs – Variety(速度) Kinesis (3)

OpenStack 介绍 2

本系列文章同步发布於笔者网站 前一篇文章以比较非技术角度介绍了 OpenStack 这个专案。今天开...

Day24 - 如何盘中计算技术指标且发送讯号到line: 不同频率分K计算

之前我们学会了如何用talib计算一分K技术指标,也学会了如何用line发送通知。因为shioaji...

Android Studio初学笔记-Day5-TextView

基本元件介绍-TextView 接下来会开始介绍android studio一些基本的元件,这些元件...

Ruby--Find the Difference

Find the Difference 题目连结:https://leetcode.com/pro...

【LeetCode】Binary Search Tree

突然发现前面应该要多写一点的@@ 我本来没打算花那麽多篇幅讲 Leetcode... 铁人赛有几篇写...