2016-12-24 12 views
2

私はネストされたプライベートクラスを持つクラスを持っています。私はBuilder標準のJavaビルダーパターンを持ち、このクラスのインスタンスを構築しています。私はクラスの外の誰も私の隠れたクラスを見ることができないようにしています。ネストされたメンバーのKotlin可視性

public class Example { 
    private SneakyType doNotExposeThis; 

    private Example(Builder builder) { 
     // OK 'cause in Java you can access the private 
     // members of a nested class 
     doNotExposeThis = builder.doNotExposeThis; 
    } 

    private static class SneakyType { 
     SneakyType(String x) { 
      // stuff 
     } 
    } 

    public static class Builder { 
     private SneakyType doNotExposeThis; 

     public void addFoo(String something) { 
      doNotExposeThis = new SneakyType(something); 
     } 

     public Example build() { return new Example(this); } 
    } 
} 

しかし、私はKotlinで同じことを行う方法を見つけ出すことはできません:

Javaでは、私はこれを行うことができます

class Example(builder: Builder) { 
    private lateinit var doNotExposeThis: SneakyType 

    init { 
     doNotExposeThis = builder.doNotExposeThis 
    } 

    class Builder { 
     // If private or internal I can't access it in Example.init 
     // and if public it gets exposed. 
     val doNotExposeThis: SneakyType 


     fun addFoo(something: String) { 
      // actual construction is quite a bit more complex 
      doNotExposeThis = SneakyType(something) 
     } 
    } 
} 

注意するJavaのために相互運用私が望むこと私の建築家を守る。私のオブジェクトは構築が複雑で、不変でなければならないので、多くのセッター、加算器、valなどがあるビルダーを持っています。initExampleを1つ作成します。

私が見る唯一の選択肢は以下のとおりです。

  1. 代わりの1を構築し、その後Exampleでそれを構築するために必要なすべての情報の保存私のビルダーでSneakyTypeを持っています。動作しますが、複雑さが増します。
  2. Javaバージョンを模倣する方法はありません不変であることExampleにあきらめ、ビルダーはSneaky

を公開Sneaky

  • を設定するには、それに呼び出すことができますか?

  • 答えて

    2

    私は2つの実行可能なオプションを参照してください。

    1. internalvisibility modifierを使用します。

      class Example private constructor(builder: Builder) { 
          private val doNotExposeThis: SneakyType 
      
          init { 
           doNotExposeThis = builder.doNotExposeThis 
          } 
      
          internal class SneakyType(x: String) 
      
          class Builder { 
           internal lateinit var doNotExposeThis: SneakyType 
      
           fun addFoo(something: String) { 
            doNotExposeThis = SneakyType(something) 
           } 
      
           fun build(): Example { 
            return Example(this) 
           } 
          } 
      } 
      

      これはあなたのKotlinのコンパイルモジュール内SneakyTypeのみが見えるようになります。

    2. メイクそのビルダーのExample独立した(これは私がお勧めするものである):

      class Example private constructor(private val doNotExposeThis: SneakyType) { 
          private class SneakyType(x: String) 
      
          class Builder { 
           private lateinit var doNotExposeThis: SneakyType 
      
           fun addFoo(something: String) { 
            doNotExposeThis = SneakyType(something) 
           } 
      
           fun build(): Example { 
            return Example(doNotExposeThis) 
           } 
          } 
      } 
      
    +0

    私は2番目のオプションは本当に素敵であることに同意します。残念ながら、私にとっては、実際には 'SneakyType'のようなもっと複雑なデータ構造しか持たないので、うまく動作するとは思えません。第一の選択肢は私がやったことです。良いオプションを選ぶことができます。誰かがより良いアイデアを思いつくことを願って、「正しい」とマークしていません。ありがとう! –

    関連する問題