정적은 좋지 않지만 팩토리 패턴은 어떻습니까?


13

저는 TDD 프로젝트를 진행 중이므로 가능한 한 이런 종류의 개발에 참여하는 훌륭한 실무자를 고수하려고합니다. 그들 중 하나는 가능한 정적 및 전역을 피하고 있습니다.

이 문제에 직면하고 있습니다. "옵션"(추가 "마이크로 아티클")을 연결할 수있는 "아티클"개체가 있습니다.

나는 모든 것이 분리되어 기본적으로 객체 당 1 개의 쿼리를 작성 해야하는 상황에 있기 때문에 생산적이지 않거나 너무 많은 쿼리를 생성하지 않는 좋은 접근 방법을 알 수 없습니다.

실제 관점에서 볼 때 세 가지 옵션이 있습니다.

1) 기사 내부 빌드 :

class Article
{
    //[...]
    public function getArrOption(){
        //Build an array of Options instance.
        //return an array of Options.
    }
}

프로 : 똑바로

Const : 유지 관리 : 이제 기사 오브젝트에 Option 오브젝트의 빌드 로직이 포함됩니다. 이것은 아마도 코드 복제로 이어질 것입니다.

2) 옵션 팩토리 사용

class Article
{
    //[...]
    public function getArrOption(){
        return OptionFactory::buildFromArticleId($this->getId());
    }
}

장점 : 건축 논리가 기사 클래스에 속하지 않습니다

Const : 기사 클래스를 테스트하기 어렵게 만드는 "정적은 조롱하기 어려운"규칙을 위반하고 있습니다.

3) 모든 논리를 분리하십시오.

//Build the array of Option instance in a controller somewhere, using a Factory:
$arrOption = OptionFactory::buildFromArticleId($article->getId());

찬성 : 기사는 자신의 책임 만 처리하며 옵션에 대한 "아버지"링크는 신경 쓰지 않습니다. 상황이 실제로 분리되어 있습니다

Const : 옵션에 액세스해야 할 때마다 컨트롤러 내부에 더 많은 코드가 필요합니다. 즉 , 객체 내부에서 Factory를 절대 사용 해서는 안되며 , 그 소리는 나에게 우 토프입니다.

가장 좋은 방법은 무엇입니까? (내가 뭔가를 놓쳤습니까?) 감사합니다.

편집하다:

말할 것도없이 클래스 내부에서 팩토리를 호출 할 수 없다면 기본적으로 게으른 초기화 패턴을 절대로 사용할 수 없습니다 ...


그것이 적절한 지 확실하지 않지만 PHP로 코딩하고 있으므로 "응용 프로그램"은 상태가 적습니다. 세션 쿠키에 저장되지 않은 경우 각 페이지간에 모든 데이터를 다시로드해야합니다. 이는 애플리케이션 언어와 같은 모든 것을 사전로드 할 수 없음을 의미합니다 .
FMaz008

@job : 글쎄요. 왜냐하면 메소드 내부 의 정적 호출 은 단위 테스트시 대체하기가 거의 불가능하기 때문입니다. 목표는 의존성 주입을 사용하는 것입니다. 그러나 공장은 일반적으로 정적이므로 주입 할 수 없습니다.
FMaz008

답변:


12
  1. 스태틱은 "나쁜"것이 아니며, 불가능합니다. 조롱이 의미가없는 곳에서도 계속 사용할 수 있습니다.

  2. 팩토리 패턴은 아니지만 리포지토리 패턴처럼 보이지만 그렇지 않을 수도 있습니다. 팩토리는 동일한 인터페이스 / 기본 클래스를 가진 여러 클래스가 있고 반환 할 클래스를 결정하는 논리를 분리하려고합니다. 리포지토리는 리포지토리에서 데이터를 가져 와서 해당 리포지토리의 구현을 추상화합니다 (아티클은 옵션이 동일한 DB, 다른 하나, XML 파일, CSV 파일 등에 저장되어 있는지 알 필요가 없습니다).

  3. buildFromArticle 메소드를 호출 할 수있는 생성자에서 Article 클래스에 ObjectFactory (또는 Repository 또는 기타) 오브젝트를 제공 할 가능성을 무시했습니다.

내 PHP는 녹슬었지만 다음과 같이 보입니다.

class Article
{
    private $_option_repository;

    public function __construct($option_repository) {
        $_option_repository = $option_repository;
    }

    //[...]

    public function getArrOption(){
        return $_option_repository->buildFromArticleId($this->getId());
    }
}

나는 이것이 위의 모든 프로를 충족 시킨다고 생각합니다.


따라서 Factory / Repository / Mapper의 인스턴스를 갖는 것이 좋습니다. 객체가 반환 할 수있는 모든 가능한 객체에 대해 모든 팩토리 / 리포지토리 / 매퍼를 주입 해야하는 경우 신속하게 많이 만들었으므로 종속성 컨테이너 또는 무언가가 필요합니다. (
Article-

1
괜찮아, 바람직하다. 나는 일반적으로 여러 클래스에서 테스트하기에 충분히 작은 반복 코드를 제거하는 데 정적 사용을 예약합니다. 그리고 네, IOC / DI 컨테이너는 당신의 인생을 훨씬 더 쉽게 만들어 줄 것입니다. 하나를 사용하십시오.
pdr

1

정적 메소드가 필요하지 않으며 추상 팩토리가 혼동되는 것으로 입증되었으며 솔루션으로 종속성 주입에 대한 약간의 언어 변경을 제안하는 논문의 인용문이 있습니다.

인스턴스와 클래스 사이의 긴밀한 연결은 캡슐화를 깨뜨리고 정적 메소드의 전체 가시성과 함께 테스트를 복잡하게합니다. 의존성 주입을 프로그래밍 언어의 기능으로 만들어 정적 메소드를 완전히 제거 할 수 있습니다. 우리는 다음과 같은 의미 변화를 사용합니다.

(1) 모든 전역 발생을 인스턴스 변수에 대한 액세스로 대체하십시오.

(2) 인스턴스 변수가 인스턴스화 될 때 객체에 자동으로 주입되도록하십시오.

"Seuss : 세분화 된 구성 기능을위한 정적 방법에서 책임 분리

웨이 백 머신 링크


3
이 링크가 질문에 대한 답변을 제공 할 수 있지만 여기에 답변의 필수 부분을 포함시키고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변 이 유효하지 않을 수 있습니다.
gnat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.