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 加入
还未添加个人简介
评论