我必须根据某些标准为各种特许经营实施不同的收费结构。我为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模式方法的正确方法吗?请告诉我,如果我错了或有任何改善的建议。
答案 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();
}
}
}
如果您还需要其他任何东西请求它:)我会尽力帮助您