はじめに
こちらの続きです。
コードの全量のリンクをこちらの記事に書いているので全量を見たい方はこちらを参照してください。
まずは多重継承の話の前に必要な土台作りがメインです。
Objectクラスを、ほんの少し(?)拡張するInterfaceの追加をします。
Objectを拡張からはじめる
Interfaceのdefaultを使った実装をするにあたって、どこから手を付けようと思ったか?についてから。
どのような型であれ、フロントから取得して、DBで永続化するにあたって
- フロントからは任意項目で受け取りたい
- DBのカラムの定義がnull許容
というのがある以上、DTOのメンバとしては Nullableであることを起きえます。
フラグなどを設ければ避けられるのですが、その分の手間がかかります。
そこで、Nullを安全に扱うのに便利なのがOptional
です。
// dto.getName() の戻り値の型が Stringだと if(Objects.isNull(dto.getName()){ // なにかしら } // これをOptionalにすれば、こういう感じの実装ができる if(dto.getName().isEmpty(){ // なにかしら }
ということで、ObjectをNullableに扱いやすい拡張を一番初めにしました。
このメソッドがプロパティを扱うためのエントリーポイント的なものになります。
実装と説明
public interface SinglePropertyObjectType<T> { Optional<T> getNullableValue(); }
インスタンスがNullableなものだという拡張をしただけですね。
NotEmptyを扱う
Nullableとは逆にNonNullを強制をするものも下準備しておきます。
Objectがベースになるので、Nullableなものが先にあって Nullを許容しないという制約宣言を追加する、というイメージで使用する想定です。
public interface NotEmptyType<T> { T getValue(); }
<T>
は、SinglePropertyObjectType<T>
の<T>
と同じプリミティブな型を指定します。
具体的な使い方は次の「文字列編」で示す予定です。
インスタンスの生成
ここでやりたいことは new
の振舞いを定義する、です。
せっかくプリミティブをラップした独自型のための準備をしたのですからメソッドの戻り値がプリミティブというのだと少々残念です。
また、booleanを戻り値とする判定ロジックであれば特にいらないのですが、加工/編集をした結果をインスタンスとした戻り値にしたいです。
その辺りの作法的なところをInterfaceとして定義します。
実装と説明
public interface NoArgumentNewInstance<R> { /** * 引数なしでインスタンスを生成します. * * @return 生成したインスタンス */ public R newInstance(); }
public interface SingleArgumentNewInstance<T, R> { /** * 引数ありでインスタンスを生成します. * * @param value インスタンスのプロパティ * @return 生成したインスタンス */ R newInstance(T value); }
これを具象クラスで実装すれば編集や加工をしたインスタンスをInterfaceのdefault内で生成することが出来るようになります。
さいごに
こんな感じで、Interfaceのdefaultを実装していく話がこれから続いていきます。
次回はStringの拡張をテーマにした「文字列編」を予定。