public class TaxPayer {
public static final int COMPANY = 0;
public static final int EMPLOYEE = 1;
public static final int TRUST = 2;
private static final double COMPANY_RATE = 0.30;
private static final double EMPLOYEE_RATE = 0.45;
private static final double TRUST_RATE = 0.35;
private double income;
private final int type;
public TaxPayer(int type, double income) {
this.type = type;
this.income = income;
}
public double getIncome() {
return income;
}
public double extortCash() {
switch (type) {
case COMPANY: return income * COMPANY_RATE;
case EMPLOYEE: return income * EMPLOYEE_RATE;
case TRUST: return income * TRUST_RATE;
default: throw new IllegalArgumentException();
}
}
}
public class ReceiverOfRevenue {
public static void main(String[] args) {
TaxPayer heinz = new TaxPayer(TaxPayer.EMPLOYEE, 50000);
TaxPayer maxsol = new TaxPayer(TaxPayer.COMPANY, 100000);
TaxPayer family = new TaxPayer(TaxPayer.TRUST, 30000);
System.out.println(heinz.extortCash());
System.out.println(maxsol.extortCash());
System.out.println(family.extortCash());
}
}
switch语句的话,当你引入一种新的纳税类型的话,你将不得不更新每一个switch语句。一旦我使用这种方法写了一个case公举的话,当我增加一个新的结构,我将不得不更改五种不同的switch语句来适应这种改变。如果我忘记输入switch语句的话,那么新的结构也将没有得到输入。
public interface TaxStrategy {
public double extortCash(double income);
}
public class CompanyTaxStrategy implements TaxStrategy {
private static final double RATE = 0.30;
public double extortCash(double income) {
return income * RATE ;
}
}
public class EmployeeTaxStrategy implements TaxStrategy {
private static final double RATE = 0.45;
public double extortCash(double income) {
return income * RATE;
}
}
public class TrustTaxStrategy implements TaxStrategy {
private static final double RATE = 0.40;
public double extortCash(double income) {
return income * RATE;
}
}
public class TaxPayer {
public static final TaxStrategy EMPLOYEE =
new EmployeeTaxStrategy();
public static final TaxStrategy COMPANY =
new CompanyTaxStrategy();
public static final TaxStrategy TRUST =
new TrustTaxStrategy();
private final TaxStrategy strategy;
private final double income;
public TaxPayer(TaxStrategy strategy, double income) {
this.strategy = strategy;
this.income = income;
}
public double getIncome() {
return income;
}
public double extortCash() {
return strategy.extortCash(income);
}
}
public interface TaxStrategy {
public double extortCash(TaxPayer p);
}
public class TaxPayer {
// the rest of the class is the same
public double extortCash() {
return strategy.extortCash(this);
}
}
public class Employee extends TaxPayer {
public enum Gender { MALE, FEMALE };
private final boolean married;
private final Gender gender;
public Employee(TaxStrategy strategy, double income,
boolean married, Gender gender) {
super(strategy, income);
this.married = married;
this.gender = gender;
}
public boolean isMarried() {
return married;
}
public Gender getGender() {
return gender;
}
}
instanceof检测它是否为Employee的实例。但是如果不是的话,我们会做什么呢?
public class EmployeeTaxStrategy implements TaxStrategy {
private static final double NORMAL_RATE = 0.40;
private static final double MARRIED_FEMALE_RATE = 0.48;
public double extortCash(TaxPayer p) {
Employee e = (Employee) p; // here we need to downcast!!!
if (e.isMarried() &&
e.getGender() == Employee.Gender.FEMALE) {
return e.getIncome() * MARRIED_FEMALE_RATE;
}
return e.getIncome() * NORMAL_RATE;
}
}
”这样符号斗争,那么你会发现我们的
Java 5 Delta Course课程是有用的,在这个课程的第三章,我们特别讲到了泛型。
public interface TaxStrategyextends TaxPayer> {
public double extortCash(P p);
}
public class CompanyTaxStrategy implements TaxStrategy {
private static final double BIG_COMPANY_RATE = 0.30;
private static final double SMALL_COMPANY_RATE = 0.15;
public double extortCash(Company company) {
if (company.getNumberOfEmployees() > 5
&& company.getIncome() < 1000000) {
return company.getIncome() * SMALL_COMPANY_RATE;
}
return company.getIncome() * BIG_COMPANY_RATE;
}
}
class
TaxPayerextends TaxPayer
>看起来有点古怪,并且好像是一个习惯用法。它和让Ken Arnold困惑的Enum
extends Enum
>
相类似。经过考虑,我认为Enum
extends Enum
>
有充分的理由。然而,就像Philip Wadler指出的那样,既然Enum是一个泛型类,我们应该仅仅使用它来关联一个类型,(而不是一个泛型类)。将来,Java将会变得更加严格,那些夹生的类型将变得非法。因而我们必须选择是写Enum
extends Enum
>
还是
extends Enum
>
,它们中间第一个选择要正确些。即使编译器现在还不能显示它们之间的差别,不久的将来,可能会看到警告信息,所以我在我的代码中遵从了上面的结论。
getDetailedType()的工厂方法返回子类来解决这个问题。
public abstract class TaxPayerextends TaxPayer
> {
public static final TaxStrategy
EMPLOYEE =
new EmployeeTaxStrategy();
public static final TaxStrategy
COMPANY =
new CompanyTaxStrategy();
public static final TaxStrategy
TRUST =
new TrustTaxStrategy();
private double income;
private TaxStrategystrategy;
public TaxPayer(TaxStrategystrategy, double income) {
this.strategy = strategy;
this.income = income;
}
protected abstract P getDetailedType();
public double getIncome() {
return income;
}
public double extortCash() {
return strategy.extortCash(getDetailedType());
}
}
public class Employee extends TaxPayer {
public enum Gender { MALE, FEMALE };
private final boolean married;
private final Gender gender;
public Employee(TaxStrategy strategy, double income,
boolean married, Gender gender) {
super(strategy, income);
this.married = married;
this.gender = gender;
}
protected Employee getDetailedType() {
return this;
}
public boolean isMarried() {
return married;
}
public Gender getGender() {
return gender;
}
}
public class EmployeeTaxStrategy implements TaxStrategy {
private static final double NORMAL_RATE = 0.40;
private static final double MARRIED_FEMALE_RATE = 0.48;
public double extortCash(Employee e) {
if (e.isMarried() &&
e.getGender() == Employee.Gender.FEMALE) {
return e.getIncome() * MARRIED_FEMALE_RATE;
}
return e.getIncome() * NORMAL_RATE;
}
}
2106

被折叠的 条评论
为什么被折叠?



