Rails 앱을 작성하는 동안 다른 데이터 저장소로 더 쉽게 해결할 수 있는 문제에 직면할 수 있습니다. 예를 들어, 사이트에서 질문에 답하여 얻은 점수에 따라 사용자의 순위를 매기는 리더보드가 있을 수 있습니다. Redis Sorted Sets를 사용하면 많은 구현이 완료됩니다. 대박! 하지만 Redis와 상호 작용하는 코드는 어디에 두나요?
귀하의 User
모델이 Redis와 대화할 수 있음:
class User < ActiveRecord::Base
def award_points(points)
Redis.current.zincrby("leaderboard", points, id)
end
end
하지만 이제 User
모델은 사용자를 대표하고 Redis와 대화하며 및 리더보드 관리! 이것은 User
를 만듭니다. 이해하기 어렵고 테스트하기가 더 어렵습니다. 그것은 당신이 원하는 것과 반대입니다.
대신 Redis를 for 사용하는 대상을 나타내는 새 객체로 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 데이터 모델로 이동하고 코드를 더 쉽게 이해하고 작업하고 테스트할 수 있는지 확인하십시오. 그런 다음 이메일을 보내 어떻게 진행되었는지 알려주세요!
기억하세요:
<블록 인용>컴퓨터 과학의 모든 문제는 다른 수준의 간접 참조로 해결할 수 있습니다.
— 데이비드 휠러
<블록 인용>...너무 많은 간접 계층의 문제를 제외하고.
— 케블린 헤니