Java 用多态性替换条件
我试图通过一个例子来理解这个干净的代码实践。考虑具有折扣情况的类产品。我试图用多态性替换switch语句 代码之前:Java 用多态性替换条件,java,design-patterns,polymorphism,Java,Design Patterns,Polymorphism,我试图通过一个例子来理解这个干净的代码实践。考虑具有折扣情况的类产品。我试图用多态性替换switch语句 代码之前: class Product { String priceCode; int discount; Product(String priceCode) { setDiscount(priceCode); } public int getDiscount() { return discount; }
class Product {
String priceCode;
int discount;
Product(String priceCode) {
setDiscount(priceCode);
}
public int getDiscount() {
return discount;
}
public void setDiscount(String priceCode) {
switch (priceCode) {
case "CODE1":
discount = // some logic;
case "CODE2":
discount = // some other logic;
case "CODE3":
discount = // some other logic;
}
}
}
在下面的代码中,您可以看到我删除了switch语句,但我仍然有if条件来创建discountStrategy的对象。
我的问题是,我仍然有我试图用多态性消除的if条件
代码后:
class Product {
String priceCode;
DiscountStrategy discountStrategy;
Product(String priceCode) {
setDiscount(priceCode);
}
public int getDiscount() {
return discountStrategy.getDiscount();
}
public void setDiscount(String priceCode) {
if (priceCode.equals("CODE1")) {
discountStrategy = new DiscountStrategy1();
} else if (priceCode.equals("CODE2")) {
discountStrategy = new DiscountStrategy2();
}
// ...
}
}
interface DiscountStrategy {
public int getDiscount();
}
class DiscountStrategy1 implements DiscountStrategy {
public int getDiscount() {
// calculate & return discount;
}
}
class DiscountStrategy2 implements DiscountStrategy {
public int getDiscount() {
// calculate & return discount;
}
}
class DiscountStrategy3 implements DiscountStrategy {
public int getDiscount() {
// calculate & return discount;
}
}
您能帮助我更好地实现这个示例,从而理解这个概念吗?我的两分钱:
您需要将参数传递给discount()
方法
a。创建一个静态类级别折扣策略
。
例如:
b。无论您需要什么,您都可以简单地使用:
map.get(priceCode).discount()
这是你需要做的
class Product {
String priceCode;
DiscountStrategy discountStrategy;
HashMap<String, DiscountStrategy> map=new HashMap();
Product(String priceCode) {
map.put("CODE1", new DiscountStrategy1());
map.put("CODE2", new DiscountStrategy2());
map.put("CODE3", new DiscountStrategy3());
setDiscount(priceCode);
}
public void setDiscount(String priceCode){
discountStrategy=map.get(priceCode);
}
public int getDiscount() {
return discountStrategy.getDiscount();
}
}
类产品{
字符串价格码;
折扣策略折扣策略;
HashMap=newHashMap();
产品(字符串价格代码){
map.put(“代码1”,新的折扣策略1());
map.put(“代码2”,新的折扣策略2());
map.put(“代码3”,新的折扣策略3());
设置折扣(价格代码);
}
公共无效设置折扣(字符串价格代码){
折扣策略=map.get(priceCode);
}
公共int getDiscount(){
return discountStrategy.getDiscount();
}
}
我认为Product类不能知道折扣创建过程,它应该只使用折扣。因此,我的建议是创建一个带有地图的折扣工厂,该地图将包含不同的折扣实施:
class DiscountFactory {
private static final Map<String, DiscountStrategy> strategies = new HashMap<>();
private static final DiscountStrategy DEFAULT_STRATEGY = () -> 0;
static {
strategies.put("code1", () -> 10);
strategies.put("code2", () -> 20);
}
public DiscountStrategy getDiscountStrategy(String priceCode) {
if (!strategies.containsKey(priceCode)) {
return DEFAULT_STRATEGY;
}
return strategies.get(priceCode);
}
}
功能接口将允许您使用lambda表达式创建不同的实现:
interface DiscountStrategy {
int getDiscount();
}
最后,产品与折扣一起使用的示例:
DiscountFactory factory = new DiscountFactory();
Product product = new Product(factory.getDiscountStrategy("code1"));
class QuantityRateDiscount implements DiscountStrategy {
static class QuantityRate {
final int minQuantity;
final double rate; // in %
QuantityRate(int minQuantity, double rate) {
this.minQuantity = minQuantity;
this.rate = rate;
}
}
QuantityRate[] rateTable;
// rateTable must be sorted by ascending minQuantity
QuantityRateDiscount(QuantityRate... rateTable) {
this.rateTable = rateRable.clone();
}
@Override
public double calculate(int quantity, Product product) {
QuantityRate qr = null;
for (QuantityRate qr2: rateTable) {
if (qr2.minQuantity > quantity) {
break;
}
qr = qr2;
}
if (qr != null) {
return product.getBasePrice()*qr.rate/100.0;
} else {
return 0;
}
}
}
在您的示例中,当折扣策略绑定到特定的产品类型时,我将在订单项级别计算折扣。 例如:
class Product {
double basePrice;
DiscountStrategy discountStrategy;
...
public double getBasePrice() {
return basePrice;
}
public DiscountStrategy getDiscountStrategy() {
return discountStrategy;
}
}
interface DiscountStrategy {
public double calculate(int quantity, Product product);
}
class OrderItem {
int quantity;
Product product;
public double getAmount() {
DiscountStrategy ds = product.getDiscountStrategy();
double discount = ds.calculate(quantity, product);
return quantity*(product.getBasePrice() - discount);
}
}
折扣策略示例:数量折扣:
DiscountFactory factory = new DiscountFactory();
Product product = new Product(factory.getDiscountStrategy("code1"));
class QuantityRateDiscount implements DiscountStrategy {
static class QuantityRate {
final int minQuantity;
final double rate; // in %
QuantityRate(int minQuantity, double rate) {
this.minQuantity = minQuantity;
this.rate = rate;
}
}
QuantityRate[] rateTable;
// rateTable must be sorted by ascending minQuantity
QuantityRateDiscount(QuantityRate... rateTable) {
this.rateTable = rateRable.clone();
}
@Override
public double calculate(int quantity, Product product) {
QuantityRate qr = null;
for (QuantityRate qr2: rateTable) {
if (qr2.minQuantity > quantity) {
break;
}
qr = qr2;
}
if (qr != null) {
return product.getBasePrice()*qr.rate/100.0;
} else {
return 0;
}
}
}
这种情况下的折扣是多少?为什么它是int?请看这篇文章,它解决了条件的问题,使用工厂模式和
映射来解析要创建的类型。提到的每个解决方案几乎都使用相同的技术。如果条件语句基于对象的类型
,那么直接用多态性替换switch语句是可行的,您只需使用接口的类型
就可以解决这个问题。看这个例子