官术网_书友最值得收藏!

Creating an email – the Kotlin way – second attempt

Let's try a fluent setter approach, instead. We'll have only mandatory fields in our constructor, and all of the others will become setters. So to create a new email, we no longer need to do the following:

   val mail = Mail("manager@company.com") 
   mail.title("Ping") 
   mail.cc(listOf<String>()) 

Instead, we will do the following:

Mail("manager@company.com").title("Ping").cc(listOf<String>())

Fluent setters allow us to chain one set call to another.

That's a lot nicer for a couple of reasons:

  • The order of fields can now be arbitrary, unlike the order used with the constructor.
  • It's clearer which field is being set; no more need for comments.
  • Optional fields don't need to be set at all. As an example, the CC field is set while the BCC field is omitted.

Let's look at one way of implementing this approach. There are other convenient ways to do this, which we'll discuss in Chapter 10, Idioms and Anti-Patterns:

   data class Mail(// Stays the same 
                   private var _message: String = "", 
                   // ...) { 
       fun message(message: String) : Mail { 
           _message = message 
return this } 
       // Pattern repeats for every other variable 
   } 

Using underscores for private variables is a common convention in Kotlin. It allows us to avoid repeating the phrase this.message = message and mistakes, such as message = message.

This is nice and is very similar to what we may achieve in Java, although we did have to make our message mutable.

We can also implement a full-blown builder design pattern, of course:

class MailBuilder(val to: String) { 
    private var mail: Mail = Mail(to) 
    fun title(title: String): MailBuilder { 
        mail.title = title 
        return this 
    }
// Repeated for other properties fun build(): Mail { return mail } }

You can use it to create your email in the following way:

val email = MailBuilder("hello@hello.com").title("What's up?").build()

But Kotlin provides two other ways that you may find even more useful.

主站蜘蛛池模板: 滨海县| 石屏县| 信丰县| 宁德市| 乌审旗| 巴林右旗| 格尔木市| 西华县| 荣成市| 乐陵市| 仙居县| 庄河市| 镇沅| 获嘉县| 搜索| 遂平县| 页游| 通山县| 平陆县| 忻州市| 蒙城县| 陆河县| 固阳县| 海盐县| 施秉县| 灵石县| 郎溪县| 沾化县| 綦江县| 黔西县| 河曲县| 乌兰浩特市| 东安县| 图木舒克市| 淳化县| 依安县| 车险| 宜君县| 天等县| 建始县| 南康市|