『増補改訂版Java言語で学ぶデザインパターン入門』をKotlinでやってみる(Prototype編)


【経緯】

『増補改訂版Java言語で学ぶデザインパターン入門』をKotlinでやってみるの第六回目、Prototypeパターンです。

【コード】

Prototypeはクラスからインスタンスを生成するのではなく、インスタンスから別のインスタンスをコピーして生成するパターンです。
単語の通りPrototype(原型)からのインスタンスからコピーを作り出すデザインパターンです。このあたりの関係なのか、ProductインターフェースにCloneableインターフェースを実装するとエラー出て対応できなかったのでちょっと変えてます。

UnderlinePen.kt
class UnderlinePen(ulp:String):Product,Cloneable {
    private var ulStr = ulp

    override fun use(s:String) {
        var length = s.toByteArray().size
        println("\"" + s + "\"")
        println("")

        for(i in 0..length+3) {
            println(ulStr)
        }
        println("")
    }

    override fun createClone():Product? {
        var p:Product? = null

        try {
            p = super.clone() as Product
        } catch(e:CloneNotSupportedException) {
            println(e.printStackTrace())
        }
        return p
    }
}
MessageBox.kt
class MessageBox(msg:String):Product,Cloneable {
    private var decochar:String = msg

    override fun use(s:String) {
        var length = s.toByteArray().size

        for(i in 0..length+3) {
            println(decochar)
        }

        println("")
        println(decochar + " " + s + " " + decochar)

        for(i in 0..length+3) {
            println(decochar)
        }
        println("")
    }

    override fun createClone():Product? {
        var p:Product? = null

        try {
            p = clone() as Product
        } catch(e:CloneNotSupportedException) {
            println(e.printStackTrace())   
        }
        return p
    }
}
Manager.kt
class Manager {
    private var showcase:HashMap<String, Product> = HashMap()

    fun register(name:String, proto:Product) {
        showcase.put(name, proto)
    }

    fun create(protoname:String):Product? {
        var p = showcase.get(protoname) as Product?
        return p?.createClone()
    }
}
Product.kt
interface Product  {
    public abstract fun use(str:String)
    public abstract fun createClone():Product?
}
Main.kt
fun main(args: Array<String>) {
    // Here your code !

    var manager:Manager = Manager()
    var under:UnderlinePen = UnderlinePen("~")
    var aBox:MessageBox = MessageBox("*")
    var sBox:MessageBox = MessageBox("/")
    manager.register("strong message", under)
    manager.register("warning box", aBox)
    manager.register("slash box", sBox)

    var pStrong:Product? = manager.create("strong message")
    pStrong?.use("Hello, World.")

    var pWarning:Product? = manager.create("warning box")
    pWarning?.use("Hello, World.")

    var pSlash:Product? = manager.create("slash box")
    pSlash?.use("Hello, World.")
}
出力結果(改行削除)
"Hello, World."
"~~~~~~~~~~~~~~~~~"
*****************
* Hello, World. *
*****************
/////////////////
/ Hello, World. /
/////////////////