2016-12-24 48 views
2

我有一個嵌套的私有類的類。我有一個標準的Java構建器模式Builder,它構造了這個類的實例。我不希望我班以外的任何人能夠看到我隱藏的課程。Kotlin嵌套成員的可見性

在Java中我可以這樣做:

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); } 
    } 
} 

但我無法弄清楚如何做相同的科特林:

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的緣故互操作我想保持我的建設者。我也想要它,因爲我的對象構造起來很複雜,我希望它是不可變的,所以我有一個有很多setter,加法器,vals等的構建器,然後在init中我構建了一個不可變的Example

我看到的唯一的選擇是:

  1. 而不是在我的建設者一個SneakyType保存所有必要的信息,以構建一個,然後構造它Example。工程但增加了很多複雜性。
  2. 放棄Example是不可改變的,允許製造商調入它來建立一個Sneaky
  3. 揭露Sneaky

有沒有辦法模仿的Java版本?

回答

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) 
         } 
        } 
    } 
    

    這將使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

我同意第二個選項是非常好的。不幸的是,對我來說,我認爲它不會很好地工作,因爲我實際上有一個更復雜的數據結構,它只涉及一些'SneakyType'。第一種選擇是我最終做的。爲好的選項提供最高票數。沒有標記「正確」,只是希望有人提出一個更好的主意。謝謝! –