接口多实现

有两个外呼方法(XML和JSON),现在希望将它们统一为一个入口,同时保持内部调用的灵活性。这种需求非常适合使用策略模式(Strategy Pattern)或工厂模式(Factory Pattern),具体选择取决于实现的复杂性和扩展性需求。

1. 策略模式(Strategy Pattern)
适用场景:
当您有多个算法或行为(这里是XML和JSON外呼方法),且希望在使用时动态切换它们时,策略模式是理想的选择。

实现步骤:

定义策略接口:声明外呼方法的通用行为。
实现具体策略:分别为XML和JSON外呼实现具体策略。
使用上下文类:通过上下文类选择并执行具体策略。
代码示例
java
// 1. 定义策略接口
public interface OutboundStrategy {
void outbound(String data);
}

// 2. 实现具体策略(XML)
public class XmlOutboundStrategy implements OutboundStrategy {
@Override
public void outbound(String data) {
System.out.println("XML Outbound: " + data);
// 实际XML外呼逻辑
}
}

// 3. 实现具体策略(JSON)
public class JsonOutboundStrategy implements OutboundStrategy {
@Override
public void outbound(String data) {
System.out.println("JSON Outbound: " + data);
// 实际JSON外呼逻辑
}
}

// 4. 上下文类(统一入口)
public class OutboundContext {
private OutboundStrategy strategy;

public void setStrategy(OutboundStrategy strategy) {
    this.strategy = strategy;
}

public void executeOutbound(String data) {
    if (strategy == null) {
        throw new IllegalStateException("Strategy not set");
    }
    strategy.outbound(data);
}

}

// 5. 使用示例
public class Client {
public static void main(String[] args) {
OutboundContext context = new OutboundContext();

    // 动态选择XML或JSON策略
    context.setStrategy(new XmlOutboundStrategy());
    context.executeOutbound("<data>example</data>");
    
    context.setStrategy(new JsonOutboundStrategy());
    context.executeOutbound("{\"data\":\"example\"}");
}

}
优点:

符合开闭原则(对扩展开放,对修改关闭)。
运行时动态切换策略。

2. 工厂模式(Factory Pattern)
适用场景:
如果外呼方法的创建逻辑较复杂(例如需要根据参数动态选择策略),可以使用工厂模式封装对象的创建过程。

代码示例
java
// 1. 工厂类
public class OutboundFactory {
public static OutboundStrategy getStrategy(String type) {
switch (type.toLowerCase()) {
case “xml”:
return new XmlOutboundStrategy();
case “json”:
return new JsonOutboundStrategy();
default:
throw new IllegalArgumentException("Unsupported outbound type: " + type);
}
}
}

// 2. 使用示例
public class Client {
public static void main(String[] args) {
OutboundContext context = new OutboundContext();

    // 通过工厂获取策略
    OutboundStrategy xmlStrategy = OutboundFactory.getStrategy("xml");
    context.setStrategy(xmlStrategy);
    context.executeOutbound("<data>example</data>");
}

}
优点:

封装创建逻辑,客户端无需关心具体实现。
易于扩展新的外呼类型(如未来新增YAML外呼)。

3. 结合Spring的依赖注入
在Spring中,当您需要处理接口的多个实现(例如OutboundStrategy接口的多个实现类)时,可以通过@Qualifier注解或Map注入的方式管理这些实现。以下是详细说明和示例:

场景描述
假设您有一个接口OutboundStrategy和它的两个实现类(XmlOutboundStrategy和JsonOutboundStrategy),您希望:

将这些实现类自动注入到一个Map中,键为Bean的名称(或自定义标识符)。
在运行时根据键(如"xml"或"json")动态选择对应的策略。
实现步骤

  1. 定义接口和实现类
    java
    public interface OutboundStrategy {
    void outbound(String data);
    }

@Service(“xmlStrategy”) // 显式指定Bean名称
public class XmlOutboundStrategy implements OutboundStrategy {
@Override
public void outbound(String data) {
System.out.println("XML Outbound: " + data);
}
}

@Service(“jsonStrategy”) // 显式指定Bean名称
public class JsonOutboundStrategy implements OutboundStrategy {
@Override
public void outbound(String data) {
System.out.println("JSON Outbound: " + data);
}
}
2. 使用Map注入所有实现
Spring会自动将所有OutboundStrategy的实现类注入到一个Map中,键为Bean的名称(即@Service中指定的名称)。

java
@Service
public class OutboundContext {
// Map的Key为Bean名称(如"xmlStrategy"、“jsonStrategy”)
@Autowired
private Map<String, OutboundStrategy> strategies;

public void executeOutbound(String strategyName, String data) {
    OutboundStrategy strategy = strategies.get(strategyName);
    if (strategy == null) {
        throw new IllegalArgumentException("Unsupported strategy: " + strategyName);
    }
    strategy.outbound(data);
}

}
3. 调用示例
java
@RestController
public class OutboundController {
@Autowired
private OutboundContext outboundContext;

@PostMapping("/outbound")
public void triggerOutbound(@RequestParam String type, @RequestBody String data) {
    outboundContext.executeOutbound(type + "Strategy", data); // 拼接Bean名称后缀
}

}
关键点说明
Bean名称控制:
通过@Service(“customName”)显式指定Bean名称,确保Map的键可预测。
如果不指定名称,Spring默认使用类名首字母小写作为键(如xmlOutboundStrategy)。
动态选择策略:
通过strategies.get(strategyName)直接获取对应实现。
调用方只需传入策略名称(如"xmlStrategy"或"jsonStrategy")。
扩展性:
新增策略时,只需添加新的实现类并指定@Service名称,无需修改现有代码。
替代方案:使用@Qualifier
如果不想用Map,可以通过@Qualifier明确指定注入的Bean:

java
@Service
public class OutboundContext {
@Autowired
@Qualifier(“xmlStrategy”)
private OutboundStrategy xmlStrategy;

@Autowired
@Qualifier("jsonStrategy")
private OutboundStrategy jsonStrategy;

public void executeOutbound(String type, String data) {
    if ("xml".equals(type)) {
        xmlStrategy.outbound(data);
    } else if ("json".equals(type)) {
        jsonStrategy.outbound(data);
    } else {
        throw new IllegalArgumentException("Unsupported type: " + type);
    }
}

}
总结
Map注入:适合策略数量较多或需要动态扩展的场景,代码更简洁。
@Qualifier:适合策略数量固定且逻辑简单的场景,类型安全但扩展性稍弱。
根据项目需求选择合适的方式。在Spring Boot/Spring项目中,Map注入是更灵活和推荐的做法。

总结
简单场景:直接使用策略模式,通过setStrategy动态切换。
复杂创建逻辑:结合工厂模式封装策略的创建。
Spring项目:利用依赖注入和@Qualifier实现更简洁的解耦。
最终选择取决于项目的复杂性和团队习惯。策略模式是最直接的解决方案,而工厂模式或Spring集成则更适合需要灵活扩展的场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值