2014-06-15 4 views
0

특정 기준에 따라 다양한 프랜차이즈에 대한 수수료 구조를 구현해야합니다. 나는 등 다양한 구조에 대한팩토리 메서드 디자인 패턴을 구현하는 올바른 방법이

public class ST1 extends FranchiseFeeStructure{ 
    @Override 
    void getMonthlyFee(){ 
     monthlyFee=890; 
    } 

} 

과 ST2, ST3과 같은 FranchiseFeeStructure를 확장 클래스를 만들어 지금은 다른 구조에 대한 FranchiseFeeStructure

public abstract class FranchiseFeeStructure { 
     private BigDecimal registrationFee=1500; 
     protected BigDecimal monthlyFee; 

    public BigDecimal getMonthlyFees(){ 
      return monthlyFee; 
     } 

    public BigDecimal calculateFee{ 
     //calculate fee here 
     return fee; 
     } 
} 

추상 클래스를 만든다. 정적 팩토리 메소드를 가지는 클래스가 있습니다.

public class GetFeeStructureFactory { 

    public static FranchiseFeeStructure getFranchiseFeeStructure(String franchiseFeeStructureType){ 

     if(franchiseFeeStructureType == null){ 
      return null; 
     } 
     if(franchiseFeeStructureType.equalsIgnoreCase("ST1")) { 
       return new ST1(); 
      } 
     else if(franchiseFeeStructureType.equalsIgnoreCase("ST2")){ 
    /// so on... 

    } 
} 

지금

FranchiseFeeStructure franchiseFeeStructure = GetFeeStructureFactory.getFranchiseFeeStructure("ST1"); 
     franchiseFeeStructure.getMonthlyFee(); 
      franchiseFeeStructure.calculateFee(); 

이 방법 공장 패턴을 구현하는 올바른 방법인가로 사용합니다. 내가 잘못했거나 더 나아질 제안이 있다면 말해주십시오.

답변

1

문제는 공장에서 구현되지 않습니다. 그것은 당신의 추상 클래스가 구현되는 방식에 있습니다. 모든 호출자가 (부적절하게 명명 된) 메소드 getMonthlyFee()을 호출하여 월간 요금을 초기화하도록합니다. 발신자가 그렇게해서는 안됩니다. 그리고 당신의 추상 클래스는 그렇게 추상적 인 방법에 ... 의존해야

public abstract class FranchiseFeeStructure { 
    private static final BigDecimal REGISTRATION_FEE = new BigDecimal(1500); 

    public final BigDecimal calculateFee { 
     BigDecimal monthlyFee = getMonthlyFee(); 
     // TODO compute 
     return fee; 
    } 

    /** 
    * Subclasses must implement this method to tell what their monthly fee is 
    */ 
    protected abstract BigDecimal getMonthlyFee(); 
} 

public class ST1 extends FranchiseFeeStructure { 
    @Override 
    protected BigDecimal getMonthlyFee(){ 
     return new BigDecimal(890); 
    } 
} 

그런 식으로, 호출 측이 월 사용료를 초기화 할 필요가 없습니다. 그것을 할 필요가 모든는 월 사용료가 항상 일정한 값이면, 당신도 추상 클래스와 여러 개의 서브 클래스를 필요로하지 않는 것이

BigDecimal fee = FeeStructureFactory.getFranchiseFeeStructure("ST1").calculateFee(); 

참고입니다. 필요한 것은 월간 요금을 생성자 인수로 사용하는 단일 클래스입니다.

+0

감사 Nizet을 돕기 위해 노력할 것입니다, 난 정말 당신의 응답을 주셔서 감사합니다. 오프 코스, 나는 추상적 인 방법으로 getMonthlyFee를 만들어야한다. – vinaybhatoa

+0

하지만 생성자 인수로 매월 요금을 내리는 마지막 줄로 이해할 수 없습니다. 월간 수수료가 다른 경우 수수료가 다르다. 구조체 – vinaybhatoa

+0

그러나 모든 서브 클래스에 대해 월별 요금이 일정하다면 간단히 FranchiseFreeStructure를 추상화하지 않고 'new FranchiseFreeStructure (890) 반환'또는 '새 FranchiseFreeStructure (122) 반환' 구조체 유형. 단순히 값을 변경하는 하위 클래스가 필요하지 않습니다. 하위 클래스는 동작을 변경하는 데 유용합니다. 즉, 다른 논리를 제공하는 것입니다. 당신이 말했듯이 –

0

그래, 생각은 똑같지 만 코드를 개선 할 수 있습니다. 나는 나에 따라 개선을 제안 할 것이다. 추상 클래스가 아닌 인터페이스와 구현으로 제시 하겠지만 아이디어는 같습니다. 당신이 무엇을해야하는 경우

interface FranchiseFee{ 
    BigDecimal getMonthlyFee(); 
    BigDecimal calculateFee(): 
} 

public class CocaColaFee implements FranchiseFee{ 

    public BigDecimal getMonthlyFee(){ 
    return new BigDecimal(".."); 
    } 

    public BigDeicaml calculateFee(){ 
    // do the calculation 
    } 

} 

public class PepsiFee implements FranchiseFee{ 

    public BigDecimal getMonthlyFee(){ 
    return new BigDecimal(".."); 
    } 

    public BigDeicaml calculateFee(){ 
    // do the calculation 
    } 

} 

public FranchiseFeeFactoty { 


// this is the easiest way to avoid if/else which makes the code awful. Also to use this you need to have default constructor, because as you can see you need additional code and it get's complicated. 

//the other way is to use map but it's just a more convenient if/else approach 

    public static FranchiseFee create(Class<? extends FranchiseFee> franchiseFeeType){ 

    try { 
      return franchiseFeeType.newInstance(); 
     } catch (InstantiationException e) { 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 

    } 
} 

그냥 물어 : 난 당신이

+1

호출자가 인스턴스를 가져 오기 위해 클래스 (예 : PepsiFee.class)에 대한 참조가 필요하면 간단히 생성자를 직접 호출 할 수 있습니다. 팩토리의 요점은 어느 구체적인 유형이 수신 될지 알지 못하는 채 무관 한 값 (예 : 문자열)에서 객체를 가져 오는 것입니다. –

+0

글쎄, 나는 의견이 맞지 않아, 어쨌든 당신이 객체에 대한 참조를 가질 수있는 참조가 무엇인지 알지 못한다. 그리고 당신이 아무리 많은 구현을하더라도 factory 메소드에 다른 바보를 추가하지 않는다면이 방법으로는 불가능합니다. 10 가지 구현이 있다면 어떻게 될까요? 인스턴스를 얻으려면 여러 개의 if를 사용해야합니다.또한 내가 factory 메소드에서 문자열을 변경하고 어딘가에서 그것을 호출 할 때 당신이 모르게 코드를 파산시킬 수 있다고 제안하는 방법. – Tek

+0

당신이 이해하지 못했을 것 같아요. 웹 페이지에서 일부 JSON 객체를 받았다고 가정하면이 JSON 객체에는 "coke"또는 "pepsi"문자열이 포함됩니다. 이제이 문자열을 기반으로 적당한 FranchiseFree 인스턴스를 얻으십시오. 그것은 OP가 구현하려고하는 공장의 전체 지점입니다. 어떤 방식으로 보든,이 문자열을 기반으로 적절한 인스턴스를 반환하는 무언가를 구현해야합니다. JSON에는 클래스 이름이 포함되지 않습니다. 외부 세계는 애플리케이션의 내부 구현을 신경 쓸 필요가 없기 때문입니다. –