为对象合成选择正确的模式

时间:2013-08-31 14:21:32

标签: java design-patterns refactoring uml facade

有一个名为“Bill”的班级。 比尔可以是“电力”,“食品”或“客户”,它们都是POJO。 所以它包含三个对象:

    public class Bill{
      private Electricity el1;
      private Food el2;
      private Customer el3;
      //setters and getters
      public setElectricity(...)
      ...
    }

使用一些DTO填充票据清单。 每一次,我都需要检查所有元素,以确定我有什么类型的账单。

我的目标是重构这个设计。

我也可以有一个对象并设置与类型有关的内容,但它是否有任何标准模式?

对于可以成为基于所请求类型的类的类,是否有任何模式? 我的意思是比尔将在电力,食品或客户方面与人们相关。

注意:我的应用程序更喜欢组合而不是继承       它也是一个“按合同设计”的应用程序。

  

编辑:   比尔不是它的对象的摘要。   让我们假设,食物只是颜色和收据等食物的规格!   账单在某个时间点可以是唯一的一个对象。

4 个答案:

答案 0 :(得分:2)

Bill是一个抽象实体,因此它应该是abstract类。所有其他类型的账单都应该从中扩展,例如:ElectricityBillFoodBillGasBill

答案 1 :(得分:1)

如果ElectricityBill,FoodBill,GasBill有一些共同的功能,那么将Bill创建为抽象类并从bill中扩展其他类。

如果他们有完全不同的行为和状态(我怀疑),那么创建Bill作为接口,让其他具体类实现它们。

我通常称它为简单的工厂模式(不要将它与工厂方法/抽象工厂模式混淆)

public class BillFactory
{
    Bill createBill(String type)
    {
         if(type.equals("Electricity"))
           {
            bill=new ElectricityBill();
       }
        ........


    }
}

答案 2 :(得分:1)

由于您有一个包含许多参数的大对象,其中一些参数可以是可选的。

您可以使用Builder Pattern创建Bill类的实例。

  

与抽象工厂模式和工厂方法模式不同   其目的是为了实现多态性的目的   构建器模式是找到伸缩构造函数的解决方案   反模式。伸缩构造器反模式发生时   对象构造函数参数组合的增加导致了   指数的构造函数列表。而不是使用众多   构造函数,构建器模式使用另一个对象,构建器,即   逐步接收每个初始化参数,然后返回   一次产生的构造对象。

假设您正在建房子:

public House getHouse() {
    return this.houseBuilder.getHouse();
  }

  public void constructHouse() {
    this.houseBuilder.buildBasement();
    this.houseBuilder.buildStructure();
    this.houseBuilder.bulidRoof();
    this.houseBuilder.buildInterior();
  }

来自Java Papers

的示例

答案 3 :(得分:0)

如果Bill只能包含一个实例,为什么不使用界面?

    public interface Billable {

        double getPrize();
    }

    public class Electricity implements Billable {

        @Override
        public double getPrize() {
            return 20.0;
        }
    }

    public class Bill {

        /**
         * Billable to bill.
         */
        Billable billable;
        /*
         * Discount percent applied to bill.
         */
        @Min(0)
        @Max(100)
        double discount;
        /**
         * VAT percent applied to bill.
         */
        @Min(0)
        @Max(100)
        double vat;

        public Bill(@NotNull Billable billable) {
            this.billable = billable;
            discount = 10.0;
            vat = 21.0;
        }


        public double getFinalPrize() {
            double discountFactor = 1 - discount / 100;
            double vatFactor = 1 + vat / 100;
            return billable.getPrize() * discountFactor * vatFactor;
        }

        public static void main(String[] args) {
            Electricity electricity = new Electricity();
            Bill electricityBill = new Bill(electricity);
            System.out.println(electricityBill.getFinalPrize());

        }
    }