2015-01-05 5 views
0

다른 패턴을 사용할 수 있는지 알고 있습니다. 현재 나는 추상적 인 공장 패턴을 사용하고 있으며, 나는 그것에 대해 꽤 잘 알고 있다고 생각한다. 내 자원은 위키 피 디아 외에입니다 : 내가 예를 들어 샘플 추상 팩토리 패턴을 만들기 위해 애플과 자사의 제품을 사용하고 http://www.tutorialspoint.com/design_pattern/abstract_factory_pattern.htm http://www.oodesign.com/abstract-factory-pattern.html https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/AbstractFactoryPHP 추상 팩토리 패턴 구현

. 나는 코드 중복이 나쁜 디자인이라는 것을 이해한다. 그러므로 나는 이것을 쓰고있다. 지금까지 내 코드는 다음과 같습니다.

abstract class AbstractAppleFactory { 
    abstract public function createiPod($capacity, $type, $color, $engraving); 
    abstract public function createiPhone($capacity, $type, $color, $antenna); 
    abstract public function createComputer($type, $HDCapacity, $CPU, $ram); 
} 

class iPodFactory extends AbstractAppleFactory { 
    public function createiPod($capacity, $type, $color, $engraving) { 
     $class = 'iPod' . $type; 

     return new $class($capacity, $color, $engraving); 
    } 

    public function createiPhone($capacity, $type, $color, $antenna){ /* no implementation necessary */} 
    public function createComputer($type, $HDCapacity, $CPU, $ram){ /* no implementation necessary */} 
} 

interface iPlayer { 
    public function play(); 
    public function stop(); 
    public function fastForward(); 
    public function rewind(); 
} 

abstract class iPod implements iPlayer { 
    protected $capacity; 
    protected $color; 
    protected $engraving; 

    public function __construct($capacity, $color, $engraving = null) { 
     $this->capacity = $capacity; 
     $this->color = $color; 
     $this->engraving = $engraving; 
    } 
} 

class iPodClassic extends iPod { 
    public function play() {/* implementation goes here */} 
    public function stop() {/* implementation goes here */} 
    public function fastForward() {/* implementation goes here */} 
    public function rewind() {/* implementation goes here */} 
} 
class iPodShuffle extends iPod { 
    public function play() {/* implementation goes here */} 
    public function stop() {/* implementation goes here */} 
    public function fastForward() {/* implementation goes here */} 
    public function rewind() {/* implementation goes here */} 
} 

등. 여기에 입력 할 코드가 너무 많습니다. 나는 그것이 디렉토리와 네임 스페이스에서 구성하는 것이 더 낫다는 것을 안다. 그것은 내가 지금 배우고있는 것이 아닙니다. 패턴과 OOP 개념을 배우고 있습니다.

문제의 부분은 : 나는 관련이없는 공장에서 두 불필요한 메소드를 구현하도록 강요하고

class iPodFactory extends AbstractAppleFactory { 
    public function createiPod($capacity, $type, $color, $engraving) { 
     $class = 'iPod' . $type; 

     return new $class($capacity, $color, $engraving); 
    } 

    public function createiPhone($capacity, $type, $color, $antenna){ /* no implementation necessary */} 
    public function createComputer($type, $HDCapacity, $CPU, $ram){ /* no implementation necessary */} 
} 

상속/추상화로 인해. createiPhone()createComputer(). 추상 팩토리 패턴을 제대로하고 있습니까? 다시 말하지만, "코드 중복은 나쁜 디자인입니다!" 이것에 대해 더 좋은 방법이 있습니까?

+0

전체 프로젝트에서 한 패턴을 고수해야합니까? 저는 개인적으로 필요에 따라 디자인 패턴을 사용합니다. 종속성 주입을 사용하여 클래스에 iPhone 객체를 삽입하여 메소드를 사용할 수 있다고 생각하십니까? – Joao

+0

그것은 단지 운동입니다. –

답변

3

나는 당신이 중대한 실수를 저질렀다고 생각합니다. 추상 팩토리는 제품 패밀리 작성을위한 추상화를 작성하기 때문에 다른 패밀리로 쉽게 변경할 수 있습니다. f.e. Apple => Samsung :)

interface ComputerAbstractFactory { 
    /** 
    * @return Tablet 
    */ 
    function createTablet(); 
    /** 
    * @return Phone 
    */ 
    function createPhone(); 
    /** 
    * @return Computer 
    */ 
    function createComputer(); 
} 

class AppleComputerFactory implements ComputerAbstractFactory {} 

class SamsungComputerFactory implements ComputerAbstractFactory {} 

class IPad implements Tablet {} 

class GalaxyTab implements Tablet {} 

... 

추상 회사 패턴을 사용하면 두 회사를 전환 할 때 의미가 있습니다. 코드는 추상화 (솔리드 원칙) ComputerAbstractFactory, Tablet, Phone, Computer에만 의존해야합니다. 제조업체가 당신이 당신의 bussiness 코드에 ComputerAbstractFactory의 선택이 끝난 구현을 주입하는 것이 한 정도로 그리고 당신이 완료 사용해야합니다 (일부 구성 스위치에 의한 철)을 결정하는 경우에이 방법 - 등

정제가 만든 얻을, 모든 작품, 전화 호출 코드가 추상화의 구체적인 구현에 결합되지 않도록 응용 프로그램에서 어떤 추상화를 만들지 결정해야합니다. 나는 IPlayer가 당신이 원하는 곳이라고 믿는다. IPodClassic IPodShuffle은 구체적인 구현체이다. 내가 옳다 경우에 당신은 당신이 언급 한 중복 정보

class IPlayerFactory { 
    /** 
    * @return IPlayer 
    */ 
    function create() {...} 
} 

IPlayerFactory

을 만들어야합니다.iPodFactory가 AbstractAppleFactory를 확장하는 경우 모든 메소드를 구현해야합니다 (AbstractAppleFactory에 구현이없는 경우 btw는 인터페이스 여야 함) 당신은 SOLID 원칙에서 Liskov 원칙을 위반했습니다. 짧은 버전 - 호출 코드가 AbstractAppleFactory에 의존하고 작동하도록 구현 된 구체적인 구현으로 iPodFactory를 가져 오면 createiPhone 또는 createComputer를 호출 할 수 없으므로 추상화가 작동하지 않습니다.

+0

감사합니다. @Jakub! 내가 패턴을 연습 한 것은 이번이 처음입니다. –

+0

"추상화"의 정의를 살펴 봤는데 100 % 맞습니다. 나는 그것이 무엇인지 결코 알지 못할 것 같다! –

0

당신은 옳은 길로 가고 있습니다 만, 나는 틀렸다고 생각합니다.

우선, 하위 클래스에서 사용할 메서드를 만들지 않으면 abstract 클래스를 사용하지 마십시오. interface을 사용하는 것이 좋습니다. 당신이 볼 수 있듯이, 내가 이해하기 더 적은 코드를

<?php 
class iPhoneFactory implements AppleFactoryInterface 
{ 
    public function create($data) 
    { 
     $klass = sprintf('iPhone'.$data['type']); 
     $instance = new $klass; 
     $instance->setFromArray($data); 

     return $instance; 
    } 
} 

:

여기
<?php 
interface AppleFactoryInterface 
{ 
    function create($data); 
} 

그리고는 iPhoneFactory입니다 :

이 내 해결책이 될 것입니다.

관련 문제