iT邦幫忙

2023 iThome 鐵人賽

DAY 8
0
自我挑戰組

入坑 RoR 必讀 - Ruby 物件導向設計實踐系列 第 8

Day8 CH4 建立靈活的介面(上)

  • 分享至 

  • xImage
  •  

來到了第四章(快過半了,加油!),今天我們要進入到介面的世界,介面到底扮演什麼樣的角色?物件之間又是如何藉由介面去溝通呢?根據前三章所學,我們可以先歸納出三個要點:

  1. 物件導向程式設計 (OOP) 是一種程式設計規範,它將程式中的元素組織成物件,這些物件具有狀態行為,並且能夠與其他物件互動。
  2. 類別是物件導向程式設計的基本概念,用來定義物件的藍圖或模板,包含了物件的屬性方法
    設計討論經常圍繞著類別的職責和依賴關係展開,這有助於確定每個類別的功能和作用。
  3. 物件之間傳遞的訊息,包括物件的職責(它們知道如何做什麼)以及它們的依賴關係(它們是否依賴於其他物件)。
    物件間的溝通可以透過介面來實現,介面定義了物件之間的通信協議,使應用程式更具彈性,可以應對變化和擴展。

物件導向程式設計不僅僅是關於類別的定義,它更關注物件之間的互動和訊息傳遞,並通過介面實現彈性設計,使應用程式能夠不斷增長和適應變化。

理解介面

假設有兩支正在執行的應用程式,應用程式包含了許多物件,訊息在這些物件之間傳遞。
https://ithelp.ithome.com.tw/upload/images/20230908/20145409GEhjReRMM9.jpg
(圖片拍攝自書籍:Practical Object-Oriented Design in Ruby: An Agile Primer)

  • 第一種應用程式中,消息傳遞沒有明顯的模式,每個物件都可以向任何其他對象發送消息。這導致了對象之間的高度耦合,難以重複使用和修改。
  • 第二種應用程式中,消息傳遞有明確的模式,物件之間以特定和適當定義的方式進行溝通。這些物件盡量減少暴露自己,降低對其他物件的了解。

在第一支應用程式裡,每一個類別都暴露了所有的內容。任何類別裡的任何方法都可以隨意被其他任 何物件使用;在第二支應用程式裡,訊息模式明顯,每一個物件都有一套明確定義的方法,並期望其他物件去使用它們。 這些暴露出的方法構成了類別的公共介面。

「介面」一詞可以指代許多不同的概念。在此處指的是類別裡的介面(方法)。類別實作了方法,有些方法旨在被其他物件使用,而這些方法便組成了它的公共介面。

定義介面

假設有一間餐廳廚房。顧客根據菜單來點餐。這間廚房做了許多事情,但是它沒有將這些內容都暴露給顧客(謝天謝地)。它擁有 一個公共介面提供給顧客使用,也就是菜單。在廚房裡,可能發生了很多事情,有許多其他的訊息在傳遞。但是,這些訊息是私有的,因此顧客看不到它們。

文字說明可能過於抽象,實作一個簡單的範例:

class Restaurant
  def initialize
    @menu = {
      "burger" => 10,
      "pizza" => 12,
      "spaghetti" => 15
    }
  end

  def display_menu
    puts "Menu:"
    @menu.each do |item, price|
      puts "#{item}: $#{price}"
    end
  end

  def place_order(item)
    if @menu.key?(item)
      puts "Order for #{item} received."
      prepare_order(item)
    else
      puts "Sorry, we don't have #{item} on the menu."
    end
  end

  private

  def prepare_order(item)
    puts "Preparing #{item}..."
    # 廚房內部處理訂單的邏輯
    puts "#{item} is ready. Enjoy your meal!"
  end
end

# 顧客點餐
restaurant = Restaurant.new
restaurant.display_menu
restaurant.place_order("burger")
restaurant.place_order("sushi") # 菜單上沒有壽司

歸納兩種介面

公共介面(Public method)
類別所呈現與傳達給外界的方法。

  • 顯露出其主要職責
  • 期望被其他物件呼叫
  • 不會因一時興起而改變
  • 其他物件可以放心依賴它
  • 在測試裡被詳盡記錄

私有介面(Private method)
類別裡獨自運作而不需要被知道的方法。

  • 要處理實作細節
  • 不希望被傳送到其他物件
  • 可以因任何原因而變化
  • 其他物件不能放心依賴它
  • 甚至可能不會在測試裡被引用

職責、依賴關係和介面

第二章關注建立具有單一職責的類別,即每個類別應該有一個單一的目的,並且其公共方法應該反映這個目的。每個類別的具體職責與其公共方法之間應該存在對應關係。公共方法構成了類別的公共接口,它們描述了類別的職責。

第三章關注依賴關係管理,強調類別應該只依賴於比自己更穩定的類別。類別被劃分為公共和私有部分,其中公共部分是穩定的,私有部分是可變的。當類別使用其他類別的公共方法時,它表明它信任這些方法是穩定的。然而,當它依賴其他類別的私有方法時,它應該意識到這種依賴會增加風險,因為私有方法可能不夠穩定,受到不相關的變化的影響。這強調了依賴關係的管理對於系統的穩定性和可維護性至關重要。

通常情況下,我們不應該依賴於其他類的私有方法,因為這會破壞封裝性和隔離性。如果一個類的私有方法需要被其他類使用,考慮將這些方法改為受保護或公共方法,或者通過其他方式提供對其功能的使用。

今天先初步理解介面,明天我們繼續了解介面的使用與迪米特法則,晚安~

參考資料:

  • Practical Object-Oriented Design in Ruby: An Agile Primer

上一篇
Day7 CH3 管理依賴關係(下)
下一篇
Day9 CH4 建立靈活的介面(下)
系列文
入坑 RoR 必讀 - Ruby 物件導向設計實踐30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言