2009-02-27 4 views
3

특정 응용 프로그램에서 작업하면서 필자는 매우 비슷한 쿼리를 계속해서 계속 작성합니다. 정확히 동일하지는 않지만 매우 유사한 형태이며 거의 동일한 코드 덩어리 인 에 삽입됩니다.,DRY 및 이와 유사한 쿼리

$Mysqli = new mysqli; 
if ($Stmt = $Mysqli->prepare("SELECT foo 
           FROM tblFoo 
           WHERE something = ?")) { 
    $Stmt->bind_param('s', $this->_something); 
    $Stmt->execute(); 
    if (0 != $Stmt->errno) 
     throw new Exception("blah, blah, blah"); 
    $Stmt->bind_result($foo); 
    while ($Stmt->fetch()){ 
     $this->_foos[] = new Foo($foo); 
    } 
    $Stmt->close(); 
    } else { 
     throw new Exception("blah, blah, blah");); 
    } 
} 

이상 다른 곳에서 ...

$Mysqli = new mysqli; 
if ($Stmt = $Mysqli->prepare("SELECT bar, baz 
           FROM tblBar 
           WHERE somethingElse = ?")) { 
    $Stmt->bind_param('s', $this->_somethingElse); 
    $Stmt->execute(); 
    if (0 != $Stmt->errno) 
     throw new Exception("blah, blah, blah"); 
    $Stmt->bind_result($bar, $baz); 
    while ($Stmt->fetch()){ 
     // do something else with $bar and $baz 
    } 
    $Stmt->close(); 
    } else { 
     throw new Exception("blah, blah, blah");); 
    } 
} 

... 그리고 또 다른, 다른 곳에서 또 다른 ... 등

이 DRY의 실제 위반 ? 이러한 종류의 쿼리 (테이블, 열, 바운드 변수 등의 생성자 params 또는 setter 포함)를 수행하고 내 앱 전체에서 다시 사용하는 클래스를 작성하는 것은 당연한 것처럼 보입니다. 그러나 동시에, 나는 자신을 반복하고있는 잔소리 같은 느낌을 떨칠 수 없습니다.

단순한 쿼리를 작성하는 방법이 너무 많아서 이와 같은 반복이 예상되는 것일 수도 있습니다.

생각하십니까?

답변

1

많은 사람들이 정확하게 이것을합니다. 모두 같은 클래스에서 상속받은 각 테이블을 나타내는 클래스를 만듭니다. 기본 클래스는 데이터로드 및 저장을 처리 할 수 ​​있습니다. 따라서 데이터를로드하려면 load 메서드를 호출하면됩니다. 또한 개체의 속성을 사용하여 필드 값을 설정하고 액세스 할 수 있습니다.

많은 더러운 작업을 처리하는 hibernate과 같은 라이브러리도 있습니다.

+0

@ 키비 - 고마워요. 나는 Hibernate를 사용하지 않을 것이지만, 나는 ActiveRecord 클래스를 생성 한 다음 특정 테이블에 대해 몇 가지 클래스를 subbed했다. – PartialOrder

1

나는 그것이 위반이라고 말하고 싶습니다. (누락 된 것이 아니라면) 코드에서 한눈에 볼 때 "foo"및 "bar"문자열 (몇 번 반복)과 실제 비즈니스 논리를 제외하고는 두 문장이 동일합니다.

최소한 압축을 풀 수 있습니다. 더 중요한 것은 모든 SQL 문자열이 추출되어야한다는 것입니다. 그들은 항상 코드보다는 내게 데이터와 같았습니다. SQL 문자열, 테이블 등의 배열을 가지고 있다면 리팩토링이 더 명확해질 것입니다.

당신은 테이블 이름과 비즈니스 로직을 포함하는 방법을 한 물체가 있다면,

하나의 가능성 (사용자 코드에서 문자열 및 기타 데이터를 추출하는 것은 리팩토링을 시작하는 좋은 방법입니다), 당신은 통과 할 수 모든 상용구가있는 "프로세서"에 넣습니다 (나머지 모든 코드는 거기에 있습니다).

건조하게 만들 수 있다고 생각합니다.

는 (PS는. 항상 상속을 통해 구성을 선호합니다. 개체를 "실행"할 수있는 클래스를 통해 상속을 사용하는 어떠한 장점도 없다) 당신은 모듈화하는 최초의 욕망 중 하나가 발생한

+0

@ Bill K. 이것은 가까운 호출 이었지만 실제로 Kibbee의 답변을 살펴 보았습니다. 실제로이 문제를 처리하는 방법에 조금 더 가깝기 때문입니다. 귀하의 의견도 매우 유용했습니다. 특히 리팩토링에서 문자열을 추출하는 것이 중요합니다. +1 감사합니다! – PartialOrder

0

가. :-)

두 가지 일반적인 해결책이 있습니다. 첫 번째는 비슷한 쿼리의 전체 (또는 대부분)에 대한 호출을 추상화하는 것입니다. 그런 다음 다시 다른 쿼리 집합으로 이동하십시오. 그런 다음 다른 사람에게. 등등. 불행하게도이 결과는 쿼리를 호출하고, 문제를 확인하고, 결과 집합을 어셈블하고, 다시 전달하는 같은 블록을 만듭니다. 그것은 DAL이지만 일종의 것입니다. 또한 확장되지 않습니다.

두 번째 해결 방법은 쿼리를 만들고 결과를 반환하는 프로세스를 추상화 한 다음 그 위에 데이터 액세스를 추상화하는 것입니다 (기본적으로 SQL을 어셈블하는 것을 의미합니다). 이것은 간단한 DAL이 아닌 적절한 ORM이 될 가능성이 큽니다. 이것을 확장하는 것이 훨씬 쉽습니다.

관련 문제