这是实现Factory Method设计模式的正确方法吗?

时间:2014-06-15 10:21:12

标签: java design-patterns factory factory-pattern

我必须根据某些标准为各种特许经营实施不同的收费结构。我为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;
        }
}

现在,对于不同的结构,我创建了扩展FranchiseFeeStructure的类,如

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

}

和ST2,ST3等各种结构。我们有一个类有静态工厂方法。

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();

这是实现Factory模式方法的正确方法吗?请告诉我,如果我错了或有任何改善的建议。

2 个答案:

答案 0 :(得分: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();

请注意,如果月费总是一个恒定值,您甚至不需要抽象类和多个子类。您所需要的只是一个单独的课程,将月费作为构造函数参数。

答案 1 :(得分: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();
        }

   }
}

如果您还需要其他任何东西请求它:)我会尽力帮助您