Kotlin 实现组合模式
发布于: 2020 年 06 月 23 日
1. 组合模式的概念
组合模式(Composite), 将对象组合成属性结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
2. 实例
使用组合设计模式实现以下程序

2.1 类图

在这个视图层级中容器一定是ViewGroup,而且只有ViewGroup才能包含其他的View,比如Frame能包含TextBox、Button、Label等,但是反过来Button是不能包含Frame的,因此将Button等直接继承于View,Frame继承与ViewGroup,这样的设计对于使用方来说将会更加的安全。
2.2 代码实现
最近Kotlin使用的比较多,写出来也比较简洁,就酱紫
abstract class View {    abstract val text: String    open fun draw() = println("Print View($text)")}abstract class ViewGroup : View() {    val viewGroup = arrayListOf<View>()    fun addView(view: View) = viewGroup.add(view)    fun addView(block: () -> View) = viewGroup.add(block())    fun removeView(view: View) = viewGroup.remove(view)    fun getView(index: Int) = viewGroup[index]}class WinForm(override val text: String) : ViewGroup() {    override fun draw() {        println("Print WinForm($text)")        viewGroup.map {            it.draw()        }    }}class Frame(override val text: String) : ViewGroup() {    override fun draw() {        println("Print Frame($text)")        viewGroup.map {            it.draw()        }    }}class Picture(override val text: String) : View() {    override fun draw() = println("Print Picture($text)")}class Button(override val text: String) : View() {    override fun draw() = println("Print Button($text)")}class Label(override val text: String) : View() {    override fun draw() = println("Print Label($text)")}class TextBox(override val text: String) : View() {    override fun draw() = println("Print TextBox($text)")}class PasswordBox(override val text: String) : View() {    override fun draw() = println("Print PasswordBox($text)")}class CheckBox(override val text: String) : View() {    override fun draw() = println("Print CheckBox($text)")}class LinkLabel(override val text: String) : View() {    override fun draw() = println("Print LinkLabel($text)")}调用构建界面:
fun main() {    WinForm("WINDOW窗口").apply {        addView(Picture("LOGO图片"))        addView(Button("登陆"))        addView(Button("注册"))        addView { //用高阶函数实现类DSL的方式让代码结构层次看起来比较清晰            Frame("FRAME1").apply {                addView(Label("用户名"))                addView(TextBox("文本框"))                addView(Label("密码"))                addView(PasswordBox("密码框"))                addView(CheckBox("复选框"))                addView(TextBox("记住用户名"))                addView(LinkLabel("记住密码"))            }        }    }.draw()}运行打印输出:
/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=63131:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/tools.jar:/Users/Acker/Desktop/架构师训练营/代码项目/architecture-exercise/out/production/classes:/Users/Acker/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.3.72/916d54b9eb6442b615e6f1488978f551c0674720/kotlin-stdlib-jdk8-1.3.72.jar:/Users/Acker/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.3.72/3adfc2f4ea4243e01204be8081fe63bde6b12815/kotlin-stdlib-jdk7-1.3.72.jar:/Users/Acker/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.3.72/8032138f12c0180bc4e51fe139d4c52b46db6109/kotlin-stdlib-1.3.72.jar:/Users/Acker/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.3.72/6ca8bee3d88957eaaaef077c41c908c9940492d8/kotlin-stdlib-common-1.3.72.jar:/Users/Acker/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar com.sk.architect.week3.composite.ViewKtPrint WinForm(WINDOW窗口)Print Picture(LOGO图片)Print Button(登陆)Print Button(注册)Print Frame(FRAME1)Print Label(用户名)Print TextBox(文本框)Print Label(密码)Print PasswordBox(密码框)Print CheckBox(复选框)Print TextBox(记住用户名)Print LinkLabel(记住密码)Process finished with exit code 0
划线
评论
复制
发布于: 2020 年 06 月 23 日阅读数: 80
版权声明: 本文为 InfoQ 作者【Acker飏】的原创文章。
原文链接:【http://xie.infoq.cn/article/a7050fd50ecf666747e0a0682】。文章转载请联系作者。

Acker飏
关注
还未添加个人签名 2018.05.03 加入
还未添加个人简介











 
    
评论