Stop Using Case Statements in Ruby
Bài đăng này đã không được cập nhật trong 7 năm
Đã bao giờ bạn nghĩ mình đã sử dụng hết sức mạnh của OOP hay là bạn đã bỏ lỡ một số tính năng nào đó?
Nếu bạn đang viết code và đưa ra các quyết định dựa trên từng loại đối tượng cụ thể thì bạn đang bỏ lỡ một tính năng quan trọng của OOP: polymorphism
Checking For Types
Đầu tiên tôi sẽ bắt đầu bằng một ví dụ mà chúng ta không tận dụng tính đa hình.
Giả sử chúng ta đang implement “Rock, Paper, Scissors” game. Tôi quyết định có 1 class Game
và các class khác cho các loại Rock, Paper, Scissors có trong game.
Kiểm tra xem ai là người thắng bằng việc implement method play
trong class Game
.
class Game
def self.play(move1, move2)
return :tie if move1 == move2
move1.wins_against?(move2)
end
end
Và đây là một trong những hành động, các class Paper, Scissors khác implement tương tự.
class Rock
def wins_against?(other_move)
case other_move
when Paper then false
when Scissors then true
end
end
end
Bây giờ chúng ta chơi game như sau.
p Game.play(Rock.new, Paper.new)
# false
Các implement trên vẫn làm việc được, nhưng chúng ta có thể làm cho nó tốt hơn không?
Polymorphism Instead of Type Checking
Chúng ta có thể sử dụng các nguyên tắc của OOP để thay thế cho các câu lệnh case trong 3 class Rock Paper Scissors
.
In Ruby, polymorphism is the ability to send any method calls (also know as messages, in OOP parlance) to any object without having to check the object’s class. This is also known as “duck typing”, but I don’t like that term
Chúng ta sẽ sử dụng method đặc trưng cho lớp cụ thể. Ví dụ class Rock
có thể định nghĩa method do_you_beat_rock?
class Rock
def wins_against?(other_move)
other_move.do_you_beat_rock?
end
def do_you_beat_paper?
false
end
def do_you_beat_scissors?
true
end
end
class Paper
def wins_against?(other_move)
other_move.do_you_beat_paper?
end
def do_you_beat_rock?
true
end
def do_you_beat_scissors?
false
end
end
class Scissors
def wins_against?(other_move)
other_move.do_you_scissors_rock?
end
def do_you_beat_paper?
true
end
def do_you_beat_rock?
false
end
end
Các câu lệnh case statement đã được thay thế bằng 1 method gọi và 2 method định nghĩa.
Conclusion
Trong bài viết này bạn đã học được việc tránh sử dụng case statements cho việc kiểm tra loại class. Thay vào đó là tận dụng lợi ích của tính đa hình trong OOP. Điều này sẽ giúp bạn viết code tốt hơn, có thể được mở rộng bằng cách thêm mã mới thay vì thay đổi mã hiện có. Nhưng không có nghĩa là tôi đang ủng hộ để loại bỏ hoàn toàn case statements, bạn nên coi đây là chú ý trong khi viết code, đảm bảo đó là giải pháp tốt nhất để giải quyết vấn đề.
Bài viết được dịch từ:
https://www.blackbytes.info/2017/04/stop-using-case-statements-in-ruby/
All rights reserved