Đang tìm một số gem mới & thú vị để thử?
Thì hãy nhìn vào dry-rb, một tập hợp gem mang lại giải pháp cho các vấn đề phổ biến. Dry-rb bao gồm hơn 18 Ruby gem có thể làm việc cùng nhau hoặc riêng biệt.
Một số gem trong đó bao gồm:
- dry-initializer
- dry-struct
- dry-validations
- dry-events
- dry-transaction
Trong bài này, bạn sẽ học về 3 gem trong số đó để nếm trải dry-rb cung cấp gì!
Tạo Struct tốt hơn với dry-struct
Ruby Struct là một loại object bạn có thể tạo từ class Struct, nhưng chúng có một số hạn chế.
Ví dụ:
Bạn có thể tạo struct với số lượng đối số thiếu và không nhận được phàn nàn từ Ruby.
Với gem dry-struct, bạn có thể tạo struct chặt chẽ hơn.
Cách làm:
require 'dry-struct' module Types include Dry::Types.module end class Video < Dry::Struct attribute :title, Types::String attribute :views, Types::Views attribute :comments, Types::Array end Video.new(title: "abc", views: 10, comments: [])
Bây giờ nếu bạn thiếu một trong các attribute, bạn nhận được lỗi này:
[Video.new] :comments is missing in Hash input
Thông báo lỗi không quá thân thiện, nhưng nó hoàn thành nhiệm vụ.
Bạn có thể tự tạo type riêng & thêm ràng buộc:
module Types include Dry::Types.module Age = Integer.constrained(gt: 0) end
"gt" này nghĩa là "greater than" (lớn hơn).
Vì vậy Age phải là integer lớn hơn 0.
Có thể có giá trị mặc định không?
Có, đây là cách:
module Types
include Dry::Types.module
Name = String.default('')
end
Có phiên bản ngắn hơn để tạo Dry structs, giống như Ruby structs thông thường.
Ví dụ:
Book = Dry::Struct(title: Dry::Types["string"]) Book.new(title: "Computer Science 101")
Triển khai Observer Pattern với dry-events
Observer design pattern là khi một nguồn công bố cập nhật cho nhiều listener, đây có thể là cập nhật tin tức, cảnh báo cổ phiếu, tin nhắn mới trong group chat, v.v.
Đây là pattern phổ biến.
Ruby bao gồm module observable giúp bạn triển khai điều này.
Nhưng dry-events là lựa chọn khác.
Bạn có thể tạo publisher như sau:
require 'dry/events/publisher'
class Blog
include Dry::Events::Publisher[:blog]
register_event('article.published')
register_event('article.upated')
end
Bây giờ:
Bất kỳ class nào cũng có thể đăng ký để nhận sự kiện khi chúng xảy ra.
Cách làm:
class Reader
def on_article_published(event)
puts "New article published: #{event[:title]}"
end
def on_article_updated(event)
puts "Article has been updated: #{event[:title]}"
end
end
blog = Blog.new
reader = Reader.new
blog.subscribe(reader)
Bạn có thể phát sự kiện với phương thức publish:
blog.publish('article.published', title: 'How to Use The dry-events Gem')
Một điều tôi nhận thấy với gem này là nếu bạn subscribe hoặc publish sự kiện không tồn tại, sẽ fail silently (thất bại im lặng).
Dependency Injection với dry-auto_inject
Dependency (phụ thuộc) là gì?
Dependency là thứ một class cần để hoạt động, như các object & class khác.
Bạn có thể tạo các object này trực tiếp trong class của bạn…
Hoặc bạn có thể dùng dependency injection (tiêm phụ thuộc).
Dependency injection là khi các dependency được "tiêm" vào class. Nói cách khác, chúng được truyền vào như tham số.
Ví dụ:
require 'faraday'
class GitHubAPI
def initialize(http_client = Faraday.new)
@http_client = http_client
end
end
Làm điều này cho phép bạn kiểm soát dependency & làm test dễ dàng hơn.
Bây giờ:
dry-auto_inject tạo các object này cho bạn. Tất cả những gì bạn phải làm là khai báo dependency nào cần thiết.
Trong ví dụ này Fruit phụ thuộc vào Store:
require 'dry/auto_inject'
class Store
def bananas
puts 'Have some organic bananas!'
end
end
Import = Dry::AutoInject({ 'store' => Store.new })
class Fruit
include Import['store']
def eat
store.bananas
end
end
fruit = Fruit.new
fruit.eat
Bạn phải nói object được tạo như thế nào:
Import = Dry::AutoInject({ 'store' => Store.new })
Và làm nó có sẵn cho class:
include Import['store']
Sau đó bạn có thể tạo Fruit với Store khác như sau:
Fruit.new(store: MyStore.new)
Bạn không cần gem để dùng dependency injection, nhưng thú vị để thấy cách khác làm điều này.
Tóm tắt
Bạn đã học về dry-rb, một tập hợp gem Ruby thú vị bạn có thể dùng để giải quyết các vấn đề thiết kế cụ thể trong code của mình.
Bây giờ đến lượt bạn thực hành & thử nghiệm!
Cảm ơn bạn đã đọc.