1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

VB.NETでJavaの「列挙型クラス」を模倣して「区分オブジェクト」を作る

Last updated at Posted at 2021-04-30

※ 個人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

実行してみましょう。

20190927230703.png

値取れてますね。
良い感じですが、リフレクションで変数名を指定するのはちょっと怖いです。以上。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?