背景

☝️ 读了它,我受到了启发。

受启发的内容也总结在☝️。
本文只是对上述内容的通读。

介绍

有各种设​​计理论和标准可以做出更好的产品。
我想知道最好不要被拖累就好了,
对于当前产品团队决定什么是最好的我认为这是可取的。
(图书销售)

在本文中

  • 冷凝
  • 联轴器

我想从以下角度考虑功能重构

为什么要重构

由于每次重构规模小,出错的可能性较小,每次重构后系统都保持完整的工作状态,减少了系统在重构过程中严重崩溃的机会。
重构降低了增强的成本

日常小维护对于产品的发展至关重要。

内聚和耦合

凝聚力和凝聚力的概念是康斯坦丁和约顿在他们的合著者《结构化设计》中提出的功能度量。
对于结构化语言和面向对象语言,与维护工作相关的质量下降风险是相同的。

缩合

从 1 开始,它被认为是一个危险的聚合。

  1. 意外聚合
  2. 逻辑内聚
  3. 临时聚合
  4. 程序聚合
  5. 交际聚合
  6. 顺序聚合
  7. 功能聚合

    意外聚合

    包含无关处理

    def calc_price(item, price)
      result_price = price * 0.1
      item.price = result_price
      price * 0.1
    end
    

    计算价格和给 item.price 赋值是混合在一起的。

    逻辑衔接

    按参数选择内部处理

    def start_deal(item, user_type)
      if user_type == 'business_user'
        item.notify_deal_by_mail
        item.update(status: 'checking_deal')
      else
        item.update(status: 'dealing')
      end
    end
    

    仅执行选定的函数,而不是在一次调用中排序。
    执行端需要了解内部结构并传递标志。

    临时聚合

    包含仅在一个时间点运行的操作

    def start_deal(item, user)
      if user.first_deal
        PointBack.create(user_id: user.id, point: 1000)
        user.graduate_new_commer
      end
    
      item.update(status: 'dealing')
    end
    

    包含仅执行一次的处理时,功能的可重用性会降低

    程序聚合

    按执行顺序有意义的处理

    def create_item(params)
      item = ItemBuilder.new(params).build
      return nil unless item.valid?
    
      record = ItemRepository.store(item)  
      record
    end
    

    函数的复用性差,因为处理顺序有意义

    沟通凝聚力

    用于处理某些数据的函数集合

    def update_item(item)
      update_a_process(item)
      update_b_process(item)
      update_c_process(item)
    end
    

    顺序聚合

    高度相关的特征一起处理

    def greeting(user)
      user.say_hello
      user.shake_hands
    end
    

    功能聚合

    单一功能

    def twice(num)
      2 * num
    end
    

    凝聚力总结

    撰写 web db press 文章的 Sonatard 将凝聚力的程度总结如下:

    凝縮度・結合度という尺度から関数のリファクタリングを行う

    应避免意外聚集。
    逻辑内聚和时间内聚不能一概而论,但应该避免。
    功能内聚是理想的。

    时间聚合重构

    原样

    # 時間的凝集は具体的な処理を書くのではなく、極力機能的凝集の関数を実行することに徹するべき
    module Tenant
      module V2
        module CreateDisplayUnit
          class ModelBuilder
            def initialize(params, business_user)
              @params = params
              @business_user = business_user
            end
    
            def build
              # ディスプレイのインスタンスを生成
              display_unit = DisplayUnit.new(name: @params[:display_unit_name],
                                             vendor_code: @params[:display_unit_vendor_code])
              display_unit.do_something
    
              # ディスプレイ商品のインスタンスを生成
              display_unit_item = DisplayItem.new(
                  user_id: @business_user.user_id,
                  origin_price: @params[:sell_price],
                  size_id: Tenant::Item::DEFAULT_SIZE_ID,
                  delivery_method: Fril::DeliveryMethod::DEFAULT_ID,
                  open_flag: @params[:open_flag])
              display_unit_item.do_something
              [display_unit, display_unit_item]
            end
          end
        end
      end
    end
    

    成为

    module Tenant
      module V2
        module CreateDisplayUnit
          class ModelBuilder
            def initialize(params, business_user)
              @params = params
              @business_user = business_user
            end
    
            def build
              # インスタンス生成のタイミングに処理がまとまっている
              # 順序に意味はない 
              display_unit = build_display_unit
              display_unit_item =build_display_unit_item
              [display_unit, display_unit_item]
            end
    
          private
         
            def build_display_unit
              display_unit = DisplayUnit.new(name: @params[:display_unit_name], vendor_code: @params[:display_unit_vendor_code])
              display_unit.do_something
              display_unit
            end
    
            def build_display_unit_item
              display_unit_item = DisplayItem.new(
                  user_id: @business_user.user_id,
                  origin_price: @params[:sell_price],
                  size_id: Tenant::Item::DEFAULT_SIZE_ID,
                  delivery_method: Fril::DeliveryMethod::DEFAULT_ID,
                  open_flag: @params[:open_flag])
              display_unit_item.do_something
              display_unit_item
            end
          end
        end
      end
    end
    

    逻辑内聚重构

    原样

    def build_item(params, is_display_item)
      item = Item.new(params)
      item.do_something_a
      item.do_something_b
      item.do_something_c if is_display_item
      item
    end
    
    display_item = build_item(params, true)
    stock_keeping_unit_item = build_item(params, false)
    

    成为

    
    def build_display_item(params)
      item = Item.new(params)
      item.do_something_a
      item.do_something_b
      item.do_something_c if is_display_item # ディスプレイ商品は必ず「サイズなし」になるようにする
      item
    end
    
    def build_stock_keeping_unit_item(params)
      item = Item.new(params)
      item.do_something_a
      item.do_something_b
      item
    end
    
    # 呼び出し元が内部実装を知らなくても良い
    display_item = build_display_item(params)
    stock_keeping_unit_item = build_stock_keeping_unit_item(params)
    

    关于逻辑内聚,也是违背 DRY 原则的,要分情况,
    在像这次这样的情况下,顺序有一些意义,索纳塔先生说,凭经验

    • 很少出现故障
    • 即使订单发生变化也可以检测到不工作
    • 阐明在发生类似用例时需要进行哪些内部处理

    因此,建议将功能分开

    此内容也出现在 Clean Architecture 中,

    与其反身消除重复,不如确定重复是否真实

    看起来
    但是复制重复的功能也很难管理,所以根据情况进行适当的判断似乎也不错。

    耦合度

    从 1 开始,它被认为是一个危险的聚合。

    1. 内连接
    2. 普通键
    3. 外连接
    4. 控制耦合
    5. 邮票联合
    6. 数据绑定

      我认为很容易想象这种组合,所以解释会很简短。

      内部联接

      绑定到另一个函数,其值未在外部声明

      共同债券

      由一个共同的全局变量组合

      外连接

      加入公共变量

      控制耦合

      调用者知道与函数内部处理相关的标志,并通过指定它们来绑定它们。 (逻辑衔接)

      邮票装订

      通过传递结构和类进行耦合

      数据绑定

      通过标量类型传递组合

      消息组合

      与函数执行耦合。没有值传递

      耦合总结

      撰写 web db press 文章的 Sonatard 将凝聚力的程度总结如下:

      凝縮度・結合度という尺度から関数のリファクタリングを行う

      从聚合中看到错误的 DRY

      (Web db press 已经热情地写过这个,所以如果你有兴趣,我建议你购买它。)

      通过使其干燥,代码将暂时更清洁,
      每次更改功能时都会进行不必要的修改的 DRY 可能无法很好地执行时间凝聚力或逻辑凝聚力。

      凝縮度・結合度という尺度から関数のリファクタリングを行う

      (逻辑聚合完成。)

      取出一个大盘子而不打破上面的小盘子似乎更安全。
      我个人认为是这样的。

      在最后

      在开发过程中规格可能会发生变化,功能可能会有所扩展。
      我认为该软件将随着时间的推移从初始状态过时。

      我希望通过以目前最好的产品为目标,并通过继续进行微小的改进为功能扩展做准备,为服务的发展做出贡献。


原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308627770.html

相关文章:

  • 2022-12-23
  • 2021-05-14
  • 2021-08-26
  • 2021-11-19
  • 2021-05-15
  • 2022-01-11
猜你喜欢
  • 2022-12-23
  • 2021-12-15
  • 2022-01-15
  • 2021-11-15
  • 2021-06-02
  • 2021-06-03
  • 2021-09-25
相关资源
相似解决方案