如何合并功能相同但上下文与方法签名不同的createOrReturnFoo实现?
统一获取/创建Foo功能的接口方案
完全可以将这两个类统一到同一个接口下,核心思路是把不同的查询条件抽象为通用的查询对象,通过接口定义"获取或创建Foo"的统一行为,同时保留各自的业务实现逻辑。
实现步骤
1. 定义通用接口与抽象查询条件
首先创建一个标记接口或抽象类,用来统一不同的查询参数类型;再定义包含核心行为的接口:
// 抽象查询条件,作为不同查询参数的父类 public abstract class FooQuery {} // 统一的Foo获取/创建接口 public interface FooProvider<Q extends FooQuery> { Foo createOrReturnFoo(Q query); }
2. 针对不同业务场景实现查询条件类
为ClassA和ClassB分别创建对应的查询条件子类,封装各自的参数:
// ClassA对应的查询条件:包含选择存储的布尔值和FooID public class MapFooQuery extends FooQuery { private final boolean useAmap; private final String fooId; public MapFooQuery(boolean useAmap, String fooId) { this.useAmap = useAmap; this.fooId = fooId; } // Getter方法 public boolean isUseAmap() { return useAmap; } public String getFooId() { return fooId; } } // ClassB对应的查询条件:包含日期参数 public class DateFooQuery extends FooQuery { private final Date fooDate; public DateFooQuery(Date fooDate) { this.fooDate = fooDate; } // Getter方法 public Date getFooDate() { return fooDate; } }
3. 修改原有类实现统一接口
让ClassA和ClassB分别实现FooProvider接口,绑定对应的查询条件类型,无需修改核心业务逻辑:
public class ClassA implements FooProvider<MapFooQuery> { private HashMap<String, Foo> FooAMap = new HashMap<>(); private HashMap<String, Foo> FooBMap = new HashMap<>(); public ClassA() { FooAMap = new HashMap<>(); FooBMap = new HashMap<>(); } @Override public Foo createOrReturnFoo(MapFooQuery query) { HashMap<String, Foo> mapToUse = query.isUseAmap() ? FooAMap : FooBMap; String fooId = query.getFooId(); if (mapToUse.containsKey(fooId)) { return mapToUse.get(fooId); } else { Foo foo = new Foo("data"); mapToUse.put(fooId, foo); return foo; } } } public class ClassB implements FooProvider<DateFooQuery> { private Repository fooRepository; public ClassB() { fooRepository = new Repository(); } @Override public Foo createOrReturnFoo(DateFooQuery query) { Date fooDate = query.getFooDate(); Foo foo = fooRepository.findByDate(fooDate); if (foo != null) { return foo; } else { foo = new Foo("data"); fooRepository.save(foo); return foo; } } }
4. 统一方式调用
现在可以通过FooProvider接口统一调用两个类的功能:
// 使用ClassA的逻辑 FooProvider<MapFooQuery> providerA = new ClassA(); Foo fooFromMap = providerA.createOrReturnFoo(new MapFooQuery(true, "foo_001")); // 使用ClassB的逻辑 FooProvider<DateFooQuery> providerB = new ClassB(); Foo fooFromDb = providerB.createOrReturnFoo(new DateFooQuery(new Date()));
方案优势
- 保留了两个类各自的业务逻辑,没有强行合并无关参数
- 通过泛型绑定查询条件,编译期即可检查参数类型,避免运行时异常
- 统一了对外行为接口,符合面向接口编程的设计思想,便于后续扩展其他Foo获取/创建的实现类
内容的提问来源于stack exchange,提问作者xcffdsf
相关产品推荐
相关产品推荐

