Replacing if‑else with Strategy Pattern and Map‑Lambda in Java
This article demonstrates how to refactor coupon‑type dispatch logic by using the Strategy design pattern and a Map of Java 8 lambda expressions, showing code examples, trade‑offs, and a concise implementation that improves readability and maintainability.
Requirement
Service must return the grant type (distribution method) and claim rules for a coupon. Input fields: resourceType (coupon category) and resourceId (coupon identifier). Each resourceType maps to a different database table (e.g., red‑packet, shopping voucher, QQ membership, food‑delivery membership).
Problems with a naïve if‑else / switch
switch (resourceType) {
case "红包":
// query red‑packet grant type
break;
case "购物券":
// query shopping voucher grant type
break;
case "QQ会员":
// query QQ membership grant type
break;
case "外卖会员":
// query food‑delivery membership grant type
break;
default:
logger.info("Cannot find grant type for resourceType");
break;
}When each branch contains dozens of lines (database access, business validation, formatting), the method becomes long, hard to read and difficult to modify.
Strategy pattern
The Strategy pattern extracts each branch into a concrete class that implements a common interface. The client selects the appropriate strategy at runtime, so changes affect only the corresponding class.
Drawback: many small classes increase the code base and make it harder to see the overall dispatch logic.
Map + Java 8 functional interface
Store a Function<String,String> for each coupon type in a Map<String,Function<String,String>>. The map key is the resourceType; the value is a lambda that receives resourceId and returns the grant type.
@Service
public class QueryGrantTypeService {
@Autowired
private GrantTypeService grantTypeService;
private final Map<String, Function<String,String>> grantTypeMap = new HashMap<>();
/** Initialise the dispatch map – replaces the if‑else block */
@PostConstruct
public void init() {
grantTypeMap.put("红包", id -> grantTypeService.redPaper(id));
grantTypeMap.put("购物券", id -> grantTypeService.shopping(id));
grantTypeMap.put("QQ会员", id -> grantTypeService.qqVip(id));
grantTypeMap.put("外卖会员", id -> grantTypeService.takeaway(id));
}
public String getGrantType(String resourceType, String resourceId) {
Function<String,String> fn = grantTypeMap.get(resourceType);
if (fn != null) {
return fn.apply(resourceId);
}
return "查询不到该优惠券的发放方式";
}
}The concrete business logic can be isolated in a separate service:
@Service
public class GrantTypeService {
public String redPaper(String resourceId) {
// Example: query red‑packet table by resourceId
return "每周末9点发放";
}
public String shopping(String resourceId) {
// Example: query shopping voucher table
return "每周三9点发放";
}
public String qqVip(String resourceId) {
// Example: query QQ membership table
return "每周一0点开始秒杀";
}
public String takeaway(String resourceId) {
// Example: query food‑delivery membership table
return "每日中午12点发放";
}
}Expose the service through a REST endpoint:
@RestController
public class GrantTypeController {
@Autowired
private QueryGrantTypeService queryGrantTypeService;
@PostMapping("/grantType")
public String getGrantType(@RequestParam String resourceType,
@RequestParam String resourceId) {
return queryGrantTypeService.getGrantType(resourceType, resourceId);
}
}Pros and cons
Map + lambda provides a compact, visual mapping between coupon types and actions, avoiding a proliferation of classes.
Team members must be comfortable with Java 8 lambda syntax.
The Strategy pattern offers clearer separation when each branch contains extensive logic, but it can lead to many small classes.
Both approaches eliminate the long, hard‑to‑maintain if‑else chain.
Conclusion
Use the Strategy pattern when each coupon type requires substantial, independent processing and you prefer strict separation of concerns. Use the Map‑lambda approach for lighter‑weight dispatch logic, where the main goal is to keep the codebase small and the mapping easy to read. Choose the technique that matches the complexity of the business rules and the team's familiarity with functional programming.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
