ขณะที่คุณกำลังเขียนแอป Rails คุณอาจพบปัญหาที่คุณสามารถแก้ไขได้ง่ายขึ้นด้วยที่เก็บข้อมูลอื่น ตัวอย่างเช่น คุณอาจมีกระดานผู้นำที่จัดอันดับผู้ใช้ตามจำนวนคะแนนที่พวกเขาได้รับจากการตอบคำถามบนไซต์ของคุณ ด้วย Redis Sorted Sets มีการดำเนินการมากมายสำหรับคุณ สุดยอด! แต่คุณจะใส่โค้ดที่โต้ตอบกับ Redis ไว้ที่ไหน
User
ของคุณ โมเดลสามารถพูดคุยกับ Redis:
class User < ActiveRecord::Base
def award_points(points)
Redis.current.zincrby("leaderboard", points, id)
end
end
แต่ตอนนี้ User
. ของคุณ model รับผิดชอบในการเป็นตัวแทนของ auser, พูดคุยกับ Redis, และ จัดการลีดเดอร์บอร์ด! ทำให้User
เข้าใจยากขึ้นและทดสอบยากขึ้น ซึ่งตรงกันข้ามกับสิ่งที่คุณต้องการ
แต่คุณสามารถรวมคำขอ Redis ในออบเจ็กต์ใหม่ที่แสดงถึงสิ่งที่คุณกำลังใช้ Redis สำหรับ . ตัวอย่างเช่น คุณสามารถสร้าง Leaderboard
คลาสที่ปิดการสื่อสาร Redisไม่ รับช่วงจาก ActiveRecord::Base
แต่ยังอยู่ในapp/models
ไดเรกทอรี ซึ่งจะมีลักษณะดังนี้:
class Leaderboard
def award_points_to_user(user_id, points)
Redis.current.zincrby("leaderboard", points, user_id)
end
end
class User < ActiveRecord::Base
def award_points(leaderboard, points)
leaderboard.award_points_to_user(id, points)
end
end
คลาสทั้งสองนี้ใช้งานได้ใน app/models
แต่ตอนนี้คุณไม่ได้ทำให้โมเดล ActiveRecord ของคุณปนเปื้อนด้วยตรรกะพิเศษ Leaderboard
คลาสจัดการการสื่อสารกับ Redis ดังนั้นUser
ชั้นเรียนไม่ต้องสนใจว่ากระดานผู้นำถูกนำไปใช้งานอย่างไร นอกจากนี้ยังช่วยให้ทดสอบได้ง่ายขึ้นอีกด้วย
คุณได้รับมากมายจากการสร้างชั้นเรียนใหม่สำหรับความรับผิดชอบใหม่และapp/models
เป็นสถานที่ที่ดีที่จะเก็บไว้ คุณได้รับประโยชน์จากการใช้บริการอื่นสำหรับการใช้งานคุณลักษณะของคุณ ในขณะที่ยังช่วยให้โค้ดของคุณใช้งานได้ง่ายอีกด้วย
ลองใช้เลย
คุณนึกถึงการสื่อสารบริการเครือข่ายที่เรียกใช้โดยตรงจากรุ่น ตัวควบคุม หรือมุมมอง ActiveRecord ของคุณหรือไม่ ลองย้ายโค้ดนั้นไปยังโมเดลข้อมูลที่ไม่ใช่ ActiveRecord และดูว่าโค้ดของคุณเข้าใจ ใช้งาน และทดสอบได้ง่ายขึ้นหรือไม่ จากนั้นส่งอีเมลมาบอกฉันว่ามันเป็นอย่างไร!
เพียงจำไว้ว่า:
ปัญหาทั้งหมดในวิทยาการคอมพิวเตอร์สามารถแก้ไขได้โดยอ้อมอีกระดับ
— เดวิด วีลเลอร์
…ยกเว้นปัญหาเรื่องชั้นเชิงมากเกินไป
— เคฟลิน เฮนนีย์