Cách dùng một class để refer config var
Bài đăng này đã không được cập nhật trong 7 năm
Như chúng ta đều biết thì ở hầu hết các app có một class để refer đến những thuộc tính được setup sẵn, ví dụ: thông tin về Database, Email, Environment, ... Thông thường tất cả những thông tin đó được store vào một file yaml và được class này đọc, nhưng trong bài viết này mình sẽ hard code luôn cho dễ hiểu.
Đầu tiên mình viết một class:
module MusicGuu
class Configuration
def hot_trends
@top ||= {
top_hit: "See you again"
}
end
def top_music(key)
hot_trends[key]
end
end
end
Dễ thấy ở trên là một Plain Old class ruby rất đơn giản, có 2 functions
- #hot_trends - là 1 hash dùng để store các config var
- #top_music - function truy xuất config var theo key name, nếu trùng thì return value , ngược lại return nil
Cách truy xuất rất đơn giản:
MusicGuu::Configuration.new.top_music(:top_hit)
# => "See you again"
Đến đây chúng ta đã thỏa mãn yêu cầu truy xuất và có thể dừng lại tại đây. Tuy nhiên chúng ta vẫn có thể improve đoạn code trên. Vì việc tạo một object cho mỗi lần truy xuất rất ảnh hưởng tới tài nguyên mà các object config được tạo ra không cần thiết. Có thể kiểm chứng điều đó như sau:
MusicGuu::Configuration.new.top_music(:top_hit).object_id
# => 80144345091440
MusicGuu::Configuration.new.top_music(:top_hit).object_id
# => 80145304142669
Dễ thấy id của 2 instance khác nhau, => instance mới đã được tạo.
Do đó chúng ta refactor một chút đoạn code trên để chỉ tạo ta 1 object khi truy xuất thôi:
module MusicGuu
class Configuration
def self.instance
@instance ||= self.new
end
# code cũ ở đây
Và thông qua instance:
MusicGuu::Configuration.instance.top_music(:top_hit)
# => "See you again"
Giờ check lại các instance được tạo ra nhé:
MusicGuu::Configuration.instance.top_music(:top_hit).object_id
# => 81132336967820
MusicGuu::Configuration.instance.top_music(:top_hit).object_id
# => 81132336967820
Dễ thấy id trùng khớp nên chỉ có 1 instance được tạo.
Ngoài ra, chúng ta có thể sử dụng mixin Singleton để refactor như sau:
require 'singleton'
module MusicGuu
class Configuration
include Singleton
def hot_trends
@top ||= {
top_hit: "See you again"
}
end
def top_music(key)
hot_trends[key]
end
end
end
Done, nó cung cấp interface API và thực hiện chức năng tương tự hàm .instance khi nãy.
Mình hy vọng với tip nhỏ này có thể giúp mọi người viết code Ruby sáng hơn. Mình cũng sẽ cố gắng tìm hiểu các tips khác về Ruby để chia sẻ với mọi người. Ai đi qua cho mình một + nhé.
All rights reserved