0

有一个名为“Bill”的类。Bill 可以是“Electricity”、“Food”或“Customer”,它们都是 POJO。所以它包含三个对象:

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

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

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

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

对于可以成为基于请求类型的类的类是否有任何模式?我的意思是,就人口增长时间而言,比尔将成为电力、食品或客户。

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

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

4

4 回答 4

2

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

于 2013-08-31T14:22:37.617 回答
1

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

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

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

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


    }
}
于 2013-08-31T14:30:35.610 回答
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 论文中的示例

于 2013-08-31T14:44:05.757 回答
0

如果比尔只能包含一个实例,为什么不使用接口?

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

        }
    }
于 2013-08-31T23:30:03.733 回答