简体   繁体   English

这是实现工厂方法设计模式的正确方法

[英]Is this the right way to implement Factory Method design pattern

I have to implement a fee structure different for various franchise depending on certain criteria. 我必须根据某些标准对各种特许经营实行不同的费用结构。 i make an Abstract Class for 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;
        }
}

Now for different structure i make classes which extends FranchiseFeeStructure like 现在,对于不同的结构,我创建了扩展FranchiseFeeStructure的类,例如

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

}

and ST2, ST3 and so on for various structures. ST2,ST3等适用于各种结构。 and we have a class to have static factory method. 并且我们有一个具有静态工厂方法的类。

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...

    }
}

Now use it as 现在将其用作

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

Is this the right way to implement the method Factory pattern. 这是实现工厂模式方法的正确方法。 Please tell me if i am wrong or any suggestion to make it better. 请告诉我是否有错或有任何建议可以改善它。

The problem is not so in the factory implementation. 在工厂实施中问题并非如此。 It's in the way your abstract class is implemented. 这是抽象类的实现方式。 It forces every caller to initialize the monthly fee, by calling a (badly named) method getMonthlyFee() . 它通过调用(错误命名的)方法getMonthlyFee()来强制每个调用者初始化月费。 The caller shouldn't have to do that. 呼叫者不必这样做。 And your abstract class should rely... on an abstract method to do that: 并且您的抽象类应该依赖于...一个抽象方法来做到这一点:

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

That way, the caller doesn't need to initialize the monthly fee. 这样,呼叫者无需初始化月租费。 All it needs to do is 它所要做的就是

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

Note that if the monthly fee is always a constant value, you don't even need an abstract class and multiple subclasses. 请注意,如果月租费始终是一个固定值,那么您甚至不需要抽象类和多个子类。 All you need is a single class taking the monthly fee as a constructor argument. 您只需要一个将月租费作为构造函数参数的类即可。

Well yeah the idea is the same but you can improve your code. 是的,想法是一样的,但是您可以改进代码。 I will suggest an improvement according to me. 我会建议我改善一下。 I will present it with an interface and implementation not with abstract class but the idea is the same. 我将通过接口和实现(不是抽象类)来呈现它,但是想法是相同的。

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

   }
}

If you need anything else just ask for it :) i will try to help you 如果您需要其他任何东西,请要求它:)我会尽力帮助您

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM