Ruby

Code tởm #2 - Biết quá nhiều ...

Cũng là một cái tội ...

Khi bạn biết quá nhiều

  you.pocket.have_any_money?
  # Dịch:
  #   Mr. X: bạn có bao nhiêu tiền?
  #   You: Ummm.. hỏi ví tôi ý
  #   Mr. X: Ê ví! Mày còn bao nhiều trong người?
  #   Ví: cuối tháng rồi anh ơi, hỏi chi hỏi lắm rứa T_T

  you.phone.battery.batery_low?
  # Dịch:
  #   Mr X: điện thoại bạn còn pin ko?
  #   You: Ờm.. check hộ tôi phát
  #   Mr X: Ê điện thoại! sắp hết pin chưa?
  #   Điện thoại: #%%^%#^@* (tạm hiểu là cạn pin)

  you.girl_friend.get_the_remote
  # Dịch:
  #   Mr. X: lấy hộ tôi cái điều khiển phát
  #   You: Anh nhờ bạn gái tôi đi
  #   Mr. X: em ơi lấy anh cái điều khiển với
  #   NoMethodError: undefined method 'get_the_remote' for Girlfriend class
  #   Mr. X: ... đậu, có đếch.

Cuộc đời nó sẽ tươi đẹp hơn nếu code nó chỉ như thế này:

  you.have_any_money?            # False
  # Dịch:
  # Mr. X: còn tiền ko?
  # You: nát rồi
  
  you.phone_available?           # False
  # Dịch:
  # Mr. X: điện thoại còn pin ko?
  # You: cạn

  you.tell_girlfriend_get_remote # "It's not fun bro"
  # Dịch:
  # Mr. X: bảo ... à mà thôi

Muốn vậy thì phải làm sao???

Delegation

Nôm na là đùn đẩy trách nhiệm, thay vì Mr. X tự đi check điện ví, check điện thoại, check gấu của bạn thì tốt nhất là bạn nên tự làm điều đó.

  class You
    ...
    def have_money?
      pocket.have_any_money?
    end
    
    def phone_available?
      return false if phone.batery_low? == "#%%^%#^@*"
      true
    end
    
    def tell_girlfriend_get_remote
      return "It's not fun bro!" unless girl_friend
      girl_friend.get_the_remote
    end
  end

Cái giá phải trả? thêm 1 method cho mỗi phát delegation, khá chát! Tuy nhiên, rails luôn sẵn có mấy thứ hay ho, cụ thể là cái hàm #delegate sau đây

  class You
    ...
    delegate :have_any_money?, to: :pocket
    delegate :batery_low?, to: :phone
    delegate :get_the_remote, to: :girl_friend

như vậy, ta chỉ tốn 1 dòng như trên cho mỗi delegation. Và như thế này thì nó tuyệt vời như thức ăn ngon mà đắt rẻ vậy!

Law of Demeter

Theo Wikipedia:

The Law of Demeter (LoD) or principle of least knowledge is a design guideline for developing software, particularly object-oriented programs. In its general form, the LoD is a specific case of loose coupling. The
guideline was proposed by Ian Holland at Northeastern University towards the end of 1987, and can be succinctly summarized in each of the following ways:

  1. Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
  2. Each unit should only talk to its friends; don't talk to strangers.
  3. Only talk to your immediate friends.

Hay hiểu một cách đơn giản là: "CHỈ NÊN DÙNG MỘT DẤU CHẤM" (LOL)

Nhưng như vậy thì có cái lợi gì? Mệt mỏi như vậy chỉ để cho code nó dễ nhìn?

Nope! Nó thực sự làm code trở nên dễ thay đổi hơn, khi bạn thay đổi chiếc ví của mình, chẳng hạn như #brand_new_pocket,

thì Mr X cũng không cần phải biết điều đó để hỏi bạn còn tiền không.

(chỉ đơn giản là you.have_any_money? chứ không còn phải you.brand_new_pocket.have_any_money?)

Kết lại

Một object chỉ nên biết hạn chế (lí tưởng là mù tịt) về cấu tạo của object khác. Khi biết quá nhiều, chúng sẽ bị dính chặt vào nhau ...

Phần kế tiếp: middle man - hậu quả của việc lạm dụng law of demeter (hoặc do code thối bẩm sinh)- cái gì nhiều quá cũng không tốt ==!)

Bonus: Primitive Obsession

Nghĩa là truyền thẳng primitive vào trong argument của hàm.

  making_purchase(account.id, cart.id, coupon.type)   #  bad smell
  making_purchase(account, cart, coupon)              #  good!

Tại sao?

  1. Bạn đang biết quá nhiều về cách hoạt động của #making_purchase
  2. Truyền object là pass-by-reference (nói kiểu các cụ là chỉ truyền pointer), còn primitive là truyền giá trị (tức copy rồi paste), như vậy thì "truyền cả object" thực chất là nhẹ nhàng hơn "truyền từng thuộc tính của object" rất nhiều!

(*) Điều 2 thì lại không đúng với Ruby, vì cơ bản, trong này thì cái vẹo gì cũng là object cả :v. Không phải ư, vậy giả sử 1 + 1 thực chất là 1.send(:+, 1) thì sao?

Registration Login
Sign in with social account
or
Lost your Password?
Registration Login
Sign in with social account
or
A password will be send on your post
Registration Login
Registration