惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

A
About on SuperTechFans
G
Google Developers Blog
L
LangChain Blog
aimingoo的专栏
aimingoo的专栏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
云风的 BLOG
云风的 BLOG
小众软件
小众软件
月光博客
月光博客
Recent Announcements
Recent Announcements
人人都是产品经理
人人都是产品经理
P
Proofpoint News Feed
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
The Cloudflare Blog
博客园_首页
美团技术团队
大猫的无限游戏
大猫的无限游戏
B
Blog
IT之家
IT之家
Jina AI
Jina AI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
Check Point Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

Nic Lin's Blog

謝明真 - 高效領導力的課後筆記 NFT 開發實戰!基礎智能合約入門 (3) NFT 開發實戰!基礎智能合約入門 (2) NFT 開發實戰!基礎智能合約入門 (1) 如何自我檢測 log4j CVE 漏洞 Rails 如何在資料寫入時記錄來源 IP 位置 如何經營工程師 Youtube 頻道 - Part 8 營收篇 如何經營工程師 Youtube 頻道 - Part 7 酸民文化篇 如何經營工程師 Youtube 頻道 - Part 5 設備器材篇 如何經營工程師 Youtube 頻道 - Part 4 後製剪輯篇 如何經營工程師 Youtube 頻道 - Part 3 文案企劃篇 如何經營工程師 Youtube 頻道 - Part 2 設備器材篇 如何經營工程師 Youtube 頻道 - Part 1 制訂頻道方向篇 如何經營工程師 Youtube 頻道 - Part 0 Rails 中避免 race condition 的最佳實踐(二) Rails 中避免 race condition 的最佳實踐(一) 10 分鐘整合 google sheet 做自動化開發功能週報 經營 Side Project 300 天所帶來的收穫及挑戰 我的 Youtube 影片製作流程 API 設計時必須注意的 HTTP header 底線問題 如何提升你的程式可讀性之實務技巧(三) 如何提升你的程式可讀性之實務技巧(二) 如何提升你的程式可讀性之實務技巧(一) Ruby 中使用 freeze 優化效能的時機 避免 React 中的 useEffect 無限 render 在 Rails 內輕量使用 Vue Component 的最佳實踐 如何在區域網路用 Docker 架設有 SSL 的 Gitlab 從被問到問人,那些我常問的面試問題 [Rails] 如何漂亮寫出可維護的 query (Maintainable Rails Query) 在已知長度情況下優化 slice 的性能
Class method 氾濫帶來什麼問題
Nic Lin · 2019-03-31 · via Nic Lin's Blog

因為 Class method 是 global method 所以可以到處被使用

就像 User.all 這樣的方法可以在 model, controller, view 都被使用

Class method 有什麼問題?

代表你可以隨處使用而不必在乎前後因果

class User
  def self.email_to(id, email)
    user = User.find(id)
    Emailer.send(email, "Hello, #{user.name}")
  end

下面這是更好一點的版本,因為寄信這件事情應該可以直接針對該 user,也就不用在去 find 了

class User
  def email_to(email)
    Emailer.send(email, "Hello, #{name}")
  end

這樣一來你在別處執行的 code 可能就會變成

user = User.find(params[:id])

user.email_to(email)

而不是 class method

User.email_to(params[:id], email)

因為 class method 不是在一個 object instance 上面操作,是 global 都能使用,這其實不太符合 OOP 精神,尤其 ruby 又是這麼 OOP 的一個語言(萬物皆為 object)。

Class method 的寫法比較像是程序式程式語言(Procedural programming) 然而 instance method 在 object 創建本身就需要帶完整和正確的參數,在 debug 上有一定的優勢。

我個人比較偏好寫 instance method,因為 object instance 再做完他的工作就死了,不會有污染的問題…

所謂污染就是把 object 能做的事情丟給 global 做就會變成這樣

# 應該要用 class 的 new 去做,但自己寫了 initialize?

module Hello
  def self.initialize(first_name, last_name)
    @@first_name = first_name
    @@last_name = last_name
  end

  def self.fullname
    "#{@@first_name} #{@@last_name}"
  end
end

# 假設有一個 class 要使用 Hello module
class Cool
  def boy
    # 這時候強制設定了 class 層級的 local variable
    Hello.initialize("Nic", "Lin")

    puts Hello.fullname
  end

  def girl
    # 然後又把 local variable 覆蓋了...
    Hello.initialize("Doris", "Lin")

    puts Hello.fullname
  end
end

# 執行
example_1 = Cool.new

example_1.boy
# Nic Lin

example_1.girl
# Doris Lin

執行起來沒問題,但是在這個層級裡面,你的 Hello module 其實偷偷覆寫了 local variable,這是一個非常危險的事情。

我知道這 example 看起來很蠢,但確實存在。

小結

如果不是可以全域使用的方法,我認為還是用 instance method 好一些,尤其很多 service 的邏輯封裝,更不適合這樣污染。

並不是說 class method 不好,只是覺得如果要運用不該是到處氾濫,畢竟我們很常用一些好用的 class method 例如 User.find, User.all

參考資料