문제

빠른 배경 : PHP로 프로그래밍하고 있습니다. DB에서 데이터를 가져오고 도메인 클래스 생성을 담당하는 별도의 데이터 액세스 계층 (DAO 클래스)이있는 도메인 모델이 있습니다.

제가 제작할 책임이있는 DAO 수업이 있다고 가정 해 봅시다. 그룹 그리고 그루플리스트 사물. 그룹을 소셜 네트워크의 구성 요소로 상상할 수 있습니다. 이 질문에 대해 그들이 무엇인지는 중요하지 않습니다.

나는 Dao에게 나를 다양하게 만들도록 요청할 수 있어야합니다. 그루플리스트 다양한 기준을 기반으로 한 개체 :

  • 가장 최근에 추가 된 그룹
  • 가장 인기있는 그룹
  • 그룹은 관리자가 "추천"으로 식별되었습니다
  • 그룹은 특정 태그로 태그를 지정했습니다
  • 특정 키워드와 일치하는 그룹
  • 특정 범주 내의 그룹
  • 특정 사람이 만든 그룹
  • 특정 날에 그룹이 만들어졌습니다

이 중 일부는 지금 당장 필요하지 않지만 프로젝트가 끝나기 전에 필요하다고 상상할 수 있습니다. 이제 나는 멋진 간단한 DAO 방법으로 시작했습니다. CreateList. 이것은 훌륭하게 작동했습니다. 의사 코드를 다음과 같이 생각할 수 있습니다.

find out how many groups
create SQL query to fetch group details
loop through results
{
   create group object
   add to group list object
}

응용 프로그램이 진행됨에 따라 새로운 방법을 만들었습니다. CreateFeaturedList. 이것은 훌륭하게 작동했습니다. 그러나 실제로는 매우 매우 비슷했습니다 CreateList, 약간 다른 쿼리가 있습니다. 나머지 ~ 150 줄의 코드는 동일했습니다.

그래서... 필요한 모든 사례에 대해 어떻게해야합니까? 대부분의 경우 나는 특정 기준에 따라 목록을 필터링하고 정렬하기를 원합니다. 문제는 이것입니다.

ㅏ) 다음과 같은 많은 집중된 창조 방법을 만듭니다.

  • CreateList ()
  • CreateCategoryList (CategoryObject)
  • CreateUsersList (userObject)
  • CreateTaglist (태그)
  • CreatePopularList ()

또는

비) 모든 작업을 수행 할 수있는 하나의 큰 방법을 만듭니다 .- CreateList (SearchString, Orderby, FilterByCategoryObject = NULL, FilterByUserObject = NULL)

DAO 인터페이스가 더 단순하고 변경해야 할 가능성이 적기 때문에 (a)에 대한 아이디어가 아주 마음에 듭니다 (예 : 갑자기 전달해야 할 때 다른 매개 변수를 추가합니다. 데이트 비교하려면) 다른 매개 변수와 결합 할 수있는 검색 키워드와 같은 것들이있을 때 어려움이 발생합니다. EG : 검색 된 카테고리 목록, 검색 인기 목록, 검색 태그 목록 등 ... (a)는 내가 시작한 것입니다.

나는 (b)에 대한 리팩토링이있는 바람둥이를 가지고 있었지만 내 방법이 매우 크고 매우 복잡해지고, "If"S 및 "Select"S가 SQL을 구축 할 때 다른 경우를 처리 할 수있는 것을 볼 수 있습니다. 방법에 공급되는 많은 매개 변수. 그러나 적어도 그것은 모두 한 곳입니다. 그리고 당신은 사물을 결합 할 수 있습니다. EG : 사용자 그룹, blah 태그, 키워드에 일치합니다.

도움이 되었습니까?

해결책

모든 공개 방법이 호출하는 개인 방법을 만들 수 있습니다. 즉

private function _createList ( searchString, orderBy, ... )
{
    ...
}

public function createList()
{
    return $this->_createList('...', 'id');
}

public function createCategoryList()
{
    return $this->_createList('...', 'category_id');
}

이렇게하면 _CreatElist 함수가 나중에 변경되어야하는 경우이 DAO를 사용하는 모든 클래스가 아닌이 DAO의 공개 방법을 리팩터링하면됩니다.

다른 팁

나는 그것이 엄격히 또는 상황이라고 생각하지 않습니다. 옵션 A는 DAO가 노출 할 수있는 멋진 사용 가능한 인터페이스이므로 유지해야한다고 생각합니다. 나에게 옵션 B는 실제로 구현 특정 논리처럼 보입니다. 따라서 큰 방법이 귀하의 목적에 맞는 경우 옵션 A에서와 같이 인터페이스를 노출시키면서 실제 처리 로직을 수행하는 데 사용한다고 말합니다.

즉, 큰 방법이 너무 복잡하고 복잡 해지고 코드 재사용이 실제로 코드 복잡성을 높이고 응용 프로그램 유지 관리를 줄이면 각 인터페이스 방법에 대해 별도의 SQL 문을 유지하지만 도우미 메소드가 공통 로직을 실행하도록하는 데 리팩터가 필요할 수 있습니다. 결과를 구문 분석합니다.

그만큼 옵션 B의 방법은 코드 재사용을 줄이고 복잡성과 유지 보수 시간을 증가시킬 수 있습니다.

개인적으로 (그리고 코드 완료에 따르면) 방법은 한 가지 일을하고 잘 수행해야하며 모든 것을 막으려 고하지 말아야합니다. 미래에 리팩터를 리팩터링하고 처음에는 똑똑하지 않도록하십시오.

기본 사항 프로그래밍 : 코드를 섹션이나 기능으로 분류하는 것이 좋습니다.

나는 옵션 (a)에 갈 것이다. 코드를 유지하고 디버깅해야합니다. 그리고 버그가 있으면 코드를 다양한 방법으로 나누게되어 매우 기쁩니다.

또한 메소드 이름을 작성하면 자신이하는 일을 이해하는 데 도움이됩니다.

이것을 비교하십시오 :

옵션 (a)

$obj->AddNewList( /* params */ );
$obj->UpdateList( /* params */ );

이:

옵션 (b)

$obj->parse( /* first set of params */ );
$obj->parse( /* second set of params */ );

인간이 왼쪽에서 오른쪽으로 읽을 때 시간을 절약합니다. 그렇기 때문에 기능과 메소드 이름이 항상 왼쪽에 있습니다.

성능이 큰 문제가되지 않거나 그룹이 쿼리 캐싱이 유용 할 수 있도록 충분히 느리게 변경되면 필터링 기능을 작성하고 전달할 수 있습니다. 그룹을 통해 반복하고 필터링 메소드의 선택적 배열이있는 경우 루프가 있습니다. 될 것입니다 :

for(group in group) {
    cont = true
    for(f in functions) {
        if ! f(group) {cont = false; continue;}
    }
    if(cont) Continue
    add group to list
}

이렇게하면 루프를 변경하지 않고 필터링 매개 변수를 변경하거나 함수를 작성하거나 변경할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top