กำลังหา gems ใหม่และน่าสนใจลองไหม?
ลองดู dry-rb ชุด gems ที่นำเสนอโซลูชันสำหรับปัญหาทั่วไป Dry-rb ประกอบด้วยมากกว่า 18 Ruby gems ที่ทำงานร่วมกันหรือแยกกันได้
บาง gems รวมถึง:
- dry-initializer
- dry-struct
- dry-validations
- dry-events
- dry-transaction
ในโพสต์นี้ คุณจะได้เรียนรู้ 3 gems นี้ เพื่อลองชิมว่า dry-rb มีอะไรให้!
วิธีสร้าง Structs ที่ดีขึ้นด้วย dry-struct
Ruby Struct เป็นประเภทของออบเจ็กต์ที่คุณสร้างจากคลาส Struct แตมีข้อจำกัดบางอย่าง
ตัวอย่าง:
คุณสามารถสร้าง struct ด้วยจำนวนอาร์กิวเมนต์ที่ขาดหายไป และไม่ได้รับการบ่นจาก Ruby
ด้วย gem dry-struct คุณสามารถสร้าง structs ที่เข้มงวดขึ้น (stricter)
วิธีทำ:
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: [])
ตอนนี้ถ้าคุณพลาด attribute ใด attribute หนึ่ง คุณจะได้ข้อผิดพลาดนี้:
[Video.new] :comments is missing in Hash input
ข้อความข้อผิดพลาดไม่ค่อย user-friendly แตทำหน้าที่ได้
คุณสามารถ สร้าง types ของตัวเอง และเพิ่ม constraints เข้าไป:
module Types include Dry::Types.module Age = Integer.constrained(gt: 0) end
"gt" หมายถึง "greater than" (มากกว่า)
ดังนั้น Age ต้องเป็นจำนวนเต็มมากกว่า 0
สามารถมีค่าเริ่มต้น (default values) ได้ไหม?
ได้ นี่คือวิธี:
module Types
include Dry::Types.module
Name = String.default('')
end
มีรูปแบบสั้นกว่าสำหรับการสร้าง Dry structs ที่คล้าย Ruby structs ปกติ
ตัวอย่าง:
Book = Dry::Struct(title: Dry::Types["string"]) Book.new(title: "Computer Science 101")
การนำ Observer Pattern ไปใช้กับ dry-events
Observer design pattern คือเมื่อ แหล่งเดียว เผยแพร่การอัปเดตไปยัง ผู้ฟังหลายคน อาจเป็นข่าวสาร การแจ้งเตือนหุ้น ข้อความใหม่ในแชทกลุ่ม ฯลฯ
มันเป็นรูปแบบทั่วไป
Ruby รวม observable module ที่ช่วยคุณ implement นี้
แต dry-events เป็นอีกตัวเลือก
คุณสามารถสร้าง publisher ได้แบบนี้:
require 'dry/events/publisher'
class Blog
include Dry::Events::Publisher[:blog]
register_event('article.published')
register_event('article.upated')
end
ตอนนี้:
คลาสไหนก็ตามสามารถลงทะเบียนตัวเองเพื่อรับ events เมื่อเกิดขึ้น
วิธีทำ:
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)
คุณสามารถ broadcast event ด้วยเมธอด publish:
blog.publish('article.published', title: 'How to Use The dry-events Gem')
สิ่งหนึ่งที่ผมสังเกตกับ gem นี้คือ หากคุณ subscribe หรือ publish event ที่ไม่มีอยู่ มันจะล้มเหลวเงียบๆ (fail silently)
Dependency Injection ด้วย dry-auto_inject
Dependency (การพึ่งพา) คืออะไร?
Dependency คือสิ่งที่คลาสต้องการเพื่อทำงาน เช่น ออบเจ็กต์และคลาสอื่นๆ
คุณสามารถสร้างออบเจ็กต์เหล่านี้โดยตรงในคลาสของคุณ...
หรือคุณสามารถใช้ dependency injection
Dependency injection คือเมื่อ dependencies ถูก "inject" เข้าไปในคลาส กล่าวคือ ถูกส่งผ่านเป็นพารามิเตอร์
ตัวอย่าง:
require 'faraday'
class GitHubAPI
def initialize(http_client = Faraday.new)
@http_client = http_client
end
end
การทำอย่างนี้ช่วยให้คุณควบคุม dependency และทำให้ testing ง่ายขึ้น
ตอนนี้:
dry-auto_inject สร้างออบเจ็กต์เหล่านี้ให้คุณ คุณแค่ต้องประกาศว่า dependencies ไหนที่ต้องการ
ในตัวอย่างนี้ Fruit ขึ้นอยู่กับ 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
คุณต้องบอกว่าออบเจ็กต์ถูกสร้างอย่างไร:
Import = Dry::AutoInject({ 'store' => Store.new })
และทำให้พร้อมใช้สำหรับคลาส:
include Import['store']
จากนั้นคุณสามารถสร้าง Fruit ด้วย Store ที่ต่างกันได้:
Fruit.new(store: MyStore.new)
คุณไม่ต้องการ gem เพื่อใช้ dependency injection แต่น่าสนใจที่ได้เห็นอีกวิธีหนึ่ง
สรุป
คุณได้เรียนรู้เกี่ยวกับ dry-rb ชุด Ruby gems ที่น่าสนใจซึ่งคุณสามารถใช้แก้ปัญหาการออกแบบเฉพาะในโค้ดของคุณ
ตอนนี้ถึงคุณแล้ว ฝึกฝนและลองทำดูสิ!
ขอบคุณที่อ่านครับ