Phi*_*ell 3 ruby switch-statement
我目前正在使用Ruby为银行管理系统编写程序.该系统的一个功能是它可以创建一个新帐户,帐户可以是六种类型之一.
我的控制器中有以下方法来满足此功能:
def create_account(type, holder)
case type
when :current then CurrentAccount.new(holder, @account_number)
when :savings then SavingsAccount.new(holder, @account_number)
when :business then BusinessAccount.new(holder, @account_number)
when :ir then IRAccount.new(holder, @account_number)
when :smb then SMBAccount.new(holder, @account_number)
when :student then StudentAccount.new(holder, @account_number)
end
end
Run Code Online (Sandbox Code Playgroud)
这些账户中的每一个都从基础账户继承,最终将包含个人属性,例如利率,透支等.
虽然这是功能性的,并提供了所需的结果,但感觉有点冗长.但是我想不出任何明显的重构方法.
欢迎任何建议......
我假设在某些时候系统或最终用户有效地选择文本类型,您需要将其转换为要使用的类.否则,您可以编写简单引用并实例化正确类的调用代码.
您可以通过定义符号type和类之间的映射来使您拥有更清洁的东西.所以你可以在以下范围内做到这一点create_account:
ACCOUNT_CLASS_FOR = Hash[
current: CurrentAccount,
savings: SavingsAccount,
business: BusinessAccount,
ir: IRAccount,
smb: SMBAccount,
student: StudentAccount
]
def create_account(type, holder)
if account_class = ACCOUNT_CLASS_FOR[ type ]
account_class.new( holder, @account_number )
else
raise "Bad account type #{type}"
end
end
Run Code Online (Sandbox Code Playgroud)
这减少了重复的代码,并使符号名称和匹配的Ruby类之间的映射更加明确.如果您需要在其他地方应用或测试转换,您可以在不重复自己的情况下使常量在不同范围内可用.
你可以通过让每个班级都知道自己的标签来使这个更清洁
class CurrentAccount
def self.label
:current
end
end
Run Code Online (Sandbox Code Playgroud)
然后你可以有这样的东西:
ALLOWED_ACCOUNT_CLASSES = [CurrentAccount,SavingsAccount,BusinessAccount, # etc.
ACCOUNT_CLASS_FOR = Hash[
ALLOWED_ACCOUNT_CLASSES.map { |klass| [klass.label, klass] }
]
Run Code Online (Sandbox Code Playgroud)
请注意,klass在这里使用拼写错误的变量以避免与Ruby的class关键字冲突是很常见的做法,但您也可以使用account_class