2009-02-08 5 views
1

내 친구와 또 다른 논쟁. - 왜 #in_group처럼바로 가기 방법을 추가하거나 ActiveRecord 의미를 따르십니까?

class User < ActiveRecord::Base 
    has_many :groups 
    def in_group?(group) 
     groups.include?(group) 
    end 
end 
class Group < ActiveRecord::Base 
    has_many :members 
    def add_user(user) 
     members << user 
    end 
end 

내 의견이 방법은 코드에 여분의 불필요한 복잡성을 추가하고 거의 추측 할 수 있다는 것입니다 :이 코드를 생각해? #is_a_member_of?가 아닌 #add_user가 #add_member가 아닌 이유 등이 있습니다. Rails에 대한 4 년 경력과 총 20 년의 프로그래밍 경험을 통해, 나는 AR 의미를 따르고 User # groups.include? (그룹) 및 Group # members < < 사용자를 사용하는 것이 좋습니다. 그것들은 쉽게 추측 할 수 있으며 몇 가지 추가 기능이 필요하면 has_many : 회원에 대한 콜백을 사용하고 User # groups.include를 재정의 할 수 있습니까? 협회 확장 모듈에 필요하다면

그러나 친구는 "추상화 지점"을 만드는 데 바로 가기를 사용하는 것이 더 좋으며 콜백 또는 오버로드를 사용하는 대신이 코드를 확장하는 것이 더 낫다고 주장합니다.

당신은 어떻게 생각합니까?

P. 그냥 명확하게, 나는 뭘 "접근"접근 방식이 싫어 :

답변

2

전적으로 이러한 방법을 추가해서는 안됩니다. 다른 관련 개체를 만드는 것은 모델 작업이 아닙니다. 이것이 협회 프록시의 일입니다. 프록시 프록시가 구현되는 방식으로 인해 이상한 부작용이 생길 수 있으므로 연관 프록시 동작을 무시하는 것에주의해야합니다.

0

in_group?의 경우 : 메소드 이름은 한 방향으로 추측 할 수 있습니다. 읽으면 메소드 이름이 분명합니다. 이것은 중요한 종류의 추측입니다. 누군가이 코드를 유지 관리하면 그는 in_group? 호출에서 따라 잡을 수 없습니다. 또한 선언적이며 간결하며 가독성을 향상시킵니다 (이 경우 약간이지만 일반적으로 좋음). 스몰 토크 (Smalltalky) 방식의 방법입니다.

한편, add_user 방법은 필요하지 않다고 생각합니다. 특히 간결하거나 직접적인 것은 아니며, 비표준 일뿐입니다. 그 이름은 여전히 ​​상당히 명백하고 심각하게 해를 끼치 지 않지만 그 이익을 보지 못합니다. 바로 가기보다는 경치 좋은 길로 보입니다.

+0

#in \ _group을 쉽게 생각할 수 있습니까? #member \ _of입니까? –

+0

물론 그 이름을 지을 수 있습니다. 당신은 또한 Enumerable # map을 Enumerable # transform으로 이름을 바꿀 수 있습니다.하지만 뭐라 구요? 그렇다고이 방법이 존재해서는 안된다는 의미는 아닙니다. – Chuck

1

"Law of Demeter"에 인용 된 스타일은 groups 또는 members을 직접 조작하는 클라이언트 코드에 대해주의를 요합니다.

1

나는 확실히 추상화에 찬성하지만이 실행에는 찬성하지 않는다. 친구가 좋은 점을 제기합니다. 회원이 그룹에 속하는지 여부를 어떻게 결정한다면 어떻게 될까요? 리팩토링을해야 할 일이 있습니다. 행운을 빈다.

하지만 혼란스러운 기능을 잘못된 위치에 배치한다는 주장이 있습니다. 나는 당신이 잘못된 조직을 가지고 있다고 말하고 싶습니다. 왜 특정한 관계 모델 객체에 그것들을 붙이지 않을까요?

예 :

user.groups.in_group?("admin") 

또는 나를 훨씬 더 우아한 모습에, 그것의 좀 더 자세한하지만 분리가 더 관련성을

group.members.add_user(user) 

.

+0

리팩토링은 실제로 복잡하지 않습니다. 나는 항상 <

+0

그룹에있는 그룹의 컬렉션을 요청하고 있습니까? 그것은 단지 이상하게 보입니다. 그것은 그룹에있는 사용자이고 그룹 콜렉션은 아닙니다. 이런 식으로하면 #include?를 사용할 수 있습니다. – Chuck

+0

컬렉션에 대한 정보가 적어서 내 마음 속에서 프록 싱하는 것에 대해 자세히 설명합니다. 각자 자신에게 나는 생각한다. 또한 메서드 추적과 관련하여 악몽처럼 들릴 수도 있습니다. –

0

나는 (그룹 변경 의미에서 "회원"과 같은) 원인이있을 때 이러한 방법을 선호합니다. 이러한 방법을 사용하면 시간이 지남에 따라 증가하고 변화하는 논리를 캡슐화하고 테스트를 돕습니다. 이것이 OO 프로그래밍의 요점이 아닌가?