下列为初始代码:
package org.example;
public class GodShop {
private final String WATER = "water";
private final String PEN = "pen";
private final String HAT = "hat";
private String name;
private int days;
private int quality;
public GodShop(String name, int days, int quality) {
this.name = name;
this.days = days;
this.quality = quality;
}
private void handleWater() {
this.quality++;
}
private void handlePen() {
System.out.println("pen");
}
private void handleHat() {
this.quality = Math.max(this.quality++, 5);
}
public void parse() {
this.days--;
switch (this.name) {
case WATER:
handleWater();
break;
case PEN:
handlePen();
break;
case HAT:
handleHat();
break;
default:
this.quality++;
break;
}
}
public static void main(String[] args) {
GodShop godShop = new GodShop("南瓜", 5, 10);
}
}
使用枚举类型优化
package org.example;
import java.util.HashMap;
import java.util.Map;
public class GodShop {
private static final Map<Goods, GoodsHandler> HANDLERS = new HashMap<>();
static {
HANDLERS.put(Goods.WATER, new GoodsHandler() {
@Override
public void handle(GodShop shop) {
shop.quality++;
}
});
HANDLERS.put(Goods.PEN, new GoodsHandler() {
@Override
public void handle(GodShop shop) {
System.out.println("pen");
}
});
HANDLERS.put(Goods.HAT, new GoodsHandler() {
@Override
public void handle(GodShop shop) {
shop.quality = Math.max(shop.quality++, 5);
}
});
HANDLERS.put(Goods.BOOK, new GoodsHandler() {
@Override
public void handle(GodShop shop) {
System.out.println("Handling book...");
shop.quality += 2;
}
});
}
public enum Goods {
WATER, PEN, HAT, BOOK
}
interface GoodsHandler {
void handle(GodShop shop);
}
private String name;
private int days;
private int quality;
public GodShop(String name, int days, int quality) {
this.name = name;
this.days = days;
this.quality = quality;
}
public void parse() {
this.days--;
try {
Goods goods = Goods.valueOf(name.toUpperCase());
GoodsHandler handler = HANDLERS.getOrDefault(goods, new GoodsHandler() {
@Override
public void handle(GodShop shop) {
shop.quality++;
}
});
handler.handle(this);
} catch (IllegalArgumentException e) {
System.err.println("Invalid goods name: " + name);
quality++; // 默认增加质量
}
}
public static void main(String[] args) {
GodShop godShop = new GodShop("invalid", 5, 10);
godShop.parse();
System.out.println("Quality after handling: " + godShop.quality);
}
}
- 枚举类型:
- 定义了一个枚举
Goods来替代字符串"water","pen","hat"。这使得代码更具类型安全性,也更容易维护。
- 定义了一个枚举
- 处理器接口:
- 创建了一个
GoodsHandler接口,定义了一个handle方法来处理不同的商品。
- 创建了一个
- 映射处理器:
- 使用
HashMap来存储每个商品对应的处理器。这样可以轻松地添加新的商品及其处理逻辑。
- 使用
parse方法:- 重构了
parse方法,使用valueOf方法将商品名称转换为枚举类型。 - 从
HANDLERS映射中查找相应的处理器,并调用handle方法。
- 重构了
- 默认处理器:
- 如果找不到特定的商品处理器,则使用一个默认处理器,该处理器简单地增加商品的质量。
- 拓展性:
- 如果需要添加新的商品,只需要在
Goods枚举中添加新的条目,并在HANDLERS映射中添加相应的处理器即可。
- 如果需要添加新的商品,只需要在
优点
- 降低圈复杂度:通过将逻辑分散到不同的处理器中,减少了
parse方法中的条件分支。 - 提高可读性和可维护性:枚举和处理器的使用使得代码更加清晰易懂。
- 易于拓展:添加新的商品只需要修改很少的代码。
这样的重构不仅提高了代码的质量,而且使得未来的维护和扩展变得更加容易。
使用策略模式
package org.example;
import java.util.HashMap;
import java.util.Map;
public class GodShop {
private final String name;
private int days;
public int quality;
public GodShop(String name, int days, int quality) {
this.name = name;
this.days = days;
this.quality = quality;
}
public void parse() {
this.days--;
try {
GoodsStrategy strategy = getStrategyForName(name);
if (strategy != null) {
strategy.execute(this);
} else {
quality++; // 默认情况下,增加质量
}
} catch (Exception e) {
System.err.println("Error while parsing the name: " + name);
}
}
private GoodsStrategy getStrategyForName(String name) {
return STRATEGIES.getOrDefault(name.toUpperCase(), null);
}
private static final Map<String, GoodsStrategy> STRATEGIES = new HashMap<>();
static {
STRATEGIES.put("WATER", new WaterStrategy());
STRATEGIES.put("PEN", new PenStrategy());
STRATEGIES.put("HAT", new HatStrategy());
STRATEGIES.put("BOOK", new BookStrategy());
}
public static void main(String[] args) {
GodShop godShop = new GodShop("WATER", 5, 10);
godShop.parse();
System.out.println("Quality after handling: " + godShop.quality);
}
}
interface GoodsStrategy {
void execute(GodShop shop);
}
class WaterStrategy implements GoodsStrategy {
@Override
public void execute(GodShop shop) {
shop.quality++;
}
}
class PenStrategy implements GoodsStrategy {
@Override
public void execute(GodShop shop) {
System.out.println("pen");
}
}
class HatStrategy implements GoodsStrategy {
@Override
public void execute(GodShop shop) {
shop.quality = Math.max(shop.quality++, 5);
}
}
class BookStrategy implements GoodsStrategy {
@Override
public void execute(GodShop shop) {
System.out.println("Handling book...");
shop.quality += 2;
}
}
** 代码解析**
- 策略接口 (
GoodsStrategy):- 定义了一个
execute方法,用于执行特定商品的策略。
- 定义了一个
- 具体策略类 (
WaterStrategy,PenStrategy,HatStrategy,BookStrategy):- 每个类都实现了
GoodsStrategy接口,并提供了不同的execute方法实现。
- 每个类都实现了
- 策略映射 (
STRATEGIES):- 使用
HashMap来存储每个商品名称与其对应的策略对象。 - 在静态初始化块中填充这个映射。
- 使用
parse方法:- 获取商品名称对应的策略对象。
- 调用策略对象的
execute方法来执行具体的策略。
- 拓展性:
- 如果需要添加新的商品,只需要创建一个新的策略类,并在
STRATEGIES映射中添加相应的条目即可。 优点
- 如果需要添加新的商品,只需要创建一个新的策略类,并在
- 降低圈复杂度:通过将不同的策略分离到独立的类中,减少了
parse方法中的条件分支。 - 提高可读性和可维护性:每个策略类只关注一种商品的处理逻辑,使得代码更加清晰。
- 易于拓展:添加新的商品只需要定义新的策略类,并在
STRATEGIES映射中添加条目即可。 这样的重构不仅提高了代码的质量,而且使得未来的维护和扩展变得更加容易。