我最近正在开发一个代码库,该代码库在整个代码中使用了大量的instanceof检查,我想知道是否有更好的方法来重构它。
作为一个例子,有一个 AbstractTender 类,它有几个子类,CreditDebitTender、CheckTender、GiftCardTender、StoreCreditTender 等。每个类都添加了几个字段、方法和自己的逻辑。这导致对整个代码进行检查,如下所示。
考虑到父类(super class)和子类 IE 在某些情况下存在更多且非常不同的字段/方法之间存在显着差异,是否有更好的方法来避免整个代码库中的所有 instanceof 检查?正如示例 maskedCardNumber 和 authCode 仅特定于贷记借记投标,而 micr 仅特定于支票投标。
if (tender instanceof CreditDebitTenderIfc) {
// insert tender into credit debit tender table
}
if (tender instanceof CheckTenderIfc) {
// insert tender into check tender table
}
if (tender instance of GiftCardTenderIfc) {
// inser tender into gift card tender table
}
// etc
仅供引用:这是一个非常古老的代码库,原始产品已经有 10 多年的历史了。
最佳答案
我可以考虑两种方法:
在
AbstractTender
中定义一个抽象方法叫save
。每个子类都必须实现如何将信息存储在数据库中。如果
AbstractTender
子类是实体类,不能有存储库逻辑,如果您使用Java 8,则可以使用Map<Class, Consumer<AbstractTender>>
其中map的每个值重点关注如何存储AbstractTender
的实例。您可以使用实例的类来查找特定元素。简单示例:
Map<Class, Consumer<AbstractTender>> mapTenderStoreFunc = new HashMap<>(); mapTenderStoreFunc.put(CreditDebitTenderIfc.class, tender -> { CreditDebitTenderIfc cdTender = (CreditDebitTenderIfc)tender; //logic goes here... }); mapTenderStoreFunc.put(CheckTenderIfc.class, tender -> { CheckTenderIfccdTender ctifc = (CheckTenderIfc)tender; //logic goes here... }); //and on...
然后你的
save
方法将像这样使用 map :public void save(AbstractTender tender) { Consumer<AbstractTender> saveOperation = mapTenderStoreFunc.get(tender.getClass()); if (saveOperation != null) { saveOperation.accept(tender); } else { //maybe throw an exception //or log a warning, error or something to notice! } }
这种方法的缺点是,如果团队中有人忘记为子类添加正确的映射,那么您就会遇到麻烦。
与 2 类似的方法,但如果您使用 Java 7 或更早版本,而不是
Consumer<AbstractTender>
您可以定义自己的接口(interface)并用匿名类填充它:interface TenderRepository { void save(AbstractTender tender); } Map<Class, TenderRepository> map = new HashMap<>(); map.put(CreditDebitTenderIfc.class, new TenderRepository() { @Override public void save(AbstractTender tender) { CreditDebitTenderIfc cdTender = (CreditDebitTenderIfc)tender; //logic goes here... } });
关于java - 避免在 Java 中使用带有附加字段的子类的 instanceof,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48472178/