※ 個人blogに投稿した記事(投稿日:2019/9/27)をQiitaに移行しました
現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法、読了しました。
Amazonのレビュー見ると結構賛否両論のようですが、
オブジェクト指向設計、ドメイン駆動設計の基礎固めとして最適では、と自分は感じました。
「CHAPTER2 場合分けのロジックを整理する > Javaの列挙型を使えばもっとかんたん」を読んで、
おお、JavaはEnumの値ごとにコンストラクタを付与したりできるのか・・・便利・・・
と恥ずかしながら初めて知りました。
.NETでも似たようなことをできないなかな、と探したら以下のようなMS公式リファレンスがありました。
enum 型の代わりに Enumeration クラスを使用する
上記と書籍のサンプルコードを真似してVB.NETで書いてみたのが以下のコードになります。
(書籍ではYen クラスを ValueObject 化していたのを端折って Integer にしてます)
本体
Public Interface Fee
Function yen() As Integer
Function label() As String
End Interface
Public Class AdultFee
Implements Fee
Public Function yen() As Integer Implements Fee.yen
Return 100
End Function
Public Function label() As String Implements Fee.label
Return "大人"
End Function
End Class
Public Class ChildFee
Implements Fee
Public Function yen() As Integer Implements Fee.yen
Return 50
End Function
Public Function label() As String Implements Fee.label
Return "子供"
End Function
End Class
Public MustInherit Class Enumeration
Public Shared Function valueOf(Of T)(typeName As String) As T
Return CType(GetType(T).GetField(typeName, Reflection.BindingFlags.Public Or Reflection.BindingFlags.Static Or Reflection.BindingFlags.DeclaredOnly).GetValue(Nothing), T)
End Function
End Class
Public Class FeeType
Inherits Enumeration
Public Shared Adult As New FeeType(New AdultFee)
Public Shared Child As New FeeType(New ChildFee)
Private ReadOnly fee As Fee
Sub New(fee As Fee)
Me.fee = fee
End Sub
Public Function yen() As Integer
Return fee.yen
End Function
Public Function label() As String
Return fee.label
End Function
End Class
クライアント側
Module Module1
Sub Main()
Dim feeForAdult = feeFor("Adult")
Dim feeForChild = feeFor("Child")
End Sub
Public Function feeFor(feeTypeName As String) As Integer
Dim theFeeType = FeeType.valueOf(Of FeeType)(feeTypeName)
Return theFeeType.yen
End Function
End Module
実行してみましょう。
値取れてますね。
良い感じですが、リフレクションで変数名を指定するのはちょっと怖いです。以上。