工厂与复合或抽象工厂

时间:2017-06-05 20:36:13

标签: java

我有以下类层次结构:



public interface RateSheetProductExtractor
{
  List<ProductData> extract(SGQuotingData quotingData);
}


@Service
@Scope("requestjob")
public class ProductExtractorFactory
{
  @Autowired
  private OptionalRatingProductExtractorFactory optionalRatingProductExtractorFactory;
  @Autowired
  private QuotePlanProductExtractorFactory quotePlanProductExtractorFactory;
  @Autowired
  private AlternateProductExtractorFactory alternateProductExtractorFactory;

  public RateSheetProductExtractor getProductExtractor(
    TablePlanType tablePlanType,
    TableRatingType ratingType)
  {
    switch (tablePlanType)
    {
      case QUOTED:
        return quotePlanProductExtractorFactory.getInstance(ratingType);
      case OPTIONAL:
        return optionalRatingProductExtractorFactory.getInstance(ratingType);
      case ALTERNATE:
        return alternateProductExtractorFactory.getInstance(ratingType);
      default:
        throw new IllegalArgumentException(tablePlanType + " is unsupported yet.");
    }
  }
}

@Service
@Scope("requestjob")
public class OptionalRatingProductExtractorFactory
{
  @Autowired
  private AcaProductExtractor acaProductExtractor;
  @Autowired
  private AgeRatedAsCompositeProductExtractor ageRatedAsCompositeProductExtractor;

  public RateSheetProductExtractor getInstance(TableRatingType ratingType)
  {
    switch (ratingType)
    {
      case AGE:
        return ageRatedAsCompositeProductExtractor;
      case COMPOSITE:
        return acaProductExtractor;
      default:
        throw new IllegalArgumentException(
          "Product extractor isn't defined for optional plan type and rating type " + ratingType);

    }
  }
}


@Service
@Scope("requestjob")
public class QuotePlanProductExtractorFactory
{
  @Autowired
  private GfProductExtractor gfExtractor;
  @Autowired
  private AgeRatedProductExtractor ageRatedProductExtractor;
  @Autowired
  private MedicalProductExtractor medicalProductExtractor;

  public RateSheetProductExtractor getInstance(TableRatingType ratingType)
  {
    switch (ratingType)
    {
      case AGE:
        return ageRatedProductExtractor;
      case COMPOSITE_AGE:
        return gfExtractor;
      case COMPOSITE:
        return medicalProductExtractor;
      default:
        throw new IllegalArgumentException(
          ratingType + " is unsupported for QuotePlan product extractor factory.");
    }
  }
}


@Service
@Scope("requestjob")
public class AlternateProductExtractorFactory
{
  @Autowired
  private AlternateAgeRatedProductExtractor ageRatedProductExtractor;

  public RateSheetProductExtractor getInstance(TableRatingType ratingType)
  {
    if (ratingType == AGE)
    {
      return ageRatedProductExtractor;
    }
    throw new IllegalArgumentException(
      ratingType + " is unsupported for QuotePlan product extractor factory.");
  }
}
&#13;
&#13;
&#13; 将ProductExtractorFactory称为AbstractProductExtractorFactory(基于适当的模式)是否正确?或者它更像是一个简单的工厂?

对不起巨大的上市......:)

2 个答案:

答案 0 :(得分:1)

我不这么认为。

1)ProductExtractorFactory是一个具体的类,在Java中,甚至在AbstractFactory模式中,以Abstract开头的类应该是一个抽象类。

2)在抽象工厂中,每个工厂都应该有一个RateSheetProductExtractor的具体子类型,但在代码示例中我看不到它们。

3)你的例子更像是工厂和复合模式。

重构使用复合材料:

定义公共工厂界面:

public interface RateSheetProductExtractorFactory{

    public RateSheetProductExtractor getProductExtractor(TablePlanType tablePlanType, TableRatingType ratingType);
}

定义复合类:

public class CompositeRateSheetProductExtractorFactory implements RateSheetProductExtractorFactory{
    private Map<String, RateSheetProductExtractorFactory> factoryMap = null;

    public void setFactoryMap(Map<String, RateSheetProductExtractorFactory> factoryMap){
        this.factoryMap = factoryMap;
    }

    @Override
    public RateSheetProductExtractor getProductExtractor(TablePlanType tablePlanType, TableRatingType ratingType){
        RateSheetProductExtractorFactory factory = factoryMap.get( tablePlanType + "-" + ratingType );

        if (factory == null) throw new IllegalArgumentException( tablePlanType + "-" + ratingType + " is unsupported yet.");

        return factory.getProductExtractor(tablePlanType, ratingType);
    }        
}

实现每个提取器及其各个工厂:

public class AcaProductExtractorFactory implements RateSheetProductExtractorFactory{

    @Override
    public RateSheetProductExtractor getProductExtractor(TablePlanType tablePlanType, TableRatingType ratingType){
        return new AcaProductExtractor();
    }
}

public class AcaProductExtractor implements RateSheetProductExtractor{

    @Override
    public List<ProductData> extract(SGQuotingData quotingData) {
        return null;
    }        
}



public class AgeRatedAsCompositeProductExtractorFactory implements RateSheetProductExtractorFactory{

    @Override
    public RateSheetProductExtractor getProductExtractor(TablePlanType tablePlanType, TableRatingType ratingType){
        return new AgeRatedAsCompositeProductExtractor();
    }
}

public class AgeRatedAsCompositeProductExtractor implements RateSheetProductExtractor{

    @Override
    public List<ProductData> extract(SGQuotingData quotingData) {
        return null;
    }        
}



public class MedicalProductExtractorFactory implements RateSheetProductExtractorFactory{

    @Override
    public RateSheetProductExtractor getProductExtractor(TablePlanType tablePlanType, TableRatingType ratingType){
        return new MedicalProductExtractor();
    }
}

public class MedicalProductExtractor implements RateSheetProductExtractor{
    @Override
    public List<ProductData> extract(SGQuotingData quotingData) {
        return null;
    }       
}

Spring XML:

<bean id="ageRatedAsCompositeProductExtractorFactory" class="AgeRatedAsCompositeProductExtractorFactory"/>
<bean id="medicalProductExtractorFactory" class="MedicalProductExtractorFactory"/>
<bean id="acaProductExtractorFactory" class="AcaProductExtractorFactory"/>

<bean id="extractorFactory" class="CompositeRateSheetProductExtractorFactory">
    <property name="factoryMap">
        <map>
            <entry key="QUOTED-AGE" value-ref="ageRatedAsCompositeProductExtractorFactory" />
            <entry key="QUOTED-COMPOSITE" value-ref="medicalProductExtractorFactory" />
            <entry key="ALTERNATE-AGE" value-ref="ageRatedAsCompositeProductExtractorFactory" />
            <entry key="OPTIONAL-COMPOSITE" value-ref="acaProductExtractorFactory" />
        </map>
    </property>
</bean>

答案 1 :(得分:0)

我的两分钱是保持名称不变。我不确定你的工作场所,但在我之前的组织中,我们曾经将类名保持为Abstract SomeClass ,如果它是一个抽象类,并且具体类必须实现其方法。如果您也检查Java Collections API,那么所有以 Abstract 开头的类都与此概念有关,而不是与设计模式有关。