有一个名为“Bill”的班级。 比尔可以是“电力”,“食品”或“客户”,它们都是POJO。 所以它包含三个对象:
public class Bill{
private Electricity el1;
private Food el2;
private Customer el3;
//setters and getters
public setElectricity(...)
...
}
使用一些DTO填充票据清单。 每一次,我都需要检查所有元素,以确定我有什么类型的账单。
我的目标是重构这个设计。
我也可以有一个对象并设置与类型有关的内容,但它是否有任何标准模式?
对于可以成为基于所请求类型的类的类,是否有任何模式? 我的意思是比尔将在电力,食品或客户方面与人们相关。
注意:我的应用程序更喜欢组合而不是继承 它也是一个“按合同设计”的应用程序。
编辑: 比尔不是它的对象的摘要。 让我们假设,食物只是颜色和收据等食物的规格! 账单在某个时间点可以是唯一的一个对象。
答案 0 :(得分:2)
Bill是一个抽象实体,因此它应该是abstract
类。所有其他类型的账单都应该从中扩展,例如:ElectricityBill
,FoodBill
,GasBill
等
答案 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();
}
的示例
答案 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());
}
}