- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在重构一些代码时,我发现我们应该在几个地方使用一些多态性,而不是到处都有一堆 if/else block 。
虽然面向对象的类很容易制作,但当我们必须决定使用什么实现时,问题就来了。似乎有很多解决方案,但我想看看是否有更优雅或“最佳实践”的方法来做到这一点。
所以基本上,为了举例,我将选择一张信用卡,并且对于每种信用卡类型,我都有一个实现。因此我有一个这样的类结构:
每个子类都将扩展 CreditCard 父类(super class)。
现在在 Web 应用程序中,我将传递一个表示用户选择的卡片类型的字符串。现在我需要将它路由到实际的实现类本身。这就是过多选择发挥作用的地方。
如果有更好的选择或者我是否坚持使用这些选择,请务必告诉我..
工厂:
@Autowired @Qualifier("visa") private CreditCard visa;
@Autowired @Qualifier("mastercard") private CreditCard mastercard;
@Autowired @Qualifier("amex") private CreditCard amex;
public CreditCard getCreditCard(String input) {
{
if ("visa".equals(input)) {
return visa;
} else if ("mastercard".equals(input)) {
return mastercard;
} else if ("amex".equals(input)) {
return amex;
}
return null;
}
map :
@Autowired HashMap<String, CreditCard> creditCardImpls;
public CreditCard getCreditCard(String input) {
return creditCardImpls.get(input);
}
ApplicationContext getBean:
@Autowired private ApplicationContext applicationContext;
public CreditCard getCreditCard(String input) {
return applicationContext.getBean(input);
}
我在这里看到的问题是,如果我们要在未来添加更多的信用卡类型,我将不得不在可能的几个不同领域 Autowiring 。然后,Map 的问题是我们没有使用 Spring 来获取 bean。对于吨他从 ApplicationContext 中获取 Bean,我们没有遵循 Spring 提供的 IoC。
这个问题的最佳解决方案或最佳实践是什么?
最佳答案
首先对您的解决方案发表一些评论,然后是我自己的建议。
input
)映射,而且每次你想引入一个新的信用卡类型时,你需要修改工厂类代码。CreditCard
抽象。与您的评论“它不使用 Spring 来确定要使用哪个 bean”相反,该映射将 bean ID 作为键并由 Spring Autowiring ,因此我们实际上在这里广泛使用了 Spring。但是,由于映射键是 bean ID,这将业务逻辑(信用卡类型 - input
)与技术实现(Spring bean ID)混合在一起。如果你想实现一个单独的 bean 来处理“mastercard platinum”信用卡类型怎么办?由于技术原因,您不能拥有这样的 bean ID(由于空间)。或者在某些时候您会希望某个 bean 可以处理多种卡片类型。然后,您需要在业务标识符和 bean ID 之间实现另一个转换映射。请参阅下面我的解决方案以获得增强功能。我的建议是将业务 key 与 bean ID 分开。所以我们需要 CreditCard
能够说明它可以处理哪种信用卡类型。
abstract class CreditCard {
public abstract String getType();
}
然后每个子类返回自己的类型。
或者
abstract class CreditCard {
private String type;
protected CreditCard(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
每个子类调用super(<the subclass type>)
他们自己的构造函数中的构造函数。
然后,在工厂中,您可以这样实现。
@Autowire private Collection<CreditCard> creditCards;
private Map<String, CreditCard> creditCardsMap = new HashMap<>();
@PostCostruct
public void mapCreditCards() {
for (CreditCard creditCard : creditCards) {
creditCardsMap.put(creditCard.getType(), creditCard);
}
}
public CreditCard getCreditCard(String type) {
return creditCardsMap.get(type);
}
@PostConstruct方法将在 creditCards
之后运行(所有类型为 CreditCard
的 bean)都已 Autowiring ,因此允许在业务 key 而非技术 key 下进行动态发现和映射。
关于java - 基于运行时提供的字符串查找要使用哪个接口(interface)实现的优雅解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23507079/
您如何优雅编码同一tableView中的两种类型的单元格? 显然我可以这样: NSDictionary *cellInfo = [_userInformation objectAtIndex:inde
假设我正在编写一个仅包含标题或主要包含标题的库,并且具有以下代码: using my_type = int; namespace detail { inline void foo() { my
我正在使用复选框和输入进行一系列启用/禁用选择,我想知道我是否可以使用循环、变量或复合语句来简单地处理这个js?感觉就像是使用大量代码来实现相对简单的功能。 这是我正在做的事情的一个 fiddle :
我正在尝试为来自维基百科的 API 响应编写一个解析器。它真的很困惑,我已经求助于旧的 RegEx 来清理大部分东西。然而,我坚持这一点。考虑一个字符串: var a ="[[December 1]
我正在通过一个 channel 接收多个消息,并在对其进行迭代之后,我想保留最后一个元素以供进一步使用。我的第一个(可能很糟糕!)方法是声明一些变量,然后在每个循环中分配它。 let last = 0
我正在编写一个 PHP Web 应用程序,它将在不久的将来在生产环境下运行,而不是使用非用户友好的 die() , 我想我会想出一个 Class处理错误消息。 基本上,我的思考过程是这样的: 如果 W
我们有 elb 负载平衡 2 台运行 tomcat 作为应用程序服务器的 WAS 机器。要实现AWS环境下的不间断部署,我们应该, 选择部署目标 WAS。 让它停止来自 elb 的交易。(elb 暂停
何为pythonic? pythonic如果翻译成中文的话就是很python。很+名词结构的用法在中国不少,比如:很娘,很国足,很CCTV等等。 我的理解为,很+名词表达了一种特殊和强调的意味。
认为已经有对此的答案,但找不到。我一直在以某种方式解析方法选项,并想检查并确保它是最优雅/最简洁的方式。 这是我通常做的: def some_method *args options = args
我正在清理我的一个旧项目。它必须做的一件事是——给定笛卡尔网格系统和网格上的两个正方形,找到所有正方形的列表,连接这两个正方形中心的线将通过这些正方形。 这里的特殊情况是所有起点和终点都被限制在正方形
如何使系统 ( SystemB1 ) 访问另一个系统 ( SystemA::sub ) 的字段,就好像它是自己的字段一样? SystemA是一个拥有自己领域的实用系统 Sub* sub . Syste
我有一个包含约 8.000.000 条记录的 MySQL 数据库。因为我需要处理所有这些,所以我使用 BlockingQueue 作为生产者从数据库读取数据并将 1000 条记录放入队列中。 Cons
我正在让我的 HTTP 服务器正常关闭。我从帖子中获取了提示 here ,到目前为止,我的代码是这样设置的: func start() { //...... //START HTTP/
示例脚本只是“wc -m”命令的包装器,简单的符号计数器。我尝试只用“teststrings” slice 元素提供输入。并在输出监听器 goroutine 接收每个字符串的符号数。寻找一种让“wc”
我想干净/优雅地关闭 Internet Explorer。 taskkill 会关闭它,但是当重新打开它时,它会询问您是否要重新打开上一个 session 。 最佳答案 尝试 CloseMainWin
Haskell 的简洁和优雅给我留下了深刻的印象。但我在 .Net 公司工作,所以当我可以使用 F# 时我会使用它——我可能是全国数百个使用它的人中唯一的一个。 ADO.NET 或 F# 是否提供像
如果我们不想在我们的类中实现 init 方法,并且记住 NSObject 中的 init 只返回一个没有初始化的对象实例,如果我们已经得到了,我不明白调用 init 的意义带有分配的实例。我已经尝试过
我们的组织中有许多初级 Delphi 开发人员,作为向他们教授 Delphi 过程的一部分,我希望他们能够看到“干净”、编写良好、设计良好的 Delphi 代码。 我要寻找的一些标准包括: 优秀的类(
我有一个 3D 图像扫描(形状:335x306x306,总元素:31368060),我想用相同大小的 3D bool 掩码来掩盖它以返回相同大小的蒙版图像。 当我简单地用掩码索引数组时: masked
如何使适配器类适本地支持 const 和非 const 底层数据? 具体例子 RigidBody是描述对象物理属性的类。 这是其非常简化的版本(1D):- class RigidBody{ f
我是一名优秀的程序员,十分优秀!