├── BuilderDesignPattern.md ├── BuilderDesignPattern └── BuilderUml.png ├── CommandPattern.md ├── CommandPattern ├── mlms1.mdj ├── mlms1.png └── mlms2.png ├── README.md ├── 原型模式.md ├── 原型模式 ├── result1.png ├── result2.png ├── result3.png ├── 原型模式.mdj └── 原型模式.png ├── 工厂方法模式.md ├── 工厂方法模式 ├── factoryUml.mdj ├── factoryUml.png ├── factoryresult.png ├── lazyfactory.png ├── morefactory.mdj └── morefactory.png ├── 策略模式.md ├── 策略模式 ├── clms.mdj ├── clms1.png └── clns2.png ├── 观察者模式.md └── 观察者模式 ├── gczms.gif ├── gczms.mdj └── gczms1.png /BuilderDesignPattern.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Android 建造者(Builder)模式 3 | date: 2016-08-03 13:56:23 4 | tags: Java 设计模式 5 | --- 6 | 7 | 8 | 9 | ## 前言 10 | 11 | 正所谓只要功夫深,铁杵磨成针,坚持不懈,水滴石穿。学习也要坚持不懈,慢慢积累,才能达到以量变促成质变。在前进的过程中也要保持好良好的心态,不急不燥,脚踏实地,一步一个脚印。 12 | 13 | ## Builder Design Pattern 介绍 14 | 15 | * 建造者模式(Builder Pattern)也叫做生成器模式,Builder Design pattern 是一种**创建型模式**,Builder模式所解决的问题与对象的创建有关。它允许用户在不知道内部构建细节的情况下,可以更精细的控制对象的构造流程,Builder模式是为了将构造复杂对象的过程和他的部件解耦。Android 中我们最常用的Builder模式是AlterDialog.Builder。 16 | 17 | * Builder 模式通常是以静态内部类的形式实现。 18 | 19 |    20 | 21 | ## Builder Design Pattern 定义 22 | 23 | ​ 将一个复杂对象的构建过程与他的表示分离,使得同样的构建过程可以创建不同的表示。 24 | 25 | 26 | 27 | ## Builder Design Pattern 使用场景 28 | 29 | * 需要太多的构造函数。 30 | * 当初始化一个对象特别复杂,如参数多,并且很多参数具有默认值时。 31 | * 配置类的构造器的构建,将配置与目标类隔离出来(参照[Universal-Image_Loader](https://github.com/nostra13/Android-Universal-Image-Loader))。 32 | * 相同的方法,不同的执行顺序,产生不同的事件结果时。 33 | * 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果不同时。 34 | * 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能。 35 | 36 | 37 | ## Builder Design Pattern 通用UML类图 38 | 39 | ![Builder](BuilderDesignPattern/BuilderUml.png) 40 | 41 | **说明:** 42 | 43 | * **Product产品类** 44 | ConcreateBuilder 创建该产品的内部表示,并定义它的装配过程。 45 | 46 | * **Builder抽象建造者** 47 | 48 | 规范产品的组建,一般是由子类实现。 49 | 50 | * **ConcreateBuilder 具体建造者** 51 | 52 | 实现抽象类定义的所有方法,并且返回一个组建好的对象。 53 | 54 | * **Director导演类** 55 | 56 | 负责安排已有模块的顺序,然后告诉Builder开始建造。 57 | 58 | 59 | 60 | 61 | ## Builder Design Pattern 使用实例 62 | 63 | ### 标准化的建造者(Builder)模式使用实例 64 | 65 | 我们以组建一台自己心仪的台式机电脑为例; 66 | 67 | 1. 电脑抽象类 68 | 69 | ``` java 70 | /** 71 | * Created by iuni.life on 16/8/2. 72 | * 组建一台简单的台式机电脑,电脑抽象类 即Product角色 73 | */ 74 | public class Computer { 75 | //cpu 76 | protected String mCpu = "intel i3-4150"; 77 | //显示器 78 | protected String mDisplay = "21寸"; 79 | //主板 80 | protected String mBoard = "华硕 B85"; 81 | //电源 82 | protected String mPower = "安钛克 220V"; 83 | //系统 84 | protected String mSysOs = "Dos"; 85 | //主机箱 86 | protected String mMainBox = "先马"; 87 | //鼠标 88 | protected String mMouse = "贱驴"; 89 | //键盘 90 | protected String mKeyBoard = "cherry"; 91 | //内存条 92 | protected String mSimm = "2*4G"; 93 | //硬盘 94 | protected String mHardDisk = "希捷 1T"; 95 | 96 | protected ComputerStant() { 97 | } 98 | 99 | public abstract void setSimm(String simm); 100 | 101 | public abstract void setHardDisk(String hardDisk); 102 | 103 | public abstract void setCpu(String cpu); 104 | 105 | public abstract void setDisplay(String display); 106 | 107 | public abstract void setBoard(String board); 108 | 109 | public abstract void setPower(String power); 110 | 111 | public abstract void setSysOs(String sysOs); 112 | 113 | public abstract void setMainBox(String mainBox); 114 | 115 | public abstract void setMouse(String mouse); 116 | 117 | public abstract void setKeyBoard(String keyBoard); 118 | 119 | @Override 120 | public String toString() { 121 | return "ComputerStant{" + 122 | "mCpu='" + mCpu + '\'' + 123 | ", mDisplay='" + mDisplay + '\'' + 124 | ", mBoard='" + mBoard + '\'' + 125 | ", mPower='" + mPower + '\'' + 126 | ", mSysOs='" + mSysOs + '\'' + 127 | ", mMainBox='" + mMainBox + '\'' + 128 | ", mMouse='" + mMouse + '\'' + 129 | ", mKeyBoard='" + mKeyBoard + '\'' + 130 | ", mSimm='" + mSimm + '\'' + 131 | ", mHardDisk='" + mHardDisk + '\'' + 132 | '}'; 133 | } 134 | } 135 | ``` 136 | 137 | 2. 电脑抽象类的具体实现,我们以Mac电脑为例 138 | 139 | ```java 140 | /** 141 | * Created by iuni.life on 16/8/2. 142 | * 143 | */ 144 | public class MacComputer extends Computer { 145 | 146 | protected MacComputer() { 147 | } 148 | 149 | @Override 150 | public void setSimm(String simm) { 151 | mSimm = simm; 152 | } 153 | 154 | @Override 155 | public void setHardDisk(String hardDisk) { 156 | mHardDisk = hardDisk; 157 | } 158 | 159 | @Override 160 | public void setCpu(String cpu) { 161 | mCpu = cpu; 162 | } 163 | 164 | @Override 165 | public void setDisplay(String display) { 166 | mDisplay = display; 167 | } 168 | 169 | @Override 170 | public void setBoard(String board) { 171 | mBoard = board; 172 | } 173 | 174 | @Override 175 | public void setPower(String power) { 176 | mPower = power; 177 | } 178 | 179 | @Override 180 | public void setSysOs(String sysOs) { 181 | mSysOs = sysOs; 182 | } 183 | 184 | @Override 185 | public void setMainBox(String mainBox) { 186 | mMainBox = mainBox; 187 | } 188 | 189 | @Override 190 | public void setMouse(String mouse) { 191 | mMouse = mouse; 192 | } 193 | 194 | @Override 195 | public void setKeyBoard(String keyBoard) { 196 | mKeyBoard = keyBoard; 197 | } 198 | } 199 | ``` 200 | 201 | 3. Builder抽象类 202 | 203 | ```java 204 | /** 205 | * Created by iuni.life on 16/8/2. 206 | * builder 抽象类 207 | */ 208 | public abstract class Builder { 209 | //创建显示器 210 | public abstract Builder buildDisplay(String display); 211 | 212 | //创建主板 213 | public abstract Builder buildBoard(String board); 214 | 215 | //创建电源 216 | public abstract Builder buildPower(String power); 217 | 218 | //创建cpu 219 | public abstract Builder buildCpu(String cpu); 220 | 221 | //创建系统 222 | public abstract Builder buildSysOs(String sysOs); 223 | 224 | //创建主机箱 225 | public abstract Builder buildMainBox(String mainBox); 226 | 227 | //创建鼠标 228 | public abstract Builder buildMouse(String mouse); 229 | 230 | //创建键盘 231 | public abstract Builder buildKeyBoard(String keyBoard); 232 | 233 | //创建内存条 234 | public abstract Builder buildSimm(String simm); 235 | 236 | //创建硬盘 237 | public abstract Builder buildHardDisk(String hardDisk); 238 | 239 | //创建Computer 240 | public abstract ComputerStant create(); 241 | } 242 | ``` 243 | 244 | 4. Builder 的具体实现,因为我们是要组装一个Mac 电脑,所以需要MacBuilder 245 | 246 | ```java 247 | /** 248 | * Created by iuni.life on 16/8/2. 249 | */ 250 | public class MacBuilder extends Builder { 251 | MacComputer macComputer = new MacComputer(); 252 | 253 | @Override 254 | public Builder buildDisplay(String display) { 255 | macComputer.setDisplay(display); 256 | return this; 257 | } 258 | 259 | @Override 260 | public Builder buildBoard(String board) { 261 | macComputer.setBoard(board); 262 | return this; 263 | } 264 | 265 | @Override 266 | public Builder buildPower(String power) { 267 | macComputer.setPower(power); 268 | return this; 269 | } 270 | 271 | @Override 272 | public Builder buildCpu(String cpu) { 273 | macComputer.setCpu(cpu); 274 | return this; 275 | } 276 | 277 | @Override 278 | public Builder buildSysOs(String sysOs) { 279 | macComputer.setSysOs(sysOs); 280 | return this; 281 | } 282 | 283 | @Override 284 | public Builder buildMainBox(String mainBox) { 285 | macComputer.setMainBox(mainBox); 286 | return this; 287 | } 288 | 289 | @Override 290 | public Builder buildMouse(String mouse) { 291 | macComputer.setMouse(mouse); 292 | return this; 293 | } 294 | 295 | @Override 296 | public Builder buildKeyBoard(String keyBoard) { 297 | macComputer.setKeyBoard(keyBoard); 298 | return this; 299 | } 300 | 301 | @Override 302 | public Builder buildSimm(String simm) { 303 | macComputer.setSimm(simm); 304 | return this; 305 | } 306 | 307 | @Override 308 | public Builder buildHardDisk(String hardDisk) { 309 | macComputer.setHardDisk(hardDisk); 310 | return this; 311 | } 312 | 313 | @Override 314 | public ComputerStant create() { 315 | return macComputer; 316 | } 317 | } 318 | ``` 319 | 320 | 5. Director 导演类 321 | 322 | ```java 323 | /** 324 | * Created by iuni.life on 16/8/2. 325 | */ 326 | public class Director { 327 | Builder mBuilder = null; 328 | 329 | public Director(Builder mBuilder) { 330 | this.mBuilder = mBuilder; 331 | } 332 | 333 | //构建对象 334 | public void constract(String mCpu, String mDisplay, String mBoard, String mPower, String mSysOs, String mMainBox, String mMouse, String mKeyBoard, String mSimm, String mHardDisk) { 335 | mBuilder.buildCpu(mCpu); 336 | mBuilder.buildDisplay(mDisplay); 337 | mBuilder.buildBoard(mBoard); 338 | mBuilder.buildPower(mPower); 339 | mBuilder.buildSysOs(mSysOs); 340 | mBuilder.buildMainBox(mMainBox); 341 | mBuilder.buildMouse(mMouse); 342 | mBuilder.buildKeyBoard(mKeyBoard); 343 | mBuilder.buildSimm(mSimm); 344 | mBuilder.buildHardDisk(mHardDisk); 345 | //也可链式 346 | // mBuilder.buildMouse(mMouse).buildCpu(mCpu).buildPower(mPower); 347 | } 348 | } 349 | ``` 350 | 351 | 6. 测试类 test 352 | 353 | ```java 354 | /** 355 | * Created by iuni.life on 16/8/2. 356 | * 经典的Builder模式实现较为繁琐,文章后面会列举一个简单的 357 | */ 358 | public class Test { 359 | public static void main(String[] args) { 360 | //构造器 361 | Builder builder = new MacBuilder(); 362 | //Director 363 | Director director = new Director(builder); 364 | 365 | //封装构建过程 366 | director.constract("intel i7", "25寸", "华硕 B85", "安钛克220V", "Mac Os", "先马", "精灵 X5", "cherry", "2*8G", "希捷500G"); 367 | 368 | //构建电脑,输出相关信息 369 | 370 | System.out.println("My Mac Computer Info:"+builder.create().toString()); 371 | // 通过Builder来构建产品对象, 而Director封装了构建复杂产品对象对象的过程,对外隐藏构建细节。 372 | } 373 | } 374 | ``` 375 | * **说明** 376 | 377 | 通过Builder来构建产品对象, 而Director封装了构建复杂产品对象对象的过程,对外隐藏构建细节。但是这种经典的写法有点小烦,有点繁琐,在要求不是很苛刻的情况下,我们可以用下面的方式进行实现。 378 | 379 | ### 一种简单的方式实现Builder模式 380 | 381 | 1. 这种方式以Builder为静态内部类的方式实现,我们还是以组装一台自己的电脑为例。 382 | 383 | ```java 384 | /** 385 | * Created by iuni.life on 16/8/2. 386 | * 组建一台简单的台式机电脑,电脑抽象类 即Product角色 387 | */ 388 | public class Computer { 389 | //cpu 390 | private String cpu; 391 | //显示器 392 | private String display; 393 | //主板 394 | private String board; 395 | //电源 396 | private String power; 397 | //系统 398 | private String sysOs; 399 | //主机箱 400 | private String mainBox; 401 | //鼠标 402 | private String mouse; 403 | //键盘 404 | private String keyBoard; 405 | 406 | //私有化构造函数 使之不能从外部创建实例 407 | private Computer() { 408 | } 409 | 410 | private void setCpu(String cpu) { 411 | this.cpu = cpu; 412 | } 413 | 414 | private void setDisplay(String display) { 415 | this.display = display; 416 | } 417 | 418 | private void setBoard(String board) { 419 | this.board = board; 420 | } 421 | 422 | private void setPower(String power) { 423 | this.power = power; 424 | } 425 | 426 | private void setSysOs(String sysOs) { 427 | this.sysOs = sysOs; 428 | } 429 | 430 | private void setMainBox(String mainBox) { 431 | this.mainBox = mainBox; 432 | } 433 | 434 | private void setMouse(String mouse) { 435 | this.mouse = mouse; 436 | } 437 | 438 | private void setKeyBoard(String keyBoard) { 439 | this.keyBoard = keyBoard; 440 | } 441 | 442 | @Override 443 | public String toString() { 444 | return "Computer{" + 445 | "cpu='" + cpu + '\'' + 446 | ", display='" + display + '\'' + 447 | ", board='" + board + '\'' + 448 | ", power='" + power + '\'' + 449 | ", sysOs='" + sysOs + '\'' + 450 | ", mainBox='" + mainBox + '\'' + 451 | ", mouse='" + mouse + '\'' + 452 | ", keyBoard='" + keyBoard + '\'' + 453 | '}'; 454 | } 455 | //Builder 静态内部类 456 | public static class ComputerBuilder { 457 | //创建computer实例 458 | private Computer computer = new Computer(); 459 | 460 | //创建Cpu 461 | public ComputerBuilder buildCpu(String cpu) { 462 | computer.setCpu(cpu); 463 | return this; 464 | } 465 | 466 | //创建显示器 467 | public ComputerBuilder buildDisplay(String display) { 468 | computer.setDisplay(display); 469 | return this; 470 | 471 | } 472 | //创建主板 473 | public ComputerBuilder buildBoard(String board) { 474 | computer.setBoard(board); 475 | return this; 476 | } 477 | 478 | //创建电源 479 | public ComputerBuilder buildPower(String power) { 480 | computer.setPower(power); 481 | return this; 482 | } 483 | 484 | //创建系统 485 | public ComputerBuilder buildSysOs(String sysOs) { 486 | computer.setSysOs(sysOs); 487 | return this; 488 | } 489 | 490 | //创建主机箱 491 | public ComputerBuilder buildMainBox(String mainBox) { 492 | computer.setMainBox(mainBox); 493 | return this; 494 | } 495 | 496 | //创建鼠标 497 | public ComputerBuilder buildMouse(String mouse) { 498 | computer.setMouse(mouse); 499 | return this; 500 | } 501 | 502 | //创建键盘 503 | public ComputerBuilder buildKeyBoard(String keyBoard) { 504 | computer.setKeyBoard(keyBoard); 505 | return this; 506 | } 507 | //组装电脑,并返回创建好的电脑 508 | public Computer create() { 509 | //这里可以做一些初始化操作以及一些逻辑判断 510 | if (computer==null){ 511 | throw new IllegalStateException("computer is null"); 512 | } 513 | return computer; 514 | } 515 | } 516 | } 517 | ``` 518 | 519 | 2.测试类 520 | 521 | ```java 522 | /** 523 | * Created by iuni.life on 16/8/2. 524 | */ 525 | public class main { 526 | public static void main(String[] args) { 527 | //创建Builder对象 528 | Computer.ComputerBuilder computerBuilder = new Computer.ComputerBuilder(); 529 | //组装电脑,构建组装顺序 530 | computerBuilder.buildBoard("华硕"); 531 | computerBuilder.buildCpu("intel i7"); 532 | computerBuilder.buildDisplay("三星"); 533 | computerBuilder.buildKeyBoard("cherry"); 534 | computerBuilder.buildMainBox("杀神").buildMouse("贱驴").buildPower("安钛克").buildSysOs("Windoes 10"); 535 | //组装成一个自己想要的的电脑。 536 | // computerBuilder 只需要知道客户想组装成什么样的电脑,并对客户不关心的如何安装进行了隐藏。 537 | Computer computer = computerBuilder.create(); 538 | System.out.printf(computer.toString()); 539 | } 540 | } 541 | ``` 542 | 543 | 544 | ## 建造者(Builder)模式的优缺点 545 | 546 | ### 优点 547 | 548 | * 封装性,使用建造者模式客户端不必知道产品内部的组成的细节。 549 | * 建造者独立,容易拓展 550 | 551 | ### 缺点 552 | 553 | * 会产生多余的Builder对象以及Director对象,消耗内存。 554 | 555 | 556 | 557 | ## 后记 558 | 559 | 文章不足之处,望大家多多指点,共同学习,共同进步。 560 | 561 | 562 | 563 | ## 参考资料 564 | 565 | * ***<<设计模式之蝉>>*** 秦小波 著 566 | 567 | -------------------------------------------------------------------------------- /BuilderDesignPattern/BuilderUml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/BuilderDesignPattern/BuilderUml.png -------------------------------------------------------------------------------- /CommandPattern.md: -------------------------------------------------------------------------------- 1 | title: 命令模式 2 | date: 2016-09-08 09:29:13 3 | tags: Java 设计模式 4 | 5 | **摘要:** 6 | 7 | 本篇主要内容是Java设计模式之命令模式(Command Pattern)。 8 | 9 |    10 | 11 | ## 前言 12 | 13 | ​ 正所谓只要功夫深,铁杵磨成针,坚持不懈,水滴石穿。学习也要坚持不懈,慢慢积累,才能达到以量变促成质变。在前进的过程中也要保持好良好的心态,不急不燥,脚踏实地,一步一个脚印。 14 | 15 | ## 命令模式介绍 16 | 17 | ​ 命令模式(Command Pattern)是一种**行为型**设计模式。是一种高内聚的模式。命令模式相较于其他设计模式更为灵活多变。命令模式听名字就知道其关键点就是命令,在GUI开发中,命令模式的使用频率比较高一点,比如:一个按钮的点击是一个命令,我们可以采用命令模式。 18 | 19 | ## 命令模式定义 20 | 21 | ​ 将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。 22 | 23 | ## 命令模式使用场景 24 | 25 | * 使用场景非常广泛,只要你认为是命令的地方你就可以采用命令模式。 26 | * 触发——反馈机制的处理。 27 | 28 | ## 命令模式通用UML类图 29 | 30 | ![mlms1](CommandPattern/mlms1.png) 31 | 32 | **说明:** 33 | 34 | * **Receiver** 35 | 36 | 接收角色,执行具体逻辑的角色。 37 | 38 | * **Command** 39 | 40 | 命令角色,需要执行的所有命令都在这里声明,是所有具体命令类的抽象接口。 41 | 42 | * **ConcreteCommand** 43 | 44 | 具体的命令角色,实现Command接口。 45 | 46 | * **Invoker** 47 | 48 | 调用者角色,接收到命令,并执行命令 49 | 50 | * **Client** 51 | 52 | 客户端角色。 53 | 54 | ## 命令模式使用实例 55 | 56 | ​ 在安卓开发中,我们经常会使用第三方登录,这里我们就用开发第三方登录为简单示例。 57 | 58 | 1. Receiver接收者角色。 59 | 60 | ```java 61 | package iuni.life; 62 | 63 | /** 64 | * Created by iuni.life on 2016/10/17. 65 | * yangfei's computer 66 | * 接受者角色 67 | */ 68 | public class Receiver { 69 | public void qQLogin() { 70 | System.out.println("QQ登录"); 71 | } 72 | 73 | public void weChatLogin() { 74 | System.out.println("微信登录"); 75 | } 76 | 77 | public void weiBoLogin() { 78 | System.out.println("新浪微博登录"); 79 | } 80 | 81 | public void baiDuLogin() { 82 | System.out.println("百度登录"); 83 | } 84 | } 85 | 86 | ``` 87 | 88 | ​ 89 | 90 | 2. Command 抽象命令角色。 91 | 92 | ```java 93 | package iuni.life; 94 | 95 | /** 96 | * Created by iuni.life on 2016/9/22. 97 | * yangfei's computer 98 | * 抽象命令角色 99 | */ 100 | public interface Command { 101 | void execute(); 102 | } 103 | 104 | ``` 105 | 106 | ​ 107 | 108 | 3. QQLogin 具体命令角色。 109 | 110 | ```java 111 | package iuni.life; 112 | 113 | /** 114 | * Created by iuni.life on 2016/10/17. 115 | * yangfei's computer 116 | */ 117 | public class QQLogin implements Command { 118 | private Receiver receiver; 119 | 120 | public QQLogin(Receiver receiver) { 121 | this.receiver = receiver; 122 | } 123 | 124 | @Override 125 | public void execute() { 126 | receiver.qQLogin(); 127 | } 128 | } 129 | 130 | ``` 131 | 132 | ​ 133 | 134 | 4. WeChatLogin 具体命令角色。 135 | 136 | ```java 137 | package iuni.life; 138 | 139 | /** 140 | * Created by iuni.life on 2016/10/17. 141 | * yangfei's computer 142 | */ 143 | public class WeChatLogin implements Command { 144 | private Receiver receiver; 145 | 146 | public WeChatLogin(Receiver receiver) { 147 | this.receiver = receiver; 148 | } 149 | 150 | @Override 151 | public void execute() { 152 | receiver.weChatLogin(); 153 | } 154 | } 155 | 156 | ``` 157 | 158 | ​ 159 | 160 | 5. WeiBoLogin 具体命令角色。 161 | 162 | ```java 163 | package iuni.life; 164 | 165 | /** 166 | * Created by iuni.life on 2016/10/17. 167 | * yangfei's computer 168 | * 具体命令角色类 169 | */ 170 | public class WeiBoLogin implements Command { 171 | private Receiver receiver; 172 | 173 | public WeiBoLogin(Receiver receiver) { 174 | this.receiver = receiver; 175 | } 176 | 177 | @Override 178 | public void execute() { 179 | receiver.weiBoLogin(); 180 | } 181 | } 182 | 183 | ``` 184 | 185 | ​ 186 | 187 | 6. BaiduLogin 具体命令角色。 188 | 189 | ```java 190 | package iuni.life; 191 | 192 | /** 193 | * Created by iuni.life on 2016/10/17. 194 | * yangfei's computer 195 | */ 196 | public class BaiduLogin implements Command { 197 | private Receiver receiver; 198 | 199 | public BaiduLogin(Receiver receiver) { 200 | this.receiver = receiver; 201 | } 202 | 203 | @Override 204 | public void execute() { 205 | receiver.baiDuLogin(); 206 | } 207 | } 208 | 209 | ``` 210 | 211 | ​ 212 | 213 | 7. Client 客户端角色类 214 | 215 | ```java 216 | package iuni.life; 217 | 218 | /** 219 | * Created by iuni.life on 2016/10/17. 220 | * yangfei's computer 221 | * 客户端角色类 222 | */ 223 | public class Client { 224 | public static void main(String[] args) { 225 | //创建接受者 226 | Receiver receiver = new Receiver(); 227 | //创建命令对象 228 | Command QQCommand = new QQLogin(receiver); 229 | Command weChatCommand = new WeChatLogin(receiver); 230 | Command weiBoCommand = new WeiBoLogin(receiver); 231 | Command baiduCommand = new BaiduLogin(receiver); 232 | //创建请求者 233 | Invoker invoker = new Invoker(QQCommand); 234 | invoker = new Invoker(weChatCommand); 235 | invoker = new Invoker(weiBoCommand); 236 | invoker = new Invoker(baiduCommand); 237 | //执行方法 238 | invoker.allAction(); 239 | System.out.println("------------------我是华丽的分割线-------------------------------"); 240 | invoker.removeAction(baiduCommand); 241 | System.out.println("------------------我是华丽的分割线-------------------------------"); 242 | invoker.allAction(); 243 | } 244 | } 245 | 246 | 247 | ``` 248 | 249 | ​ 250 | 251 | 8. 运行结果。 252 | 253 | ![mlms2](CommandPattern/mlms2.png) 254 | 255 | 256 | 257 | ## 命令模式优缺点 258 | 259 | ### 优点 260 | 261 | * **类间解耦** 262 | 263 | 调用者与接收者之间没有任何依赖关系。调用者实现功能时只需要调用Command抽象类的execute方法就可以了,不需要了解到底是哪个接收者执行。 264 | 265 | * **可拓展性** 266 | 267 | Command的子类可以非常容易的拓展,而调用者Invoker和高层次的模块Client不产生严重的代码耦合。 268 | 269 | * **结合其他设计模式会更优秀** 270 | 271 | 命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,可以减少Command子类膨胀的问题。 272 | 273 | ### 缺点 274 | 275 | * 如果有N个命令,Command子类就是N个,子类膨胀的非常大。 276 | 277 | ## 后记 278 | 279 | ​ 文章不足之处,望大家多多指点,共同学习,共同进步。 280 | 281 | ## 参考资料 282 | 283 | - ***<<设计模式之蝉>>*** 秦小波 著 284 | 285 | ## 个人博客 286 | 287 | 如想获得更好阅读体验,请访问个人博客网站:[iplugin.cn](http://www.iplugin.cn) 288 | -------------------------------------------------------------------------------- /CommandPattern/mlms1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/CommandPattern/mlms1.png -------------------------------------------------------------------------------- /CommandPattern/mlms2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/CommandPattern/mlms2.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DesignPattern 2 | 3 | Java 设计模式有23种,分三大类,创建型的五种,结构型的七种,行为型的十一种。 4 | 5 | 其他设计有模式:MVC,MVP,MVVM。 6 | 7 | ## 创建型模式 8 | * [建造者(Builder)模式](https://github.com/OriginalLove/DesignPattern/blob/master/BuilderDesignPattern.md) 9 | * [原型模式](https://github.com/OriginalLove/DesignPattern/blob/master/%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F.md) 10 | * [工厂方法模式](https://github.com/OriginalLove/DesignPattern/blob/master/%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F.md) 11 | * 抽象工厂模式 12 | * 单例模式 13 | 14 | 15 | ## 结构型模式 16 | 17 | * 适配器模式 18 | * 装饰模式 19 | * 代理模式 20 | * 外观模式(门面模式) 21 | * 桥接模式 22 | * 组合模式 23 | * 享元模式 24 | 25 | ## 行为型模式 26 | 27 | * [策略模式](https://github.com/OriginalLove/DesignPattern/blob/master/%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F.md) 28 | * 模板方法模式 29 | * [观察者模式](https://github.com/OriginalLove/DesignPattern/blob/master/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F.md) 30 | * 迭代器模式 31 | * 责任链模式 32 | * [命令模式](https://github.com/OriginalLove/DesignPattern/blob/master/CommandPattern.md) 33 | * 备忘录模式 34 | * 状态模式 35 | * 访问者模式 36 | * 中介者模式 37 | * 解释器模式 38 | 39 | ## 其他 40 | 41 | * MVC 42 | * MVP 43 | * MVVM 44 | 45 | 46 | 47 | # 个人网站 48 | [iplugin.cn](http://www.iplugin.cn) 49 | -------------------------------------------------------------------------------- /原型模式.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Android 原型模式 3 | date: 2016-08-08 12:58:55 4 | tags: Java 设计模式 5 | --- 6 | 7 | **摘要:** 8 | 9 | Java设计模式之原型模式。 10 | 11 |    12 | 13 | ## 前言 14 | 15 | 正所谓只要功夫深,铁杵磨成针,坚持不懈,水滴石穿。学习也要坚持不懈,慢慢积累,才能达到以量变促成质变。在前进的过程中也要保持好良好的心态,不急不燥,脚踏实地,一步一个脚印。 16 | 17 | ## 原型模式 介绍 18 | 19 | 原型模式是一个**创建型**的模式。原型二字即可表明该模式有一个样板实例,用户可以从这个样板的对象中复制一个与该对象内部属性一致的对象,也就是我们所说的克隆。 20 | 21 | ## 原型模式 定义 22 | 23 | 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 24 | 25 | ## 原型模式 使用场景 26 | 27 | * **资源优化场景** 28 | 29 | 类初始化需要消耗非常多的资源,这个资源包括数据、硬件资源等。 30 | 31 | * **性能和安全要求的场景** 32 | 33 | 通过new产生一个对象需要非常繁琐的数据准备或访问权限。 34 | 35 | * **一个对象多个修改者的场景** 36 | 37 | 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。 38 | 39 | **说明** 40 | 41 | 原型模式已经与Java融为一体,大家可以随手拿来使用。 42 | 43 | ## 原型模式 通用UML类图 44 | 45 | ![原型模式通用UML](原型模式/原型模式.png) 46 | 47 | **角色介绍** 48 | 49 | * **client:** 客户端用户。 50 | * **Prototype:** 抽象类或者接口,声明具备clone能力。 51 | * **ConcretePrototype:** 具体的原型类。 52 | 53 | ## 原型模式使用实例 54 | 55 | 原型模式一般是要实现cloneable接口,并且重写clone方法,现在我们以文档拷贝来演示一个原型模式的实现。 56 | 57 | ***注意:*** clone 方法并不是Cloneable中的,而是Object中的方法,Cloneable 是一个标识接口,它表明这个类的对象是可以拷贝的。如果没有实现Cloneable接口却调用了clone()函数将抛出异常。 58 | 59 | 1. ConcretePrototype 角色 60 | 61 | ```java 62 | /** 63 | * Created by iuni.life on 16/8/5. 64 | * 文档类型,扮演的是ConCretePrototype角色,而cloneable是代表prototype角色 65 | */ 66 | public class WordDocument implements Cloneable { 67 | //文本 68 | private String mText; 69 | //图片列表 70 | private ArrayList mImages = new ArrayList<>(); 71 | private HashMap hashMap = new HashMap<>(); 72 | 73 | public WordDocument() { 74 | System.out.println("---------------WordDocument构造函数--------------------"); 75 | } 76 | 77 | @Override 78 | protected WordDocument clone() { 79 | try { 80 | WordDocument document = (WordDocument) super.clone(); 81 | document.mText = this.mText; 82 | document.mImages = this.mImages; 83 | document.hashMap = this.hashMap; 84 | return document; 85 | } catch (Exception e) { 86 | 87 | } 88 | 89 | return null; 90 | } 91 | 92 | public HashMap getHashMap() { 93 | return hashMap; 94 | } 95 | 96 | public void setHashMap(HashMap hashMap) { 97 | this.hashMap = hashMap; 98 | } 99 | 100 | public void addMap(String key, String value) { 101 | hashMap.put(key, value); 102 | } 103 | 104 | public String getmText() { 105 | return mText; 106 | } 107 | 108 | public void setmText(String mText) { 109 | this.mText = mText; 110 | } 111 | 112 | public ArrayList getmImages() { 113 | return mImages; 114 | } 115 | 116 | public void setmImages(ArrayList mImages) { 117 | this.mImages = mImages; 118 | } 119 | 120 | public void addImages(String image) { 121 | this.mImages.add(image); 122 | } 123 | 124 | //打印文档内容 125 | public void showDocument() { 126 | System.out.println("---------Word Content Start---------------"); 127 | System.out.println("Text:" + mText); 128 | System.out.println("Images List:"); 129 | for (String imgName : mImages) { 130 | System.out.println("image name :" + imgName); 131 | } 132 | System.out.println("hashMap:"); 133 | for (String key : hashMap.keySet()) { 134 | System.out.println(key + ":" + hashMap.get(key)); 135 | 136 | } 137 | 138 | System.out.println("---------Word Content End---------------"); 139 | } 140 | } 141 | ``` 142 | 143 | 2. 测试Client类 144 | 145 | ```java 146 | /** 147 | * Created by iuni.life on 16/8/5. 148 | */ 149 | public class Client { 150 | public static void main(String[] args) { 151 | //构建文档对象 152 | WordDocument originDoc = new WordDocument(); 153 | originDoc.setmText("这是一篇文档"); 154 | originDoc.addImages("图片1"); 155 | originDoc.addImages("图片2"); 156 | originDoc.addImages("图片3"); 157 | originDoc.addMap("yi", "ui"); 158 | originDoc.showDocument(); 159 | 160 | //一万原始文档为模板,拷贝一份副本 161 | WordDocument doc2 = originDoc.clone(); 162 | originDoc.showDocument(); 163 | //修改文档副本,不会影响原始文档 164 | doc2.setmText("这是修改过的文本"); 165 | doc2.showDocument(); 166 | 167 | originDoc.showDocument(); 168 | } 169 | } 170 | ``` 171 | 172 | ​ 173 | 174 | 3. 运行结果 175 | 176 | ![client 运行结果](原型模式/result1.png) 177 | 178 | ***说明:*** 通过运行结果可以知道doc2是通过originDoc.clone创建的,并且doc2首次输出的时候和originDoc 是一样的结果,即doc2是originDoc 的一个拷贝,而doc2得文本内容更改后,originDoc的文本并没有变化,并没有受到影响,这样就保证了originDoc的安全性.。 179 | 180 | **注意:** 通过clone拷贝对象的时候并不会执行构造函数。如果在构造函数中有需要一些特殊的初始化,在使用Cloneable实现拷贝的时候,需要注意这一点。 181 | 182 | ​ 183 | ## 原型模式的深拷贝和浅拷贝 184 | 185 | ### 浅拷贝 186 | 187 | 上述原型模式的实例其实是一个浅拷贝,也叫影子拷贝,这种拷贝实际上并不是将原始文档的所有字段都重新构造一份,而是将副本文档的字段引用原始文档的字段。 188 | 189 | 比如改变上述client类中Image List的值: 190 | 191 | ```java 192 | /** 193 | * Created by iuni.life on 16/8/5. 194 | */ 195 | public class Client { 196 | public static void main(String[] args) { 197 | //构建文档对象 198 | WordDocument originDoc = new WordDocument(); 199 | originDoc.setmText("这是一篇文档"); 200 | originDoc.addImages("图片1"); 201 | originDoc.addImages("图片2"); 202 | originDoc.addImages("图片3"); 203 | originDoc.addMap("yi", "ui"); 204 | originDoc.showDocument(); 205 | 206 | //一万原始文档为模板,拷贝一份副本 207 | WordDocument doc2 = originDoc.clone(); 208 | originDoc.showDocument(); 209 | //修改文档副本,不会影响原始文档 210 | doc2.setmText("这是修改过的文本"); 211 | //doc2 新增自己的图片 212 | doc2.addImages("这是doc2添加的图片"); 213 | doc2.showDocument(); 214 | 215 | originDoc.showDocument(); 216 | } 217 | } 218 | ``` 219 | 220 | 执行结果为: 221 | 222 | ![浅拷贝执行结果](原型模式/result2.png) 223 | 224 | 从图中可以看到doc2新增的图片,originDoc 也新增了同样的一张图片,那么如何解决这个问题呢,那就需要深拷贝。 225 | 226 | ### 深拷贝 227 | 228 | 那什么是深拷贝呢,两个对象之间没有任何瓜葛,你修改你的,我修改我的,不相互影响,对于引用类型的字段也要采用拷贝的形式,而不是单纯引用的形式,这才叫深拷贝。 229 | 230 | 下面我们只需修改上述例子的ConcretePrototype 角色**WordDocument类**中的clone方法,以实现深拷贝: 231 | 232 | ```java 233 | @Override 234 | protected WordDocument clone() { 235 | try { 236 | WordDocument document = (WordDocument) super.clone(); 237 | document.mText = this.mText; 238 | // document.mImages=this.mImages; 239 | // document.hashMap=this.hashMap; 240 | //对MImages对象也调用clone对象,进行深拷贝 241 | document.mImages = (ArrayList) this.mImages.clone(); 242 | document.hashMap = (HashMap) this.hashMap.clone(); 243 | return document; 244 | } catch (Exception e) { 245 | 246 | } 247 | 248 | return null; 249 | } 250 | ``` 251 | 252 | client不动,运行后的结果为: 253 | 254 | ![深拷贝运行结果](原型模式/result3.png) 255 | 256 | 从上述图片可以看到doc2添加了图片,originDoc并没有受到影响,doc2新增的图片在originDoc中并没有找到。 257 | 258 | **建议:** 在开发过程中,为了减少错误,建议大家使用深拷贝,避免因操作副本影响原始对象。 259 | 260 | ## 原型模式优缺点 261 | 262 | ### 优点 263 | 264 | * **性能优良** 265 | 266 | 原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是在一个循环体内产生大量的对象时,原型模式可以更好的体现其优点。 267 | 268 | ### 缺点 269 | 270 | ​ 这既是优点也是缺点,直接在内存中拷贝,构造函数不会执行。优点是减少了约束,缺点也是减少了约束,大家在实际应用中应该需要考虑这一点。 271 | 272 | ## 后记 273 | 274 | 文章不足之处,望大家多多指点,共同学习,共同进步。 275 | 276 | ## 参考资料 277 | 278 | - ***<<设计模式之蝉>>*** 秦小波 著 279 | 280 | 281 | 282 | ## 个人博客 283 | 284 | [iplugin.cn](http://www.iplugin.cn) 285 | 286 | -------------------------------------------------------------------------------- /原型模式/result1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/原型模式/result1.png -------------------------------------------------------------------------------- /原型模式/result2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/原型模式/result2.png -------------------------------------------------------------------------------- /原型模式/result3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/原型模式/result3.png -------------------------------------------------------------------------------- /原型模式/原型模式.mdj: -------------------------------------------------------------------------------- 1 | { 2 | "_type": "Project", 3 | "_id": "AAAAAAFF+h6SjaM2Hec=", 4 | "name": "Untitled", 5 | "ownedElements": [ 6 | { 7 | "_type": "UMLModel", 8 | "_id": "AAAAAAFF+qBWK6M3Z8Y=", 9 | "_parent": { 10 | "$ref": "AAAAAAFF+h6SjaM2Hec=" 11 | }, 12 | "name": "Model", 13 | "ownedElements": [ 14 | { 15 | "_type": "UMLClassDiagram", 16 | "_id": "AAAAAAFF+qBtyKM79qY=", 17 | "_parent": { 18 | "$ref": "AAAAAAFF+qBWK6M3Z8Y=" 19 | }, 20 | "name": "Main", 21 | "visible": true, 22 | "defaultDiagram": true, 23 | "ownedViews": [ 24 | { 25 | "_type": "UMLClassView", 26 | "_id": "AAAAAAFWaJwnUrEUQ8A=", 27 | "_parent": { 28 | "$ref": "AAAAAAFF+qBtyKM79qY=" 29 | }, 30 | "model": { 31 | "$ref": "AAAAAAFWaJwnULESI68=" 32 | }, 33 | "subViews": [ 34 | { 35 | "_type": "UMLNameCompartmentView", 36 | "_id": "AAAAAAFWaJwnU7EV/z8=", 37 | "_parent": { 38 | "$ref": "AAAAAAFWaJwnUrEUQ8A=" 39 | }, 40 | "model": { 41 | "$ref": "AAAAAAFWaJwnULESI68=" 42 | }, 43 | "subViews": [ 44 | { 45 | "_type": "LabelView", 46 | "_id": "AAAAAAFWaJwnU7EWQsI=", 47 | "_parent": { 48 | "$ref": "AAAAAAFWaJwnU7EV/z8=" 49 | }, 50 | "visible": false, 51 | "enabled": true, 52 | "lineColor": "#000000", 53 | "fillColor": "#ffffff", 54 | "fontColor": "#000000", 55 | "font": "Arial;13;0", 56 | "showShadow": true, 57 | "containerChangeable": false, 58 | "containerExtending": false, 59 | "left": 80, 60 | "top": -16, 61 | "width": 0, 62 | "height": 13, 63 | "autoResize": false, 64 | "underline": false, 65 | "horizontalAlignment": 2, 66 | "verticalAlignment": 5 67 | }, 68 | { 69 | "_type": "LabelView", 70 | "_id": "AAAAAAFWaJwnU7EXYK0=", 71 | "_parent": { 72 | "$ref": "AAAAAAFWaJwnU7EV/z8=" 73 | }, 74 | "visible": true, 75 | "enabled": true, 76 | "lineColor": "#000000", 77 | "fillColor": "#ffffff", 78 | "fontColor": "#000000", 79 | "font": "Arial;13;1", 80 | "showShadow": true, 81 | "containerChangeable": false, 82 | "containerExtending": false, 83 | "left": 173, 84 | "top": 447, 85 | "width": 143, 86 | "height": 13, 87 | "autoResize": false, 88 | "underline": false, 89 | "text": "Prototype", 90 | "horizontalAlignment": 2, 91 | "verticalAlignment": 5 92 | }, 93 | { 94 | "_type": "LabelView", 95 | "_id": "AAAAAAFWaJwnVLEYryo=", 96 | "_parent": { 97 | "$ref": "AAAAAAFWaJwnU7EV/z8=" 98 | }, 99 | "visible": false, 100 | "enabled": true, 101 | "lineColor": "#000000", 102 | "fillColor": "#ffffff", 103 | "fontColor": "#000000", 104 | "font": "Arial;13;0", 105 | "showShadow": true, 106 | "containerChangeable": false, 107 | "containerExtending": false, 108 | "left": 80, 109 | "top": -16, 110 | "width": 73, 111 | "height": 13, 112 | "autoResize": false, 113 | "underline": false, 114 | "text": "(from Model)", 115 | "horizontalAlignment": 2, 116 | "verticalAlignment": 5 117 | }, 118 | { 119 | "_type": "LabelView", 120 | "_id": "AAAAAAFWaJwnVLEZH94=", 121 | "_parent": { 122 | "$ref": "AAAAAAFWaJwnU7EV/z8=" 123 | }, 124 | "visible": false, 125 | "enabled": true, 126 | "lineColor": "#000000", 127 | "fillColor": "#ffffff", 128 | "fontColor": "#000000", 129 | "font": "Arial;13;0", 130 | "showShadow": true, 131 | "containerChangeable": false, 132 | "containerExtending": false, 133 | "left": 80, 134 | "top": -16, 135 | "width": 0, 136 | "height": 13, 137 | "autoResize": false, 138 | "underline": false, 139 | "horizontalAlignment": 1, 140 | "verticalAlignment": 5 141 | } 142 | ], 143 | "visible": true, 144 | "enabled": true, 145 | "lineColor": "#000000", 146 | "fillColor": "#ffffff", 147 | "fontColor": "#000000", 148 | "font": "Arial;13;0", 149 | "showShadow": true, 150 | "containerChangeable": false, 151 | "containerExtending": false, 152 | "left": 168, 153 | "top": 440, 154 | "width": 153, 155 | "height": 25, 156 | "autoResize": false, 157 | "stereotypeLabel": { 158 | "$ref": "AAAAAAFWaJwnU7EWQsI=" 159 | }, 160 | "nameLabel": { 161 | "$ref": "AAAAAAFWaJwnU7EXYK0=" 162 | }, 163 | "namespaceLabel": { 164 | "$ref": "AAAAAAFWaJwnVLEYryo=" 165 | }, 166 | "propertyLabel": { 167 | "$ref": "AAAAAAFWaJwnVLEZH94=" 168 | } 169 | }, 170 | { 171 | "_type": "UMLAttributeCompartmentView", 172 | "_id": "AAAAAAFWaJwnVLEa1fU=", 173 | "_parent": { 174 | "$ref": "AAAAAAFWaJwnUrEUQ8A=" 175 | }, 176 | "model": { 177 | "$ref": "AAAAAAFWaJwnULESI68=" 178 | }, 179 | "visible": true, 180 | "enabled": true, 181 | "lineColor": "#000000", 182 | "fillColor": "#ffffff", 183 | "fontColor": "#000000", 184 | "font": "Arial;13;0", 185 | "showShadow": true, 186 | "containerChangeable": false, 187 | "containerExtending": false, 188 | "left": 168, 189 | "top": 465, 190 | "width": 153, 191 | "height": 10, 192 | "autoResize": false 193 | }, 194 | { 195 | "_type": "UMLOperationCompartmentView", 196 | "_id": "AAAAAAFWaJwnVLEbDbc=", 197 | "_parent": { 198 | "$ref": "AAAAAAFWaJwnUrEUQ8A=" 199 | }, 200 | "model": { 201 | "$ref": "AAAAAAFWaJwnULESI68=" 202 | }, 203 | "subViews": [ 204 | { 205 | "_type": "UMLOperationView", 206 | "_id": "AAAAAAFWaJyIMrFBttM=", 207 | "_parent": { 208 | "$ref": "AAAAAAFWaJwnVLEbDbc=" 209 | }, 210 | "model": { 211 | "$ref": "AAAAAAFWaJyIEbE+8Hg=" 212 | }, 213 | "visible": true, 214 | "enabled": true, 215 | "lineColor": "#000000", 216 | "fillColor": "#ffffff", 217 | "fontColor": "#000000", 218 | "font": "Arial;13;0", 219 | "showShadow": true, 220 | "containerChangeable": false, 221 | "containerExtending": false, 222 | "left": 173, 223 | "top": 480, 224 | "width": 143, 225 | "height": 13, 226 | "autoResize": false, 227 | "underline": false, 228 | "text": "+clone()", 229 | "horizontalAlignment": 0, 230 | "verticalAlignment": 5 231 | } 232 | ], 233 | "visible": true, 234 | "enabled": true, 235 | "lineColor": "#000000", 236 | "fillColor": "#ffffff", 237 | "fontColor": "#000000", 238 | "font": "Arial;13;0", 239 | "showShadow": true, 240 | "containerChangeable": false, 241 | "containerExtending": false, 242 | "left": 168, 243 | "top": 475, 244 | "width": 153, 245 | "height": 23, 246 | "autoResize": false 247 | }, 248 | { 249 | "_type": "UMLReceptionCompartmentView", 250 | "_id": "AAAAAAFWaJwnVLEcLv8=", 251 | "_parent": { 252 | "$ref": "AAAAAAFWaJwnUrEUQ8A=" 253 | }, 254 | "model": { 255 | "$ref": "AAAAAAFWaJwnULESI68=" 256 | }, 257 | "visible": false, 258 | "enabled": true, 259 | "lineColor": "#000000", 260 | "fillColor": "#ffffff", 261 | "fontColor": "#000000", 262 | "font": "Arial;13;0", 263 | "showShadow": true, 264 | "containerChangeable": false, 265 | "containerExtending": false, 266 | "left": 40, 267 | "top": -8, 268 | "width": 10, 269 | "height": 10, 270 | "autoResize": false 271 | }, 272 | { 273 | "_type": "UMLTemplateParameterCompartmentView", 274 | "_id": "AAAAAAFWaJwnVbEdi3I=", 275 | "_parent": { 276 | "$ref": "AAAAAAFWaJwnUrEUQ8A=" 277 | }, 278 | "model": { 279 | "$ref": "AAAAAAFWaJwnULESI68=" 280 | }, 281 | "visible": false, 282 | "enabled": true, 283 | "lineColor": "#000000", 284 | "fillColor": "#ffffff", 285 | "fontColor": "#000000", 286 | "font": "Arial;13;0", 287 | "showShadow": true, 288 | "containerChangeable": false, 289 | "containerExtending": false, 290 | "left": 40, 291 | "top": -8, 292 | "width": 10, 293 | "height": 10, 294 | "autoResize": false 295 | } 296 | ], 297 | "visible": true, 298 | "enabled": true, 299 | "lineColor": "#000000", 300 | "fillColor": "#ffffff", 301 | "fontColor": "#000000", 302 | "font": "Arial;13;0", 303 | "showShadow": true, 304 | "containerChangeable": true, 305 | "containerExtending": false, 306 | "left": 168, 307 | "top": 440, 308 | "width": 153, 309 | "height": 65, 310 | "autoResize": false, 311 | "stereotypeDisplay": "label", 312 | "showVisibility": true, 313 | "showNamespace": false, 314 | "showProperty": true, 315 | "showType": true, 316 | "nameCompartment": { 317 | "$ref": "AAAAAAFWaJwnU7EV/z8=" 318 | }, 319 | "wordWrap": false, 320 | "suppressAttributes": false, 321 | "suppressOperations": false, 322 | "suppressReceptions": true, 323 | "showMultiplicity": true, 324 | "showOperationSignature": true, 325 | "attributeCompartment": { 326 | "$ref": "AAAAAAFWaJwnVLEa1fU=" 327 | }, 328 | "operationCompartment": { 329 | "$ref": "AAAAAAFWaJwnVLEbDbc=" 330 | }, 331 | "receptionCompartment": { 332 | "$ref": "AAAAAAFWaJwnVLEcLv8=" 333 | }, 334 | "templateParameterCompartment": { 335 | "$ref": "AAAAAAFWaJwnVbEdi3I=" 336 | } 337 | }, 338 | { 339 | "_type": "UMLClassView", 340 | "_id": "AAAAAAFWaJ0bDbFIU+k=", 341 | "_parent": { 342 | "$ref": "AAAAAAFF+qBtyKM79qY=" 343 | }, 344 | "model": { 345 | "$ref": "AAAAAAFWaJ0bDLFGkl8=" 346 | }, 347 | "subViews": [ 348 | { 349 | "_type": "UMLNameCompartmentView", 350 | "_id": "AAAAAAFWaJ0bDrFJriM=", 351 | "_parent": { 352 | "$ref": "AAAAAAFWaJ0bDbFIU+k=" 353 | }, 354 | "model": { 355 | "$ref": "AAAAAAFWaJ0bDLFGkl8=" 356 | }, 357 | "subViews": [ 358 | { 359 | "_type": "LabelView", 360 | "_id": "AAAAAAFWaJ0bDrFKx6g=", 361 | "_parent": { 362 | "$ref": "AAAAAAFWaJ0bDrFJriM=" 363 | }, 364 | "visible": false, 365 | "enabled": true, 366 | "lineColor": "#000000", 367 | "fillColor": "#ffffff", 368 | "fontColor": "#000000", 369 | "font": "Arial;13;0", 370 | "showShadow": true, 371 | "containerChangeable": false, 372 | "containerExtending": false, 373 | "left": 32, 374 | "top": 0, 375 | "width": 0, 376 | "height": 13, 377 | "autoResize": false, 378 | "underline": false, 379 | "horizontalAlignment": 2, 380 | "verticalAlignment": 5 381 | }, 382 | { 383 | "_type": "LabelView", 384 | "_id": "AAAAAAFWaJ0bDrFLbzU=", 385 | "_parent": { 386 | "$ref": "AAAAAAFWaJ0bDrFJriM=" 387 | }, 388 | "visible": true, 389 | "enabled": true, 390 | "lineColor": "#000000", 391 | "fillColor": "#ffffff", 392 | "fontColor": "#000000", 393 | "font": "Arial;13;1", 394 | "showShadow": true, 395 | "containerChangeable": false, 396 | "containerExtending": false, 397 | "left": 29, 398 | "top": 463, 399 | "width": 41, 400 | "height": 13, 401 | "autoResize": false, 402 | "underline": false, 403 | "text": "Client", 404 | "horizontalAlignment": 2, 405 | "verticalAlignment": 5 406 | }, 407 | { 408 | "_type": "LabelView", 409 | "_id": "AAAAAAFWaJ0bD7FMDcA=", 410 | "_parent": { 411 | "$ref": "AAAAAAFWaJ0bDrFJriM=" 412 | }, 413 | "visible": false, 414 | "enabled": true, 415 | "lineColor": "#000000", 416 | "fillColor": "#ffffff", 417 | "fontColor": "#000000", 418 | "font": "Arial;13;0", 419 | "showShadow": true, 420 | "containerChangeable": false, 421 | "containerExtending": false, 422 | "left": 32, 423 | "top": 0, 424 | "width": 73, 425 | "height": 13, 426 | "autoResize": false, 427 | "underline": false, 428 | "text": "(from Model)", 429 | "horizontalAlignment": 2, 430 | "verticalAlignment": 5 431 | }, 432 | { 433 | "_type": "LabelView", 434 | "_id": "AAAAAAFWaJ0bD7FNlMI=", 435 | "_parent": { 436 | "$ref": "AAAAAAFWaJ0bDrFJriM=" 437 | }, 438 | "visible": false, 439 | "enabled": true, 440 | "lineColor": "#000000", 441 | "fillColor": "#ffffff", 442 | "fontColor": "#000000", 443 | "font": "Arial;13;0", 444 | "showShadow": true, 445 | "containerChangeable": false, 446 | "containerExtending": false, 447 | "left": 32, 448 | "top": 0, 449 | "width": 0, 450 | "height": 13, 451 | "autoResize": false, 452 | "underline": false, 453 | "horizontalAlignment": 1, 454 | "verticalAlignment": 5 455 | } 456 | ], 457 | "visible": true, 458 | "enabled": true, 459 | "lineColor": "#000000", 460 | "fillColor": "#ffffff", 461 | "fontColor": "#000000", 462 | "font": "Arial;13;0", 463 | "showShadow": true, 464 | "containerChangeable": false, 465 | "containerExtending": false, 466 | "left": 24, 467 | "top": 456, 468 | "width": 51, 469 | "height": 25, 470 | "autoResize": false, 471 | "stereotypeLabel": { 472 | "$ref": "AAAAAAFWaJ0bDrFKx6g=" 473 | }, 474 | "nameLabel": { 475 | "$ref": "AAAAAAFWaJ0bDrFLbzU=" 476 | }, 477 | "namespaceLabel": { 478 | "$ref": "AAAAAAFWaJ0bD7FMDcA=" 479 | }, 480 | "propertyLabel": { 481 | "$ref": "AAAAAAFWaJ0bD7FNlMI=" 482 | } 483 | }, 484 | { 485 | "_type": "UMLAttributeCompartmentView", 486 | "_id": "AAAAAAFWaJ0bD7FOL1c=", 487 | "_parent": { 488 | "$ref": "AAAAAAFWaJ0bDbFIU+k=" 489 | }, 490 | "model": { 491 | "$ref": "AAAAAAFWaJ0bDLFGkl8=" 492 | }, 493 | "visible": true, 494 | "enabled": true, 495 | "lineColor": "#000000", 496 | "fillColor": "#ffffff", 497 | "fontColor": "#000000", 498 | "font": "Arial;13;0", 499 | "showShadow": true, 500 | "containerChangeable": false, 501 | "containerExtending": false, 502 | "left": 24, 503 | "top": 481, 504 | "width": 51, 505 | "height": 10, 506 | "autoResize": false 507 | }, 508 | { 509 | "_type": "UMLOperationCompartmentView", 510 | "_id": "AAAAAAFWaJ0bD7FPOnE=", 511 | "_parent": { 512 | "$ref": "AAAAAAFWaJ0bDbFIU+k=" 513 | }, 514 | "model": { 515 | "$ref": "AAAAAAFWaJ0bDLFGkl8=" 516 | }, 517 | "visible": true, 518 | "enabled": true, 519 | "lineColor": "#000000", 520 | "fillColor": "#ffffff", 521 | "fontColor": "#000000", 522 | "font": "Arial;13;0", 523 | "showShadow": true, 524 | "containerChangeable": false, 525 | "containerExtending": false, 526 | "left": 24, 527 | "top": 491, 528 | "width": 51, 529 | "height": 10, 530 | "autoResize": false 531 | }, 532 | { 533 | "_type": "UMLReceptionCompartmentView", 534 | "_id": "AAAAAAFWaJ0bD7FQiQQ=", 535 | "_parent": { 536 | "$ref": "AAAAAAFWaJ0bDbFIU+k=" 537 | }, 538 | "model": { 539 | "$ref": "AAAAAAFWaJ0bDLFGkl8=" 540 | }, 541 | "visible": false, 542 | "enabled": true, 543 | "lineColor": "#000000", 544 | "fillColor": "#ffffff", 545 | "fontColor": "#000000", 546 | "font": "Arial;13;0", 547 | "showShadow": true, 548 | "containerChangeable": false, 549 | "containerExtending": false, 550 | "left": 16, 551 | "top": 0, 552 | "width": 10, 553 | "height": 10, 554 | "autoResize": false 555 | }, 556 | { 557 | "_type": "UMLTemplateParameterCompartmentView", 558 | "_id": "AAAAAAFWaJ0bELFRFs8=", 559 | "_parent": { 560 | "$ref": "AAAAAAFWaJ0bDbFIU+k=" 561 | }, 562 | "model": { 563 | "$ref": "AAAAAAFWaJ0bDLFGkl8=" 564 | }, 565 | "visible": false, 566 | "enabled": true, 567 | "lineColor": "#000000", 568 | "fillColor": "#ffffff", 569 | "fontColor": "#000000", 570 | "font": "Arial;13;0", 571 | "showShadow": true, 572 | "containerChangeable": false, 573 | "containerExtending": false, 574 | "left": 16, 575 | "top": 0, 576 | "width": 10, 577 | "height": 10, 578 | "autoResize": false 579 | } 580 | ], 581 | "visible": true, 582 | "enabled": true, 583 | "lineColor": "#000000", 584 | "fillColor": "#ffffff", 585 | "fontColor": "#000000", 586 | "font": "Arial;13;0", 587 | "showShadow": true, 588 | "containerChangeable": true, 589 | "containerExtending": false, 590 | "left": 24, 591 | "top": 456, 592 | "width": 51, 593 | "height": 45, 594 | "autoResize": false, 595 | "stereotypeDisplay": "label", 596 | "showVisibility": true, 597 | "showNamespace": false, 598 | "showProperty": true, 599 | "showType": true, 600 | "nameCompartment": { 601 | "$ref": "AAAAAAFWaJ0bDrFJriM=" 602 | }, 603 | "wordWrap": false, 604 | "suppressAttributes": false, 605 | "suppressOperations": false, 606 | "suppressReceptions": true, 607 | "showMultiplicity": true, 608 | "showOperationSignature": true, 609 | "attributeCompartment": { 610 | "$ref": "AAAAAAFWaJ0bD7FOL1c=" 611 | }, 612 | "operationCompartment": { 613 | "$ref": "AAAAAAFWaJ0bD7FPOnE=" 614 | }, 615 | "receptionCompartment": { 616 | "$ref": "AAAAAAFWaJ0bD7FQiQQ=" 617 | }, 618 | "templateParameterCompartment": { 619 | "$ref": "AAAAAAFWaJ0bELFRFs8=" 620 | } 621 | }, 622 | { 623 | "_type": "UMLAssociationView", 624 | "_id": "AAAAAAFWaJ2R/bF1rK8=", 625 | "_parent": { 626 | "$ref": "AAAAAAFF+qBtyKM79qY=" 627 | }, 628 | "model": { 629 | "$ref": "AAAAAAFWaJ2R+rFxwNM=" 630 | }, 631 | "subViews": [ 632 | { 633 | "_type": "EdgeLabelView", 634 | "_id": "AAAAAAFWaJ2R/rF2EvY=", 635 | "_parent": { 636 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 637 | }, 638 | "model": { 639 | "$ref": "AAAAAAFWaJ2R+rFxwNM=" 640 | }, 641 | "visible": false, 642 | "enabled": true, 643 | "lineColor": "#000000", 644 | "fillColor": "#ffffff", 645 | "fontColor": "#000000", 646 | "font": "Arial;13;0", 647 | "showShadow": true, 648 | "containerChangeable": false, 649 | "containerExtending": false, 650 | "left": 121, 651 | "top": 459, 652 | "width": 0, 653 | "height": 13, 654 | "autoResize": false, 655 | "alpha": 1.5707963267948966, 656 | "distance": 15, 657 | "hostEdge": { 658 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 659 | }, 660 | "edgePosition": 1, 661 | "underline": false, 662 | "horizontalAlignment": 2, 663 | "verticalAlignment": 5 664 | }, 665 | { 666 | "_type": "EdgeLabelView", 667 | "_id": "AAAAAAFWaJ2R/rF3mVw=", 668 | "_parent": { 669 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 670 | }, 671 | "model": { 672 | "$ref": "AAAAAAFWaJ2R+rFxwNM=" 673 | }, 674 | "visible": null, 675 | "enabled": true, 676 | "lineColor": "#000000", 677 | "fillColor": "#ffffff", 678 | "fontColor": "#000000", 679 | "font": "Arial;13;0", 680 | "showShadow": true, 681 | "containerChangeable": false, 682 | "containerExtending": false, 683 | "left": 121, 684 | "top": 444, 685 | "width": 0, 686 | "height": 13, 687 | "autoResize": false, 688 | "alpha": 1.5707963267948966, 689 | "distance": 30, 690 | "hostEdge": { 691 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 692 | }, 693 | "edgePosition": 1, 694 | "underline": false, 695 | "horizontalAlignment": 2, 696 | "verticalAlignment": 5 697 | }, 698 | { 699 | "_type": "EdgeLabelView", 700 | "_id": "AAAAAAFWaJ2R/rF4pSU=", 701 | "_parent": { 702 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 703 | }, 704 | "model": { 705 | "$ref": "AAAAAAFWaJ2R+rFxwNM=" 706 | }, 707 | "visible": false, 708 | "enabled": true, 709 | "lineColor": "#000000", 710 | "fillColor": "#ffffff", 711 | "fontColor": "#000000", 712 | "font": "Arial;13;0", 713 | "showShadow": true, 714 | "containerChangeable": false, 715 | "containerExtending": false, 716 | "left": 121, 717 | "top": 489, 718 | "width": 0, 719 | "height": 13, 720 | "autoResize": false, 721 | "alpha": -1.5707963267948966, 722 | "distance": 15, 723 | "hostEdge": { 724 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 725 | }, 726 | "edgePosition": 1, 727 | "underline": false, 728 | "horizontalAlignment": 2, 729 | "verticalAlignment": 5 730 | }, 731 | { 732 | "_type": "EdgeLabelView", 733 | "_id": "AAAAAAFWaJ2R/rF5AMc=", 734 | "_parent": { 735 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 736 | }, 737 | "model": { 738 | "$ref": "AAAAAAFWaJ2R+7Fywfc=" 739 | }, 740 | "visible": false, 741 | "enabled": true, 742 | "lineColor": "#000000", 743 | "fillColor": "#ffffff", 744 | "fontColor": "#000000", 745 | "font": "Arial;13;0", 746 | "showShadow": true, 747 | "containerChangeable": false, 748 | "containerExtending": false, 749 | "left": 99, 750 | "top": 459, 751 | "width": 0, 752 | "height": 13, 753 | "autoResize": false, 754 | "alpha": 0.5235987755982988, 755 | "distance": 30, 756 | "hostEdge": { 757 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 758 | }, 759 | "edgePosition": 2, 760 | "underline": false, 761 | "horizontalAlignment": 2, 762 | "verticalAlignment": 5 763 | }, 764 | { 765 | "_type": "EdgeLabelView", 766 | "_id": "AAAAAAFWaJ2R/7F6qnM=", 767 | "_parent": { 768 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 769 | }, 770 | "model": { 771 | "$ref": "AAAAAAFWaJ2R+7Fywfc=" 772 | }, 773 | "visible": false, 774 | "enabled": true, 775 | "lineColor": "#000000", 776 | "fillColor": "#ffffff", 777 | "fontColor": "#000000", 778 | "font": "Arial;13;0", 779 | "showShadow": true, 780 | "containerChangeable": false, 781 | "containerExtending": false, 782 | "left": 102, 783 | "top": 445, 784 | "width": 0, 785 | "height": 13, 786 | "autoResize": false, 787 | "alpha": 0.7853981633974483, 788 | "distance": 40, 789 | "hostEdge": { 790 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 791 | }, 792 | "edgePosition": 2, 793 | "underline": false, 794 | "horizontalAlignment": 2, 795 | "verticalAlignment": 5 796 | }, 797 | { 798 | "_type": "EdgeLabelView", 799 | "_id": "AAAAAAFWaJ2R/7F7eso=", 800 | "_parent": { 801 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 802 | }, 803 | "model": { 804 | "$ref": "AAAAAAFWaJ2R+7Fywfc=" 805 | }, 806 | "visible": false, 807 | "enabled": true, 808 | "lineColor": "#000000", 809 | "fillColor": "#ffffff", 810 | "fontColor": "#000000", 811 | "font": "Arial;13;0", 812 | "showShadow": true, 813 | "containerChangeable": false, 814 | "containerExtending": false, 815 | "left": 95, 816 | "top": 486, 817 | "width": 0, 818 | "height": 13, 819 | "autoResize": false, 820 | "alpha": -0.5235987755982988, 821 | "distance": 25, 822 | "hostEdge": { 823 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 824 | }, 825 | "edgePosition": 2, 826 | "underline": false, 827 | "horizontalAlignment": 2, 828 | "verticalAlignment": 5 829 | }, 830 | { 831 | "_type": "EdgeLabelView", 832 | "_id": "AAAAAAFWaJ2R/7F8vBA=", 833 | "_parent": { 834 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 835 | }, 836 | "model": { 837 | "$ref": "AAAAAAFWaJ2R+7FzNVo=" 838 | }, 839 | "visible": false, 840 | "enabled": true, 841 | "lineColor": "#000000", 842 | "fillColor": "#ffffff", 843 | "fontColor": "#000000", 844 | "font": "Arial;13;0", 845 | "showShadow": true, 846 | "containerChangeable": false, 847 | "containerExtending": false, 848 | "left": 142, 849 | "top": 459, 850 | "width": 0, 851 | "height": 13, 852 | "autoResize": false, 853 | "alpha": -0.5235987755982988, 854 | "distance": 30, 855 | "hostEdge": { 856 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 857 | }, 858 | "edgePosition": 0, 859 | "underline": false, 860 | "horizontalAlignment": 2, 861 | "verticalAlignment": 5 862 | }, 863 | { 864 | "_type": "EdgeLabelView", 865 | "_id": "AAAAAAFWaJ2R/7F91Ew=", 866 | "_parent": { 867 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 868 | }, 869 | "model": { 870 | "$ref": "AAAAAAFWaJ2R+7FzNVo=" 871 | }, 872 | "visible": false, 873 | "enabled": true, 874 | "lineColor": "#000000", 875 | "fillColor": "#ffffff", 876 | "fontColor": "#000000", 877 | "font": "Arial;13;0", 878 | "showShadow": true, 879 | "containerChangeable": false, 880 | "containerExtending": false, 881 | "left": 139, 882 | "top": 445, 883 | "width": 0, 884 | "height": 13, 885 | "autoResize": false, 886 | "alpha": -0.7853981633974483, 887 | "distance": 40, 888 | "hostEdge": { 889 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 890 | }, 891 | "edgePosition": 0, 892 | "underline": false, 893 | "horizontalAlignment": 2, 894 | "verticalAlignment": 5 895 | }, 896 | { 897 | "_type": "EdgeLabelView", 898 | "_id": "AAAAAAFWaJ2R/7F+uTs=", 899 | "_parent": { 900 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 901 | }, 902 | "model": { 903 | "$ref": "AAAAAAFWaJ2R+7FzNVo=" 904 | }, 905 | "visible": false, 906 | "enabled": true, 907 | "lineColor": "#000000", 908 | "fillColor": "#ffffff", 909 | "fontColor": "#000000", 910 | "font": "Arial;13;0", 911 | "showShadow": true, 912 | "containerChangeable": false, 913 | "containerExtending": false, 914 | "left": 146, 915 | "top": 486, 916 | "width": 0, 917 | "height": 13, 918 | "autoResize": false, 919 | "alpha": 0.5235987755982988, 920 | "distance": 25, 921 | "hostEdge": { 922 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 923 | }, 924 | "edgePosition": 0, 925 | "underline": false, 926 | "horizontalAlignment": 2, 927 | "verticalAlignment": 5 928 | }, 929 | { 930 | "_type": "UMLQualifierCompartmentView", 931 | "_id": "AAAAAAFWaJ2R/7F/x4w=", 932 | "_parent": { 933 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 934 | }, 935 | "model": { 936 | "$ref": "AAAAAAFWaJ2R+7Fywfc=" 937 | }, 938 | "visible": false, 939 | "enabled": true, 940 | "lineColor": "#000000", 941 | "fillColor": "#ffffff", 942 | "fontColor": "#000000", 943 | "font": "Arial;13;0", 944 | "showShadow": true, 945 | "containerChangeable": false, 946 | "containerExtending": false, 947 | "left": 0, 948 | "top": 0, 949 | "width": 10, 950 | "height": 10, 951 | "autoResize": false 952 | }, 953 | { 954 | "_type": "UMLQualifierCompartmentView", 955 | "_id": "AAAAAAFWaJ2R/7GAo7E=", 956 | "_parent": { 957 | "$ref": "AAAAAAFWaJ2R/bF1rK8=" 958 | }, 959 | "model": { 960 | "$ref": "AAAAAAFWaJ2R+7FzNVo=" 961 | }, 962 | "visible": false, 963 | "enabled": true, 964 | "lineColor": "#000000", 965 | "fillColor": "#ffffff", 966 | "fontColor": "#000000", 967 | "font": "Arial;13;0", 968 | "showShadow": true, 969 | "containerChangeable": false, 970 | "containerExtending": false, 971 | "left": 0, 972 | "top": 0, 973 | "width": 10, 974 | "height": 10, 975 | "autoResize": false 976 | } 977 | ], 978 | "visible": true, 979 | "enabled": true, 980 | "lineColor": "#000000", 981 | "fillColor": "#ffffff", 982 | "fontColor": "#000000", 983 | "font": "Arial;13;0", 984 | "showShadow": true, 985 | "containerChangeable": false, 986 | "containerExtending": false, 987 | "head": { 988 | "$ref": "AAAAAAFWaJwnUrEUQ8A=" 989 | }, 990 | "tail": { 991 | "$ref": "AAAAAAFWaJ0bDbFIU+k=" 992 | }, 993 | "lineStyle": 0, 994 | "points": "74:480;168:480", 995 | "stereotypeDisplay": "label", 996 | "showVisibility": true, 997 | "showProperty": true, 998 | "nameLabel": { 999 | "$ref": "AAAAAAFWaJ2R/rF2EvY=" 1000 | }, 1001 | "stereotypeLabel": { 1002 | "$ref": "AAAAAAFWaJ2R/rF3mVw=" 1003 | }, 1004 | "propertyLabel": { 1005 | "$ref": "AAAAAAFWaJ2R/rF4pSU=" 1006 | }, 1007 | "showMultiplicity": true, 1008 | "showType": true, 1009 | "tailRoleNameLabel": { 1010 | "$ref": "AAAAAAFWaJ2R/rF5AMc=" 1011 | }, 1012 | "tailPropertyLabel": { 1013 | "$ref": "AAAAAAFWaJ2R/7F6qnM=" 1014 | }, 1015 | "tailMultiplicityLabel": { 1016 | "$ref": "AAAAAAFWaJ2R/7F7eso=" 1017 | }, 1018 | "headRoleNameLabel": { 1019 | "$ref": "AAAAAAFWaJ2R/7F8vBA=" 1020 | }, 1021 | "headPropertyLabel": { 1022 | "$ref": "AAAAAAFWaJ2R/7F91Ew=" 1023 | }, 1024 | "headMultiplicityLabel": { 1025 | "$ref": "AAAAAAFWaJ2R/7F+uTs=" 1026 | }, 1027 | "tailQualifiersCompartment": { 1028 | "$ref": "AAAAAAFWaJ2R/7F/x4w=" 1029 | }, 1030 | "headQualifiersCompartment": { 1031 | "$ref": "AAAAAAFWaJ2R/7GAo7E=" 1032 | } 1033 | }, 1034 | { 1035 | "_type": "UMLTextView", 1036 | "_id": "AAAAAAFWaJ78BrIzguI=", 1037 | "_parent": { 1038 | "$ref": "AAAAAAFF+qBtyKM79qY=" 1039 | }, 1040 | "visible": true, 1041 | "enabled": true, 1042 | "lineColor": "#000000", 1043 | "fillColor": "#ffffff", 1044 | "fontColor": "#000000", 1045 | "font": "Arial;13;0", 1046 | "showShadow": true, 1047 | "containerChangeable": false, 1048 | "containerExtending": false, 1049 | "left": 80, 1050 | "top": 456, 1051 | "width": 72, 1052 | "height": 25, 1053 | "autoResize": false, 1054 | "text": "+prototype", 1055 | "wordWrap": true 1056 | }, 1057 | { 1058 | "_type": "UMLGeneralizationView", 1059 | "_id": "AAAAAAFWaJ/DBLKNKF4=", 1060 | "_parent": { 1061 | "$ref": "AAAAAAFF+qBtyKM79qY=" 1062 | }, 1063 | "model": { 1064 | "$ref": "AAAAAAFWaJ/DBLKLf/c=" 1065 | }, 1066 | "subViews": [ 1067 | { 1068 | "_type": "EdgeLabelView", 1069 | "_id": "AAAAAAFWaJ/DBbKOa8A=", 1070 | "_parent": { 1071 | "$ref": "AAAAAAFWaJ/DBLKNKF4=" 1072 | }, 1073 | "model": { 1074 | "$ref": "AAAAAAFWaJ/DBLKLf/c=" 1075 | }, 1076 | "visible": false, 1077 | "enabled": true, 1078 | "lineColor": "#000000", 1079 | "fillColor": "#ffffff", 1080 | "fontColor": "#000000", 1081 | "font": "Arial;13;0", 1082 | "showShadow": true, 1083 | "containerChangeable": false, 1084 | "containerExtending": false, 1085 | "left": 233, 1086 | "top": 545, 1087 | "width": 0, 1088 | "height": 13, 1089 | "autoResize": false, 1090 | "alpha": 1.5707963267948966, 1091 | "distance": 15, 1092 | "hostEdge": { 1093 | "$ref": "AAAAAAFWaJ/DBLKNKF4=" 1094 | }, 1095 | "edgePosition": 1, 1096 | "underline": false, 1097 | "horizontalAlignment": 2, 1098 | "verticalAlignment": 5 1099 | }, 1100 | { 1101 | "_type": "EdgeLabelView", 1102 | "_id": "AAAAAAFWaJ/DBbKPHwE=", 1103 | "_parent": { 1104 | "$ref": "AAAAAAFWaJ/DBLKNKF4=" 1105 | }, 1106 | "model": { 1107 | "$ref": "AAAAAAFWaJ/DBLKLf/c=" 1108 | }, 1109 | "visible": null, 1110 | "enabled": true, 1111 | "lineColor": "#000000", 1112 | "fillColor": "#ffffff", 1113 | "fontColor": "#000000", 1114 | "font": "Arial;13;0", 1115 | "showShadow": true, 1116 | "containerChangeable": false, 1117 | "containerExtending": false, 1118 | "left": 218, 1119 | "top": 545, 1120 | "width": 0, 1121 | "height": 13, 1122 | "autoResize": false, 1123 | "alpha": 1.5707963267948966, 1124 | "distance": 30, 1125 | "hostEdge": { 1126 | "$ref": "AAAAAAFWaJ/DBLKNKF4=" 1127 | }, 1128 | "edgePosition": 1, 1129 | "underline": false, 1130 | "horizontalAlignment": 2, 1131 | "verticalAlignment": 5 1132 | }, 1133 | { 1134 | "_type": "EdgeLabelView", 1135 | "_id": "AAAAAAFWaJ/DBbKQJGw=", 1136 | "_parent": { 1137 | "$ref": "AAAAAAFWaJ/DBLKNKF4=" 1138 | }, 1139 | "model": { 1140 | "$ref": "AAAAAAFWaJ/DBLKLf/c=" 1141 | }, 1142 | "visible": false, 1143 | "enabled": true, 1144 | "lineColor": "#000000", 1145 | "fillColor": "#ffffff", 1146 | "fontColor": "#000000", 1147 | "font": "Arial;13;0", 1148 | "showShadow": true, 1149 | "containerChangeable": false, 1150 | "containerExtending": false, 1151 | "left": 262, 1152 | "top": 546, 1153 | "width": 0, 1154 | "height": 13, 1155 | "autoResize": false, 1156 | "alpha": -1.5707963267948966, 1157 | "distance": 15, 1158 | "hostEdge": { 1159 | "$ref": "AAAAAAFWaJ/DBLKNKF4=" 1160 | }, 1161 | "edgePosition": 1, 1162 | "underline": false, 1163 | "horizontalAlignment": 2, 1164 | "verticalAlignment": 5 1165 | } 1166 | ], 1167 | "visible": true, 1168 | "enabled": true, 1169 | "lineColor": "#000000", 1170 | "fillColor": "#ffffff", 1171 | "fontColor": "#000000", 1172 | "font": "Arial;13;0", 1173 | "showShadow": true, 1174 | "containerChangeable": false, 1175 | "containerExtending": false, 1176 | "head": { 1177 | "$ref": "AAAAAAFWaJwnUrEUQ8A=" 1178 | }, 1179 | "tail": { 1180 | "$ref": "AAAAAAFWaJ/+zLLG6MQ=" 1181 | }, 1182 | "lineStyle": 0, 1183 | "points": "248:600;248:504", 1184 | "stereotypeDisplay": "label", 1185 | "showVisibility": true, 1186 | "showProperty": true, 1187 | "nameLabel": { 1188 | "$ref": "AAAAAAFWaJ/DBbKOa8A=" 1189 | }, 1190 | "stereotypeLabel": { 1191 | "$ref": "AAAAAAFWaJ/DBbKPHwE=" 1192 | }, 1193 | "propertyLabel": { 1194 | "$ref": "AAAAAAFWaJ/DBbKQJGw=" 1195 | } 1196 | }, 1197 | { 1198 | "_type": "UMLClassView", 1199 | "_id": "AAAAAAFWaJ/+zLLG6MQ=", 1200 | "_parent": { 1201 | "$ref": "AAAAAAFF+qBtyKM79qY=" 1202 | }, 1203 | "model": { 1204 | "$ref": "AAAAAAFWaJ/+y7LEIMc=" 1205 | }, 1206 | "subViews": [ 1207 | { 1208 | "_type": "UMLNameCompartmentView", 1209 | "_id": "AAAAAAFWaJ/+zLLHw94=", 1210 | "_parent": { 1211 | "$ref": "AAAAAAFWaJ/+zLLG6MQ=" 1212 | }, 1213 | "model": { 1214 | "$ref": "AAAAAAFWaJ/+y7LEIMc=" 1215 | }, 1216 | "subViews": [ 1217 | { 1218 | "_type": "LabelView", 1219 | "_id": "AAAAAAFWaJ/+zbLICgQ=", 1220 | "_parent": { 1221 | "$ref": "AAAAAAFWaJ/+zLLHw94=" 1222 | }, 1223 | "visible": false, 1224 | "enabled": true, 1225 | "lineColor": "#000000", 1226 | "fillColor": "#ffffff", 1227 | "fontColor": "#000000", 1228 | "font": "Arial;13;0", 1229 | "showShadow": true, 1230 | "containerChangeable": false, 1231 | "containerExtending": false, 1232 | "left": 64, 1233 | "top": -160, 1234 | "width": 0, 1235 | "height": 13, 1236 | "autoResize": false, 1237 | "underline": false, 1238 | "horizontalAlignment": 2, 1239 | "verticalAlignment": 5 1240 | }, 1241 | { 1242 | "_type": "LabelView", 1243 | "_id": "AAAAAAFWaJ/+zbLJHiE=", 1244 | "_parent": { 1245 | "$ref": "AAAAAAFWaJ/+zLLHw94=" 1246 | }, 1247 | "visible": true, 1248 | "enabled": true, 1249 | "lineColor": "#000000", 1250 | "fillColor": "#ffffff", 1251 | "fontColor": "#000000", 1252 | "font": "Arial;13;1", 1253 | "showShadow": true, 1254 | "containerChangeable": false, 1255 | "containerExtending": false, 1256 | "left": 181, 1257 | "top": 607, 1258 | "width": 135, 1259 | "height": 13, 1260 | "autoResize": false, 1261 | "underline": false, 1262 | "text": "Concrete Prototype", 1263 | "horizontalAlignment": 2, 1264 | "verticalAlignment": 5 1265 | }, 1266 | { 1267 | "_type": "LabelView", 1268 | "_id": "AAAAAAFWaJ/+zbLKlEw=", 1269 | "_parent": { 1270 | "$ref": "AAAAAAFWaJ/+zLLHw94=" 1271 | }, 1272 | "visible": false, 1273 | "enabled": true, 1274 | "lineColor": "#000000", 1275 | "fillColor": "#ffffff", 1276 | "fontColor": "#000000", 1277 | "font": "Arial;13;0", 1278 | "showShadow": true, 1279 | "containerChangeable": false, 1280 | "containerExtending": false, 1281 | "left": 64, 1282 | "top": -160, 1283 | "width": 73, 1284 | "height": 13, 1285 | "autoResize": false, 1286 | "underline": false, 1287 | "text": "(from Model)", 1288 | "horizontalAlignment": 2, 1289 | "verticalAlignment": 5 1290 | }, 1291 | { 1292 | "_type": "LabelView", 1293 | "_id": "AAAAAAFWaJ/+zbLLTTI=", 1294 | "_parent": { 1295 | "$ref": "AAAAAAFWaJ/+zLLHw94=" 1296 | }, 1297 | "visible": false, 1298 | "enabled": true, 1299 | "lineColor": "#000000", 1300 | "fillColor": "#ffffff", 1301 | "fontColor": "#000000", 1302 | "font": "Arial;13;0", 1303 | "showShadow": true, 1304 | "containerChangeable": false, 1305 | "containerExtending": false, 1306 | "left": 64, 1307 | "top": -160, 1308 | "width": 0, 1309 | "height": 13, 1310 | "autoResize": false, 1311 | "underline": false, 1312 | "horizontalAlignment": 1, 1313 | "verticalAlignment": 5 1314 | } 1315 | ], 1316 | "visible": true, 1317 | "enabled": true, 1318 | "lineColor": "#000000", 1319 | "fillColor": "#ffffff", 1320 | "fontColor": "#000000", 1321 | "font": "Arial;13;0", 1322 | "showShadow": true, 1323 | "containerChangeable": false, 1324 | "containerExtending": false, 1325 | "left": 176, 1326 | "top": 600, 1327 | "width": 145, 1328 | "height": 25, 1329 | "autoResize": false, 1330 | "stereotypeLabel": { 1331 | "$ref": "AAAAAAFWaJ/+zbLICgQ=" 1332 | }, 1333 | "nameLabel": { 1334 | "$ref": "AAAAAAFWaJ/+zbLJHiE=" 1335 | }, 1336 | "namespaceLabel": { 1337 | "$ref": "AAAAAAFWaJ/+zbLKlEw=" 1338 | }, 1339 | "propertyLabel": { 1340 | "$ref": "AAAAAAFWaJ/+zbLLTTI=" 1341 | } 1342 | }, 1343 | { 1344 | "_type": "UMLAttributeCompartmentView", 1345 | "_id": "AAAAAAFWaJ/+zbLMR0s=", 1346 | "_parent": { 1347 | "$ref": "AAAAAAFWaJ/+zLLG6MQ=" 1348 | }, 1349 | "model": { 1350 | "$ref": "AAAAAAFWaJ/+y7LEIMc=" 1351 | }, 1352 | "visible": true, 1353 | "enabled": true, 1354 | "lineColor": "#000000", 1355 | "fillColor": "#ffffff", 1356 | "fontColor": "#000000", 1357 | "font": "Arial;13;0", 1358 | "showShadow": true, 1359 | "containerChangeable": false, 1360 | "containerExtending": false, 1361 | "left": 176, 1362 | "top": 625, 1363 | "width": 145, 1364 | "height": 10, 1365 | "autoResize": false 1366 | }, 1367 | { 1368 | "_type": "UMLOperationCompartmentView", 1369 | "_id": "AAAAAAFWaJ/+zrLN5fE=", 1370 | "_parent": { 1371 | "$ref": "AAAAAAFWaJ/+zLLG6MQ=" 1372 | }, 1373 | "model": { 1374 | "$ref": "AAAAAAFWaJ/+y7LEIMc=" 1375 | }, 1376 | "visible": true, 1377 | "enabled": true, 1378 | "lineColor": "#000000", 1379 | "fillColor": "#ffffff", 1380 | "fontColor": "#000000", 1381 | "font": "Arial;13;0", 1382 | "showShadow": true, 1383 | "containerChangeable": false, 1384 | "containerExtending": false, 1385 | "left": 176, 1386 | "top": 635, 1387 | "width": 145, 1388 | "height": 10, 1389 | "autoResize": false 1390 | }, 1391 | { 1392 | "_type": "UMLReceptionCompartmentView", 1393 | "_id": "AAAAAAFWaJ/+zrLOCzE=", 1394 | "_parent": { 1395 | "$ref": "AAAAAAFWaJ/+zLLG6MQ=" 1396 | }, 1397 | "model": { 1398 | "$ref": "AAAAAAFWaJ/+y7LEIMc=" 1399 | }, 1400 | "visible": false, 1401 | "enabled": true, 1402 | "lineColor": "#000000", 1403 | "fillColor": "#ffffff", 1404 | "fontColor": "#000000", 1405 | "font": "Arial;13;0", 1406 | "showShadow": true, 1407 | "containerChangeable": false, 1408 | "containerExtending": false, 1409 | "left": 32, 1410 | "top": -80, 1411 | "width": 10, 1412 | "height": 10, 1413 | "autoResize": false 1414 | }, 1415 | { 1416 | "_type": "UMLTemplateParameterCompartmentView", 1417 | "_id": "AAAAAAFWaJ/+zrLPFK4=", 1418 | "_parent": { 1419 | "$ref": "AAAAAAFWaJ/+zLLG6MQ=" 1420 | }, 1421 | "model": { 1422 | "$ref": "AAAAAAFWaJ/+y7LEIMc=" 1423 | }, 1424 | "visible": false, 1425 | "enabled": true, 1426 | "lineColor": "#000000", 1427 | "fillColor": "#ffffff", 1428 | "fontColor": "#000000", 1429 | "font": "Arial;13;0", 1430 | "showShadow": true, 1431 | "containerChangeable": false, 1432 | "containerExtending": false, 1433 | "left": 32, 1434 | "top": -80, 1435 | "width": 10, 1436 | "height": 10, 1437 | "autoResize": false 1438 | } 1439 | ], 1440 | "visible": true, 1441 | "enabled": true, 1442 | "lineColor": "#000000", 1443 | "fillColor": "#ffffff", 1444 | "fontColor": "#000000", 1445 | "font": "Arial;13;0", 1446 | "showShadow": true, 1447 | "containerChangeable": true, 1448 | "containerExtending": false, 1449 | "left": 176, 1450 | "top": 600, 1451 | "width": 145, 1452 | "height": 45, 1453 | "autoResize": false, 1454 | "stereotypeDisplay": "label", 1455 | "showVisibility": true, 1456 | "showNamespace": false, 1457 | "showProperty": true, 1458 | "showType": true, 1459 | "nameCompartment": { 1460 | "$ref": "AAAAAAFWaJ/+zLLHw94=" 1461 | }, 1462 | "wordWrap": false, 1463 | "suppressAttributes": false, 1464 | "suppressOperations": false, 1465 | "suppressReceptions": true, 1466 | "showMultiplicity": true, 1467 | "showOperationSignature": true, 1468 | "attributeCompartment": { 1469 | "$ref": "AAAAAAFWaJ/+zbLMR0s=" 1470 | }, 1471 | "operationCompartment": { 1472 | "$ref": "AAAAAAFWaJ/+zrLN5fE=" 1473 | }, 1474 | "receptionCompartment": { 1475 | "$ref": "AAAAAAFWaJ/+zrLOCzE=" 1476 | }, 1477 | "templateParameterCompartment": { 1478 | "$ref": "AAAAAAFWaJ/+zrLPFK4=" 1479 | } 1480 | } 1481 | ] 1482 | }, 1483 | { 1484 | "_type": "UMLClass", 1485 | "_id": "AAAAAAFWaJwnULESI68=", 1486 | "_parent": { 1487 | "$ref": "AAAAAAFF+qBWK6M3Z8Y=" 1488 | }, 1489 | "name": "Prototype", 1490 | "ownedElements": [ 1491 | { 1492 | "_type": "UMLGeneralization", 1493 | "_id": "AAAAAAFWaJ/DBLKLf/c=", 1494 | "_parent": { 1495 | "$ref": "AAAAAAFWaJwnULESI68=" 1496 | }, 1497 | "source": { 1498 | "$ref": "AAAAAAFWaJ/+y7LEIMc=" 1499 | }, 1500 | "target": { 1501 | "$ref": "AAAAAAFWaJwnULESI68=" 1502 | }, 1503 | "visibility": "public" 1504 | } 1505 | ], 1506 | "visibility": "public", 1507 | "operations": [ 1508 | { 1509 | "_type": "UMLOperation", 1510 | "_id": "AAAAAAFWaJyIEbE+8Hg=", 1511 | "_parent": { 1512 | "$ref": "AAAAAAFWaJwnULESI68=" 1513 | }, 1514 | "name": "clone", 1515 | "visibility": "public", 1516 | "isStatic": false, 1517 | "isLeaf": false, 1518 | "concurrency": "sequential", 1519 | "isQuery": false, 1520 | "isAbstract": false 1521 | } 1522 | ], 1523 | "isAbstract": false, 1524 | "isFinalSpecialization": false, 1525 | "isLeaf": false, 1526 | "isActive": false 1527 | }, 1528 | { 1529 | "_type": "UMLClass", 1530 | "_id": "AAAAAAFWaJ0bDLFGkl8=", 1531 | "_parent": { 1532 | "$ref": "AAAAAAFF+qBWK6M3Z8Y=" 1533 | }, 1534 | "name": "Client", 1535 | "ownedElements": [ 1536 | { 1537 | "_type": "UMLAssociation", 1538 | "_id": "AAAAAAFWaJ2R+rFxwNM=", 1539 | "_parent": { 1540 | "$ref": "AAAAAAFWaJ0bDLFGkl8=" 1541 | }, 1542 | "end1": { 1543 | "_type": "UMLAssociationEnd", 1544 | "_id": "AAAAAAFWaJ2R+7Fywfc=", 1545 | "_parent": { 1546 | "$ref": "AAAAAAFWaJ2R+rFxwNM=" 1547 | }, 1548 | "reference": { 1549 | "$ref": "AAAAAAFWaJ0bDLFGkl8=" 1550 | }, 1551 | "visibility": "public", 1552 | "navigable": false, 1553 | "aggregation": "none", 1554 | "isReadOnly": false, 1555 | "isOrdered": false, 1556 | "isUnique": false, 1557 | "isDerived": false, 1558 | "isID": false 1559 | }, 1560 | "end2": { 1561 | "_type": "UMLAssociationEnd", 1562 | "_id": "AAAAAAFWaJ2R+7FzNVo=", 1563 | "_parent": { 1564 | "$ref": "AAAAAAFWaJ2R+rFxwNM=" 1565 | }, 1566 | "reference": { 1567 | "$ref": "AAAAAAFWaJwnULESI68=" 1568 | }, 1569 | "visibility": "public", 1570 | "navigable": true, 1571 | "aggregation": "none", 1572 | "isReadOnly": false, 1573 | "isOrdered": false, 1574 | "isUnique": false, 1575 | "isDerived": false, 1576 | "isID": false 1577 | }, 1578 | "visibility": "public", 1579 | "isDerived": false 1580 | } 1581 | ], 1582 | "visibility": "public", 1583 | "isAbstract": false, 1584 | "isFinalSpecialization": false, 1585 | "isLeaf": false, 1586 | "isActive": false 1587 | }, 1588 | { 1589 | "_type": "UMLClass", 1590 | "_id": "AAAAAAFWaJ/+y7LEIMc=", 1591 | "_parent": { 1592 | "$ref": "AAAAAAFF+qBWK6M3Z8Y=" 1593 | }, 1594 | "name": "Concrete Prototype", 1595 | "visibility": "public", 1596 | "isAbstract": false, 1597 | "isFinalSpecialization": false, 1598 | "isLeaf": false, 1599 | "isActive": false 1600 | } 1601 | ], 1602 | "visibility": "public" 1603 | } 1604 | ] 1605 | } -------------------------------------------------------------------------------- /原型模式/原型模式.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/原型模式/原型模式.png -------------------------------------------------------------------------------- /工厂方法模式.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 工厂方法模式 3 | date: 2016-08-12 15:32:47 4 | tags: Java 设计模式 5 | --- 6 | 7 | ## 前言 8 | 9 | ​ 正所谓只要功夫深,铁杵磨成针,坚持不懈,水滴石穿。学习也要坚持不懈,慢慢积累,才能达到以量变促成质变。在前进的过程中也要保持好良好的心态,不急不燥,脚踏实地,一步一个脚印。 10 | 11 | ## 工厂方法模式 介绍 12 | 13 | ​ 工厂方法模式(Factory Pattern)是一种**创建型设计模式**,是日常开发中使用频率较高的一种设计模式。下面就要我们一起去了解一下工厂方法设计模式。 14 | 15 | 16 | 17 | ## 工厂方法设计模式 定义 18 | 19 | ​ 定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 20 | 21 | ## 工厂方法设计模式 使用场景 22 | 23 | * 工厂方法模式是new一个对象的替代品,所以在有需要生成对象的地方都可以使用,但是要慎重的考虑当前任务是不是需要增加一个工厂类进行管理,避免使自己的代码更加复杂。 24 | * 需要灵活、可扩展的框架时,可以考虑采用工厂方法模式。 25 | 26 | ## 工厂方法设计模式 通用UML类图 27 | 28 | ![工厂方法模式UML类图](工厂方法模式/factoryUml.png) 29 | 30 | **说明:** 31 | 32 | * **Product** 33 | 34 | 产品类的抽象方法,由具体的产品类去实现。 35 | 36 | * **ConcreateProduct** 37 | 38 | 具体的产品类,可以有多个。继承于Product 39 | 40 | * **Creator** 41 | 42 | 抽象工厂类,负责定义产品对象的产生。 43 | 44 | * **ConcreateCreator** 45 | 46 | 具体的工厂实现类,继承于Creator。 47 | 48 | ## 工厂方法模式使用实例 49 | 50 | ​ 前面我们组装了一台台式机电脑,现在台式机电脑组装好了,但是还不能使用,我们需要在电脑上安装软件系统,但是软件系统无非就是电脑系统的安装(linux系列,windows系列,mac系列(黑苹果)等等)、各个硬件驱动程序的安装。 51 | 我们可以将每一种安装的电脑系统及驱动作为一个产品类,在抽象类中定义操作的方法。 52 | ​ 下面就以此为例,实现工厂方法模式。 53 | 54 | 1. 抽象产品类。 55 | 56 | ```java 57 | package com.yf.designpatternandroid; 58 | 59 | /** 60 | * Created by yangfei on 16/8/15. 61 | * yangfei's computer. 62 | */ 63 | public abstract class InstallSoftware { 64 | /** 65 | * 安装系统 66 | * 67 | * @param systemOs 系统 68 | */ 69 | public abstract void installSystem(String systemOs); 70 | 71 | /** 72 | * 安装显卡驱动 73 | * 74 | * @param GPUType 显卡型号 75 | */ 76 | public abstract void installGPUDriver(String GPUType); 77 | 78 | /** 79 | * 安装主板驱动 80 | * 81 | * @param mainBoxType 主板型号 82 | */ 83 | public abstract void installMainBoxdriver(String mainBoxType); 84 | 85 | /** 86 | * 安装网卡驱动 87 | * 88 | * @param netCardType 网卡型号 89 | */ 90 | public abstract void installNetCardDriver(String netCardType); 91 | 92 | /** 93 | * 安装声卡驱动 94 | * 95 | * @param audioType 声卡型号 96 | */ 97 | public abstract void installAudioDriver(String audioType); 98 | 99 | /** 100 | * 安装USB驱动 101 | * @param usbDriverType(3.0,2.0,...) 102 | */ 103 | public abstract void installUSBDriver(String usbDriverType); 104 | 105 | /** 106 | * 安装键盘驱动 107 | * @param keyBoardType 键盘型号 108 | */ 109 | public abstract void installKeyBoardDriver(String keyBoardType); 110 | 111 | /** 112 | * 安装鼠标驱动 113 | * @param mouseType 鼠标型号 114 | */ 115 | public abstract void installMouseDriver(String mouseType); 116 | /** 117 | * 软件系统安装完成 118 | * @return 119 | */ 120 | public abstract String finish(); 121 | } 122 | ``` 123 | 124 | ​ 125 | 126 | 2. 具体的产品Windows系统的电脑。 127 | 128 | ```java 129 | package com.yf.designpatternandroid; 130 | 131 | /** 132 | * Created by iuni.life on 16/8/15. 133 | * yangfei's computer. 134 | * 具体的逻辑就不处理了 135 | */ 136 | public class WindowsSoftware extends InstallSoftware { 137 | @Override 138 | public void installSystem(String systemOs) { 139 | //系统下载安装处理 140 | } 141 | 142 | @Override 143 | public void installGPUDriver(String GPUType) { 144 | //显卡驱动下载安装处理 145 | } 146 | 147 | @Override 148 | public void installMainBoxdriver(String mainBoxType) { 149 | //主板驱动下载安装处理 150 | } 151 | 152 | @Override 153 | public void installNetCardDriver(String netCardType) { 154 | //网卡驱动下载安装处理 155 | } 156 | 157 | @Override 158 | public void installAudioDriver(String audioType) { 159 | //声卡驱动下载安装处理 160 | } 161 | 162 | @Override 163 | public void installUSBDriver(String usbDriverType) { 164 | //USB驱动下载安装处理 165 | } 166 | 167 | @Override 168 | public void installKeyBoardDriver(String keyBoardType) { 169 | //键盘驱动下载安装处理 170 | } 171 | 172 | @Override 173 | public void installMouseDriver(String mouseType) { 174 | //鼠标驱动下载安装处理 175 | } 176 | 177 | @Override 178 | public String finish() { 179 | return "You can use normal Windows PC"; 180 | } 181 | } 182 | ``` 183 | 184 | 185 | 186 | 3. 具体的产品类,Ubuntu系统的电脑。 187 | 188 | ```java 189 | package com.yf.designpatternandroid; 190 | 191 | /** 192 | * Created by iuni.life on 16/8/15. 193 | * yangfei's computer. 194 | */ 195 | public class UbuntuSoftware extends InstallSoftware { 196 | @Override 197 | public void installSystem(String systemOs) { 198 | //系统下载安装处理 199 | } 200 | 201 | @Override 202 | public void installGPUDriver(String GPUType) { 203 | //显卡驱动下载安装处理 204 | } 205 | 206 | @Override 207 | public void installMainBoxdriver(String mainBoxType) { 208 | //主板驱动下载安装处理 209 | } 210 | 211 | @Override 212 | public void installNetCardDriver(String netCardType) { 213 | //网卡驱动下载安装处理 214 | } 215 | 216 | @Override 217 | public void installAudioDriver(String audioType) { 218 | //声卡驱动下载安装处理 219 | } 220 | 221 | @Override 222 | public void installUSBDriver(String usbDriverType) { 223 | //USB驱动下载安装处理 224 | } 225 | 226 | @Override 227 | public void installKeyBoardDriver(String keyBoardType) { 228 | //键盘驱动下载安装处理 229 | } 230 | 231 | @Override 232 | public void installMouseDriver(String mouseType) { 233 | //鼠标驱动下载安装处理 234 | } 235 | 236 | @Override 237 | public String finish() { 238 | return "You can use normal Ubuntu PC"; 239 | } 240 | } 241 | ``` 242 | 243 | 4. 具体的产品类,Mac 系统的电脑。 244 | 245 | ```java 246 | package com.yf.designpatternandroid; 247 | 248 | /** 249 | * Created by iuni.life on 16/8/15. 250 | * yangfei's computer. 251 | */ 252 | public class MacSoftware extends InstallSoftware { 253 | @Override 254 | public void installSystem(String systemOs) { 255 | //系统下载安装处理 256 | } 257 | 258 | @Override 259 | public void installGPUDriver(String GPUType) { 260 | //显卡驱动下载安装处理 261 | } 262 | 263 | @Override 264 | public void installMainBoxdriver(String mainBoxType) { 265 | //主板驱动下载安装处理 266 | } 267 | 268 | @Override 269 | public void installNetCardDriver(String netCardType) { 270 | //网卡驱动下载安装处理 271 | } 272 | 273 | @Override 274 | public void installAudioDriver(String audioType) { 275 | //声卡驱动下载安装处理 276 | } 277 | 278 | @Override 279 | public void installUSBDriver(String usbDriverType) { 280 | //USB驱动下载安装处理 281 | } 282 | 283 | @Override 284 | public void installKeyBoardDriver(String keyBoardType) { 285 | //键盘驱动下载安装处理 286 | } 287 | 288 | @Override 289 | public void installMouseDriver(String mouseType) { 290 | //鼠标驱动下载安装处理 291 | } 292 | 293 | @Override 294 | public String finish() { 295 | return "You can use normal MacOs PC"; 296 | } 297 | } 298 | ``` 299 | 300 | 5. 抽象工厂类。 301 | 302 | ```java 303 | package com.yf.designpatternandroid; 304 | 305 | /** 306 | * Created by iuni.life on 16/8/16. 307 | * yangfei's computer. 308 | */ 309 | public abstract class Factory { 310 | abstract T getComputer(Class clz); 311 | } 312 | ``` 313 | 314 | 315 | 6. 工厂类的具体实现。 316 | 317 | ```java 318 | package com.yf.designpatternandroid; 319 | 320 | /** 321 | * Created by iuni.life on 16/8/15. 322 | * yangfei's computer. 323 | */ 324 | public class ComputerFactory extends Factory { 325 | 326 | /** 327 | * 利用反射方式生产具体的产品对象 328 | * 329 | * @param clz 330 | * @param 331 | * @return 332 | */ 333 | public T getComputer(Class clz) { 334 | InstallSoftware installSoftware = null; 335 | try { 336 | installSoftware = (InstallSoftware) Class.forName(clz.getName()).newInstance(); 337 | } catch (InstantiationException e) { 338 | e.printStackTrace(); 339 | } catch (IllegalAccessException e) { 340 | e.printStackTrace(); 341 | } catch (ClassNotFoundException e) { 342 | e.printStackTrace(); 343 | } 344 | return (T) installSoftware; 345 | } 346 | } 347 | ``` 348 | 349 | ​ 350 | 351 | 7. 场景类。 352 | 353 | ```java 354 | package com.yf.designpatternandroid; 355 | /** 356 | * Created by iuni.life on 16/8/15. 357 | * yangfei's computer. 358 | */ 359 | public class Client { 360 | public static void main(String[] args) { 361 | //现在生产一批windows系统的电脑 362 | //这里举例子说明,具体驱动就不一一列举了. 363 | ComputerFactory computerFactory = new ComputerFactory(); 364 | WindowsSoftware windowsSoftware = computerFactory.getComputer(WindowsSoftware.class); 365 | windowsSoftware.installSystem("Windows 10"); 366 | windowsSoftware.installAudioDriver("Windows AudioDriver"); 367 | windowsSoftware.installGPUDriver("Windows GPUDriver"); 368 | windowsSoftware.installKeyBoardDriver("Windows KeyBoardDriver"); 369 | windowsSoftware.installMainBoxdriver("Windows MainBoxdrive"); 370 | windowsSoftware.installMouseDriver("Windows MouseDriver"); 371 | windowsSoftware.installNetCardDriver("Windows NetCardDriver"); 372 | windowsSoftware.installUSBDriver("Windows USBDriver"); 373 | System.out.println(windowsSoftware.finish()); 374 | 375 | //现在要生产一批Ubuntu系统的电脑 376 | UbuntuSoftware ubuntuSoftware = computerFactory.getComputer(UbuntuSoftware.class); 377 | //Ubuntu系统一般只要安装好系统就可以 378 | ubuntuSoftware.installSystem("Ubuntu 14.04"); 379 | System.out.println(ubuntuSoftware.finish()); 380 | 381 | //现在又要生产一批Mac(黑苹果)系统的电脑 382 | MacSoftware macSoftware = computerFactory.getComputer(MacSoftware.class); 383 | //黑苹果安装就有点繁琐了,首先要找驱动什么的,替换原有驱动等等,如果对黑苹果有兴趣,可去远景论坛爬贴学习. 384 | //黑苹果应该是先把找好的驱动什么的融入到安装系统中,然后才开始安装mac系统 385 | macSoftware.installAudioDriver("Mac AudioDriver"); 386 | macSoftware.installGPUDriver("Mac GPUDriver"); 387 | macSoftware.installKeyBoardDriver("Mac KeyBoardDriver"); 388 | macSoftware.installMainBoxdriver("Mac MainBoxdriver"); 389 | macSoftware.installMouseDriver("Mac MouseDriver"); 390 | macSoftware.installNetCardDriver("Mac NetCardDriver"); 391 | macSoftware.installUSBDriver("Mac USBDriver"); 392 | macSoftware.installSystem("Mac Os 10.11.6"); 393 | System.out.println(macSoftware.finish()); 394 | } 395 | } 396 | ``` 397 | 398 | 399 | 400 | 8. 运行结果。 401 | 402 | ![工厂方法模式运行结果](工厂方法模式/factoryresult.png) 403 | 404 | ​ 405 | 406 | ## 工厂方法模式的优缺点 407 | 408 | ### 优点 409 | 410 | * **良好的封装性,代码结构清晰:** 411 | 412 | 不需要知道对象的创建过程,降低模块间的耦合。 413 | 414 | * **工厂方法模式的拓展性非常优秀:** 415 | 416 | 在增加产品类的情况下,只要适当修改具体的工厂类或者拓展一个工厂类,就可以拥抱变化。例如在我们的例子中需要生产一个装radHat的系统的电脑,则只需要增加一个RedHatSoftware类,工厂类不需要做任何修改就可以完成系统拓展。 417 | 418 | * **屏蔽产品类:** 419 | 420 | 产品类的任何变化,调用者都无需关心,它只要关心产品的接口。 421 | 422 | * **典型的解耦框架:** 423 | 424 | 高层模块只需要知道产品的抽象类,其他的实现类无需关心,符合迪米特原则,我们不需要的就不要去交流,符合依赖倒置原则,只依赖产品的抽象,符合里氏替换原则,使用产品子类替换产品父类,当然也没有问题。 425 | 426 | ### 缺点 427 | 428 | * **类结构的复杂化:** 429 | 430 | 每次为工厂方法模式添加新的产品时就要编写一个新的产品类,还要引入抽象层。 431 | 432 | 433 | ## 工厂方法模式的拓展 434 | 435 | ​ 工厂方法模式一般有4种拓展,分别为简单工厂模式、升级为多个工厂类、替换单例模式、延迟初始化。 436 | 437 | ​ 下面我们详细说明这4个拓展。 438 | 439 | 1. **简单工厂模式(静态工厂模式)** 440 | 441 | 如果一个模块仅需要一个工厂类,使用静态方法就可以,所有我们把上诉工厂类的具体实现(ComputerFactory)里的方法改为静态就可以了: 442 | 443 | ```java 444 | /** 445 | * Created by iuni.life on 16/8/15. 446 | * yangfei's computer. 447 | */ 448 | public class ComputerFactory{ 449 | 450 | /** 451 | * 利用反射方式生产具体的产品对象 452 | * 453 | * @param clz 454 | * @param 455 | * @return 456 | */ 457 | public static T getComputer(Class clz) { 458 | InstallSoftware installSoftware = null; 459 | try { 460 | installSoftware = (InstallSoftware) Class.forName(clz.getName()).newInstance(); 461 | } catch (InstantiationException e) { 462 | e.printStackTrace(); 463 | } catch (IllegalAccessException e) { 464 | e.printStackTrace(); 465 | } catch (ClassNotFoundException e) { 466 | e.printStackTrace(); 467 | } 468 | return (T) installSoftware; 469 | } 470 | } 471 | ``` 472 | 473 | **说明:** 474 | 475 | 上诉代码与原有相比,有2处变化,一处是去掉了Factory抽象类,一处是把getComputer设为静态方法。 476 | 477 | 场景类也要做一些适当变化: 478 | 479 | ```java 480 | /** 481 | * Created by iuni.life on 16/8/15. 482 | * yangfei's computer. 483 | */ 484 | public class Client { 485 | public static void main(String[] args) { 486 | //现在生产一批windows系统的电脑 487 | //这里举例子说明,具体驱动就不一一列举了. 488 | 489 | WindowsSoftware windowsSoftware = ComputerFactory.getComputer(WindowsSoftware.class); 490 | windowsSoftware.installSystem("Windows 10"); 491 | windowsSoftware.installAudioDriver("Windows AudioDriver"); 492 | windowsSoftware.installGPUDriver("Windows GPUDriver"); 493 | windowsSoftware.installKeyBoardDriver("Windows KeyBoardDriver"); 494 | windowsSoftware.installMainBoxdriver("Windows MainBoxdrive"); 495 | windowsSoftware.installMouseDriver("Windows MouseDriver"); 496 | windowsSoftware.installNetCardDriver("Windows NetCardDriver"); 497 | windowsSoftware.installUSBDriver("Windows USBDriver"); 498 | System.out.println(windowsSoftware.finish()); 499 | 500 | //现在要生产一批Ubuntu系统的电脑 501 | UbuntuSoftware ubuntuSoftware = ComputerFactory.getComputer(UbuntuSoftware.class); 502 | //Ubuntu系统一般只要安装好系统就可以 503 | ubuntuSoftware.installSystem("Ubuntu 14.04"); 504 | System.out.println(ubuntuSoftware.finish()); 505 | 506 | //现在又要生产一批Mac(黑苹果)系统的电脑 507 | MacSoftware macSoftware = ComputerFactory.getComputer(MacSoftware.class); 508 | //黑苹果安装就有点繁琐了,首先要找驱动什么的,替换原有驱动等等,如果对黑苹果有兴趣,可去远景论坛爬贴学习. 509 | //黑苹果应该是先把找好的驱动什么的融入到安装系统中,然后才开始安装mac系统 510 | macSoftware.installAudioDriver("Mac AudioDriver"); 511 | macSoftware.installGPUDriver("Mac GPUDriver"); 512 | macSoftware.installKeyBoardDriver("Mac KeyBoardDriver"); 513 | macSoftware.installMainBoxdriver("Mac MainBoxdriver"); 514 | macSoftware.installMouseDriver("Mac MouseDriver"); 515 | macSoftware.installNetCardDriver("Mac NetCardDriver"); 516 | macSoftware.installUSBDriver("Mac USBDriver"); 517 | macSoftware.installSystem("Mac Os 10.11.6"); 518 | System.out.println(macSoftware.finish()); 519 | 520 | } 521 | } 522 | 523 | ``` 524 | 525 | 526 | **说明:** 527 | 528 | 运行结果没有发生变化,而且调用者比较简单,缺点是工厂类的拓展比较困难,不符合开闭原则,但是它仍然是一个非常实用的设计模式。 529 | 530 | 531 | 2. **升级为多个工厂类** 532 | 533 | 我们在做一个比较复杂的项目的时候,所有产品类都放到一个工厂方法中进行初始化会使代码结构不清晰。例如:一个产品类有5个具体实现。每个实现类的初始化(不仅仅是new,初始化包括new一个对象,并对对象设置一定的初始值)方法都不相同,如果写在一个工厂方法中,势必会导致该方法巨大无比,这时我们把工厂方法模式升级为多个工厂类就可以解决这个问题,下面我们还是以上述案例为例,但是每个电脑安装的驱动版本不同。下面是修改后的简单的UML类图(方法全部省略了): 534 | 535 | ![多工厂模式类图](工厂方法模式/morefactory.png) 536 | 537 | 我们以生产不同软件/系统版本的windows电脑为例,其他2种实现方式一致。 538 | 539 | 其实就是在文章最开始的例子中把一个工厂类分成了3个工厂类,使其各个工厂各司其职,提升工厂产量。 540 | 541 | 1. Factory修改为 542 | 543 | ```java 544 | /** 545 | * Created by iuni.life on 16/8/16. 546 | * yangfei's computer. 547 | */ 548 | public abstract class Factory { 549 | public abstract InstallSoftware getComputer(); 550 | } 551 | ``` 552 | 553 | 2. 增加WindowsFactory 554 | 555 | ```java 556 | /** 557 | * Created by yangfei on 16/8/16. 558 | */ 559 | public class WindowsFactory extends Factory { 560 | 561 | @Override 562 | public InstallSoftware getComputer() { 563 | return new WindowsSoftware(); 564 | } 565 | } 566 | ``` 567 | 568 | 3. 场景类 569 | 570 | ```java 571 | /** 572 | * Created by yangfei on 16/8/16. 573 | */ 574 | public class Client2 { 575 | 576 | public static void main(String[] args) { 577 | //这里举例子说明,具体驱动就不一一列举了. 578 | WindowsFactory windowsFactory = new WindowsFactory(); 579 | WindowsSoftware windowsSoftware = (WindowsSoftware) windowsFactory.getComputer(); 580 | windowsSoftware.installSystem("Windows 10"); 581 | windowsSoftware.installAudioDriver("Windows AudioDriver"); 582 | windowsSoftware.installGPUDriver("Windows GPUDriver"); 583 | windowsSoftware.installKeyBoardDriver("Windows KeyBoardDriver"); 584 | windowsSoftware.installMainBoxdriver("Windows MainBoxdrive"); 585 | windowsSoftware.installMouseDriver("Windows MouseDriver"); 586 | windowsSoftware.installNetCardDriver("Windows NetCardDriver"); 587 | windowsSoftware.installUSBDriver("Windows USBDriver"); 588 | System.out.println(windowsSoftware.finish()); 589 | } 590 | } 591 | ``` 592 | 593 | **说明:**其他2种就不举例了,实现方式类似。实现各自的Factory使其继承自Factory抽象类。 594 | 595 | 3. **替换单例模式** 596 | 597 | 通过反射实现,下面举个例子: 598 | 599 | 1. 单例类 600 | 601 | ```java 602 | /** 603 | * Created by yangfei on 16/8/16. 604 | */ 605 | public class Singleton { 606 | //不允许通过new产生一个对象 607 | private Singleton() { 608 | } 609 | 610 | public void doSomething() { 611 | //业务处理 612 | } 613 | } 614 | ``` 615 | 2. 负责生成单例的工厂类 616 | 617 | ```java 618 | import java.lang.reflect.Constructor; 619 | import java.lang.reflect.InvocationTargetException; 620 | 621 | /** 622 | * Created by yangfei on 16/8/16. 623 | */ 624 | public class SingletonFactory { 625 | private static Singleton singleton; 626 | static { 627 | try { 628 | Class c1=Class.forName(Singleton.class.getName()); 629 | //获得无参构造 630 | Constructor constructor=c1.getDeclaredConstructor(); 631 | //设置无参构造是可以访问的 632 | constructor.setAccessible(true); 633 | //产生一个实体对象 634 | singleton=(Singleton)constructor.newInstance(); 635 | } catch (ClassNotFoundException e) { 636 | e.printStackTrace(); 637 | } catch (NoSuchMethodException e) { 638 | e.printStackTrace(); 639 | } catch (IllegalAccessException e) { 640 | e.printStackTrace(); 641 | } catch (InstantiationException e) { 642 | e.printStackTrace(); 643 | } catch (InvocationTargetException e) { 644 | e.printStackTrace(); 645 | } 646 | } 647 | 648 | public static Singleton getSingleton() { 649 | return singleton; 650 | } 651 | } 652 | ``` 653 | 654 | 4. **延迟初始化** 655 | 656 | 何为延迟初始化(Lazy initialization)?一个对象被消费完毕后,并不立刻释放,工厂类保持其初始状态,等待再次被使用。延迟初始化是工厂方法模式的一个扩展应用,其通用类图如图如下所示。 657 | 658 | ![延迟初始化](工厂方法模式/lazyfactory.png) 659 | 660 | ProductFactory负责产品类对象的创建工作,并且通过prMap变量产生一个缓存,对需要再次被重用的对象保留,Product和ConcreteProduct是一个示例代码。ProductFactory如代码清单如下所示: 661 | 662 | ```java 663 | public class ProductFactory { 664 | private static final Map prMap = new HashMap(); 665 | 666 | public static synchronized Product createProduct(String type) 667 | throws Exception { 668 | Product product = null; 669 | // 如果Map中已经有这个对象 670 | if (prMap.containsKey(type)) { 671 | product = prMap.get(type); 672 | } else { 673 | if (type.equals("Product1")) { 674 | product = new ConcreteProduct1(); 675 | } else { 676 | product = new ConcreteProduct2(); 677 | } 678 | // 同时把对象放到缓存容器中 679 | prMap.put(type, product); 680 | } 681 | return product; 682 | } 683 | } 684 | ``` 685 | 686 | 通过定义一个Map容器,容纳所有产生的对象,如果在Map容器中已经有的对象,则直接取出返回;如果没有,则根据需要的类型产生一个对象并放入到Map容器中,以方便下次调用。 687 | 688 | 延迟加载框架是可以扩展的,例如限制某一个产品类的最大实例化数量,可以通过判断Map中已有的对象数量来实现,这样的处理是非常有意义的,例如JDBC连接数据库,都会 689 | 要求设置一个MaxConnections最大连接数量,该数量就是内存中最大实例化的数量。 690 | 延迟加载还可以用在对象初始化比较复杂的情况下,例如硬件访问,涉及多方面的交互,则可以通过延迟加载降低对象的产生和销毁带来的复杂性。 691 | 692 | 693 | ## 后记 694 | 695 | 文章不足之处,望大家多多指点,共同学习,共同进步。 696 | 697 | ## 参考资料 698 | 699 | - ***<<设计模式之蝉>>*** 秦小波 著 700 | 701 | ## 个人博客 702 | 703 | [iplugin.cn](http://www.iplugin.cn) 704 | 705 | -------------------------------------------------------------------------------- /工厂方法模式/factoryUml.mdj: -------------------------------------------------------------------------------- 1 | { 2 | "_type": "Project", 3 | "_id": "AAAAAAFF+h6SjaM2Hec=", 4 | "name": "Untitled", 5 | "ownedElements": [ 6 | { 7 | "_type": "UMLModel", 8 | "_id": "AAAAAAFF+qBWK6M3Z8Y=", 9 | "_parent": { 10 | "$ref": "AAAAAAFF+h6SjaM2Hec=" 11 | }, 12 | "name": "Model", 13 | "ownedElements": [ 14 | { 15 | "_type": "UMLClassDiagram", 16 | "_id": "AAAAAAFF+qBtyKM79qY=", 17 | "_parent": { 18 | "$ref": "AAAAAAFF+qBWK6M3Z8Y=" 19 | }, 20 | "name": "Main", 21 | "visible": true, 22 | "defaultDiagram": true, 23 | "ownedViews": [ 24 | { 25 | "_type": "UMLClassView", 26 | "_id": "AAAAAAFWfb8ht6WzRRc=", 27 | "_parent": { 28 | "$ref": "AAAAAAFF+qBtyKM79qY=" 29 | }, 30 | "model": { 31 | "$ref": "AAAAAAFWfb8htaWx0s0=" 32 | }, 33 | "subViews": [ 34 | { 35 | "_type": "UMLNameCompartmentView", 36 | "_id": "AAAAAAFWfb8huKW0yzQ=", 37 | "_parent": { 38 | "$ref": "AAAAAAFWfb8ht6WzRRc=" 39 | }, 40 | "model": { 41 | "$ref": "AAAAAAFWfb8htaWx0s0=" 42 | }, 43 | "subViews": [ 44 | { 45 | "_type": "LabelView", 46 | "_id": "AAAAAAFWfb8huKW1ffc=", 47 | "_parent": { 48 | "$ref": "AAAAAAFWfb8huKW0yzQ=" 49 | }, 50 | "visible": false, 51 | "enabled": true, 52 | "lineColor": "#000000", 53 | "fillColor": "#ffffff", 54 | "fontColor": "#000000", 55 | "font": "Arial;13;0", 56 | "showShadow": true, 57 | "containerChangeable": false, 58 | "containerExtending": false, 59 | "left": 0, 60 | "top": 0, 61 | "width": 0, 62 | "height": 13, 63 | "autoResize": false, 64 | "underline": false, 65 | "horizontalAlignment": 2, 66 | "verticalAlignment": 5 67 | }, 68 | { 69 | "_type": "LabelView", 70 | "_id": "AAAAAAFWfb8huKW2dD8=", 71 | "_parent": { 72 | "$ref": "AAAAAAFWfb8huKW0yzQ=" 73 | }, 74 | "visible": true, 75 | "enabled": true, 76 | "lineColor": "#000000", 77 | "fillColor": "#ffffff", 78 | "fontColor": "#000000", 79 | "font": "Arial;13;1", 80 | "showShadow": true, 81 | "containerChangeable": false, 82 | "containerExtending": false, 83 | "left": 93, 84 | "top": 231, 85 | "width": 111, 86 | "height": 13, 87 | "autoResize": false, 88 | "underline": false, 89 | "text": "Product", 90 | "horizontalAlignment": 2, 91 | "verticalAlignment": 5 92 | }, 93 | { 94 | "_type": "LabelView", 95 | "_id": "AAAAAAFWfb8huKW3p/4=", 96 | "_parent": { 97 | "$ref": "AAAAAAFWfb8huKW0yzQ=" 98 | }, 99 | "visible": false, 100 | "enabled": true, 101 | "lineColor": "#000000", 102 | "fillColor": "#ffffff", 103 | "fontColor": "#000000", 104 | "font": "Arial;13;0", 105 | "showShadow": true, 106 | "containerChangeable": false, 107 | "containerExtending": false, 108 | "left": 0, 109 | "top": 0, 110 | "width": 73, 111 | "height": 13, 112 | "autoResize": false, 113 | "underline": false, 114 | "text": "(from Model)", 115 | "horizontalAlignment": 2, 116 | "verticalAlignment": 5 117 | }, 118 | { 119 | "_type": "LabelView", 120 | "_id": "AAAAAAFWfb8huKW4Oac=", 121 | "_parent": { 122 | "$ref": "AAAAAAFWfb8huKW0yzQ=" 123 | }, 124 | "visible": false, 125 | "enabled": true, 126 | "lineColor": "#000000", 127 | "fillColor": "#ffffff", 128 | "fontColor": "#000000", 129 | "font": "Arial;13;0", 130 | "showShadow": true, 131 | "containerChangeable": false, 132 | "containerExtending": false, 133 | "left": 0, 134 | "top": 0, 135 | "width": 0, 136 | "height": 13, 137 | "autoResize": false, 138 | "underline": false, 139 | "horizontalAlignment": 1, 140 | "verticalAlignment": 5 141 | } 142 | ], 143 | "visible": true, 144 | "enabled": true, 145 | "lineColor": "#000000", 146 | "fillColor": "#ffffff", 147 | "fontColor": "#000000", 148 | "font": "Arial;13;0", 149 | "showShadow": true, 150 | "containerChangeable": false, 151 | "containerExtending": false, 152 | "left": 88, 153 | "top": 224, 154 | "width": 121, 155 | "height": 25, 156 | "autoResize": false, 157 | "stereotypeLabel": { 158 | "$ref": "AAAAAAFWfb8huKW1ffc=" 159 | }, 160 | "nameLabel": { 161 | "$ref": "AAAAAAFWfb8huKW2dD8=" 162 | }, 163 | "namespaceLabel": { 164 | "$ref": "AAAAAAFWfb8huKW3p/4=" 165 | }, 166 | "propertyLabel": { 167 | "$ref": "AAAAAAFWfb8huKW4Oac=" 168 | } 169 | }, 170 | { 171 | "_type": "UMLAttributeCompartmentView", 172 | "_id": "AAAAAAFWfb8huKW5WB4=", 173 | "_parent": { 174 | "$ref": "AAAAAAFWfb8ht6WzRRc=" 175 | }, 176 | "model": { 177 | "$ref": "AAAAAAFWfb8htaWx0s0=" 178 | }, 179 | "visible": true, 180 | "enabled": true, 181 | "lineColor": "#000000", 182 | "fillColor": "#ffffff", 183 | "fontColor": "#000000", 184 | "font": "Arial;13;0", 185 | "showShadow": true, 186 | "containerChangeable": false, 187 | "containerExtending": false, 188 | "left": 88, 189 | "top": 249, 190 | "width": 121, 191 | "height": 10, 192 | "autoResize": false 193 | }, 194 | { 195 | "_type": "UMLOperationCompartmentView", 196 | "_id": "AAAAAAFWfb8huaW6xXE=", 197 | "_parent": { 198 | "$ref": "AAAAAAFWfb8ht6WzRRc=" 199 | }, 200 | "model": { 201 | "$ref": "AAAAAAFWfb8htaWx0s0=" 202 | }, 203 | "visible": true, 204 | "enabled": true, 205 | "lineColor": "#000000", 206 | "fillColor": "#ffffff", 207 | "fontColor": "#000000", 208 | "font": "Arial;13;0", 209 | "showShadow": true, 210 | "containerChangeable": false, 211 | "containerExtending": false, 212 | "left": 88, 213 | "top": 259, 214 | "width": 121, 215 | "height": 10, 216 | "autoResize": false 217 | }, 218 | { 219 | "_type": "UMLReceptionCompartmentView", 220 | "_id": "AAAAAAFWfb8huaW7P2I=", 221 | "_parent": { 222 | "$ref": "AAAAAAFWfb8ht6WzRRc=" 223 | }, 224 | "model": { 225 | "$ref": "AAAAAAFWfb8htaWx0s0=" 226 | }, 227 | "visible": false, 228 | "enabled": true, 229 | "lineColor": "#000000", 230 | "fillColor": "#ffffff", 231 | "fontColor": "#000000", 232 | "font": "Arial;13;0", 233 | "showShadow": true, 234 | "containerChangeable": false, 235 | "containerExtending": false, 236 | "left": 0, 237 | "top": 0, 238 | "width": 10, 239 | "height": 10, 240 | "autoResize": false 241 | }, 242 | { 243 | "_type": "UMLTemplateParameterCompartmentView", 244 | "_id": "AAAAAAFWfb8huqW8aS8=", 245 | "_parent": { 246 | "$ref": "AAAAAAFWfb8ht6WzRRc=" 247 | }, 248 | "model": { 249 | "$ref": "AAAAAAFWfb8htaWx0s0=" 250 | }, 251 | "visible": false, 252 | "enabled": true, 253 | "lineColor": "#000000", 254 | "fillColor": "#ffffff", 255 | "fontColor": "#000000", 256 | "font": "Arial;13;0", 257 | "showShadow": true, 258 | "containerChangeable": false, 259 | "containerExtending": false, 260 | "left": 0, 261 | "top": 0, 262 | "width": 10, 263 | "height": 10, 264 | "autoResize": false 265 | } 266 | ], 267 | "visible": true, 268 | "enabled": true, 269 | "lineColor": "#000000", 270 | "fillColor": "#ffffff", 271 | "fontColor": "#000000", 272 | "font": "Arial;13;0", 273 | "showShadow": true, 274 | "containerChangeable": true, 275 | "containerExtending": false, 276 | "left": 88, 277 | "top": 224, 278 | "width": 121, 279 | "height": 45, 280 | "autoResize": false, 281 | "stereotypeDisplay": "label", 282 | "showVisibility": true, 283 | "showNamespace": false, 284 | "showProperty": true, 285 | "showType": true, 286 | "nameCompartment": { 287 | "$ref": "AAAAAAFWfb8huKW0yzQ=" 288 | }, 289 | "wordWrap": false, 290 | "suppressAttributes": false, 291 | "suppressOperations": false, 292 | "suppressReceptions": true, 293 | "showMultiplicity": true, 294 | "showOperationSignature": true, 295 | "attributeCompartment": { 296 | "$ref": "AAAAAAFWfb8huKW5WB4=" 297 | }, 298 | "operationCompartment": { 299 | "$ref": "AAAAAAFWfb8huaW6xXE=" 300 | }, 301 | "receptionCompartment": { 302 | "$ref": "AAAAAAFWfb8huaW7P2I=" 303 | }, 304 | "templateParameterCompartment": { 305 | "$ref": "AAAAAAFWfb8huqW8aS8=" 306 | } 307 | }, 308 | { 309 | "_type": "UMLClassView", 310 | "_id": "AAAAAAFWfb/JgaY37Ck=", 311 | "_parent": { 312 | "$ref": "AAAAAAFF+qBtyKM79qY=" 313 | }, 314 | "model": { 315 | "$ref": "AAAAAAFWfb/Jf6Y1KYA=" 316 | }, 317 | "subViews": [ 318 | { 319 | "_type": "UMLNameCompartmentView", 320 | "_id": "AAAAAAFWfb/JgaY47TQ=", 321 | "_parent": { 322 | "$ref": "AAAAAAFWfb/JgaY37Ck=" 323 | }, 324 | "model": { 325 | "$ref": "AAAAAAFWfb/Jf6Y1KYA=" 326 | }, 327 | "subViews": [ 328 | { 329 | "_type": "LabelView", 330 | "_id": "AAAAAAFWfb/JgaY5jow=", 331 | "_parent": { 332 | "$ref": "AAAAAAFWfb/JgaY47TQ=" 333 | }, 334 | "visible": false, 335 | "enabled": true, 336 | "lineColor": "#000000", 337 | "fillColor": "#ffffff", 338 | "fontColor": "#000000", 339 | "font": "Arial;13;0", 340 | "showShadow": true, 341 | "containerChangeable": false, 342 | "containerExtending": false, 343 | "left": -16, 344 | "top": 0, 345 | "width": 0, 346 | "height": 13, 347 | "autoResize": false, 348 | "underline": false, 349 | "horizontalAlignment": 2, 350 | "verticalAlignment": 5 351 | }, 352 | { 353 | "_type": "LabelView", 354 | "_id": "AAAAAAFWfb/JgaY6GS8=", 355 | "_parent": { 356 | "$ref": "AAAAAAFWfb/JgaY47TQ=" 357 | }, 358 | "visible": true, 359 | "enabled": true, 360 | "lineColor": "#000000", 361 | "fillColor": "#ffffff", 362 | "fontColor": "#000000", 363 | "font": "Arial;13;1", 364 | "showShadow": true, 365 | "containerChangeable": false, 366 | "containerExtending": false, 367 | "left": 93, 368 | "top": 345, 369 | "width": 111, 370 | "height": 13, 371 | "autoResize": false, 372 | "underline": false, 373 | "text": "ConcreteProduct", 374 | "horizontalAlignment": 2, 375 | "verticalAlignment": 5 376 | }, 377 | { 378 | "_type": "LabelView", 379 | "_id": "AAAAAAFWfb/JgaY7u44=", 380 | "_parent": { 381 | "$ref": "AAAAAAFWfb/JgaY47TQ=" 382 | }, 383 | "visible": false, 384 | "enabled": true, 385 | "lineColor": "#000000", 386 | "fillColor": "#ffffff", 387 | "fontColor": "#000000", 388 | "font": "Arial;13;0", 389 | "showShadow": true, 390 | "containerChangeable": false, 391 | "containerExtending": false, 392 | "left": -16, 393 | "top": 0, 394 | "width": 73, 395 | "height": 13, 396 | "autoResize": false, 397 | "underline": false, 398 | "text": "(from Model)", 399 | "horizontalAlignment": 2, 400 | "verticalAlignment": 5 401 | }, 402 | { 403 | "_type": "LabelView", 404 | "_id": "AAAAAAFWfb/JgaY8edM=", 405 | "_parent": { 406 | "$ref": "AAAAAAFWfb/JgaY47TQ=" 407 | }, 408 | "visible": false, 409 | "enabled": true, 410 | "lineColor": "#000000", 411 | "fillColor": "#ffffff", 412 | "fontColor": "#000000", 413 | "font": "Arial;13;0", 414 | "showShadow": true, 415 | "containerChangeable": false, 416 | "containerExtending": false, 417 | "left": -16, 418 | "top": 0, 419 | "width": 0, 420 | "height": 13, 421 | "autoResize": false, 422 | "underline": false, 423 | "horizontalAlignment": 1, 424 | "verticalAlignment": 5 425 | } 426 | ], 427 | "visible": true, 428 | "enabled": true, 429 | "lineColor": "#000000", 430 | "fillColor": "#ffffff", 431 | "fontColor": "#000000", 432 | "font": "Arial;13;0", 433 | "showShadow": true, 434 | "containerChangeable": false, 435 | "containerExtending": false, 436 | "left": 88, 437 | "top": 338, 438 | "width": 121, 439 | "height": 25, 440 | "autoResize": false, 441 | "stereotypeLabel": { 442 | "$ref": "AAAAAAFWfb/JgaY5jow=" 443 | }, 444 | "nameLabel": { 445 | "$ref": "AAAAAAFWfb/JgaY6GS8=" 446 | }, 447 | "namespaceLabel": { 448 | "$ref": "AAAAAAFWfb/JgaY7u44=" 449 | }, 450 | "propertyLabel": { 451 | "$ref": "AAAAAAFWfb/JgaY8edM=" 452 | } 453 | }, 454 | { 455 | "_type": "UMLAttributeCompartmentView", 456 | "_id": "AAAAAAFWfb/JgaY94j4=", 457 | "_parent": { 458 | "$ref": "AAAAAAFWfb/JgaY37Ck=" 459 | }, 460 | "model": { 461 | "$ref": "AAAAAAFWfb/Jf6Y1KYA=" 462 | }, 463 | "visible": true, 464 | "enabled": true, 465 | "lineColor": "#000000", 466 | "fillColor": "#ffffff", 467 | "fontColor": "#000000", 468 | "font": "Arial;13;0", 469 | "showShadow": true, 470 | "containerChangeable": false, 471 | "containerExtending": false, 472 | "left": 88, 473 | "top": 363, 474 | "width": 121, 475 | "height": 10, 476 | "autoResize": false 477 | }, 478 | { 479 | "_type": "UMLOperationCompartmentView", 480 | "_id": "AAAAAAFWfb/JgaY+DXU=", 481 | "_parent": { 482 | "$ref": "AAAAAAFWfb/JgaY37Ck=" 483 | }, 484 | "model": { 485 | "$ref": "AAAAAAFWfb/Jf6Y1KYA=" 486 | }, 487 | "visible": true, 488 | "enabled": true, 489 | "lineColor": "#000000", 490 | "fillColor": "#ffffff", 491 | "fontColor": "#000000", 492 | "font": "Arial;13;0", 493 | "showShadow": true, 494 | "containerChangeable": false, 495 | "containerExtending": false, 496 | "left": 88, 497 | "top": 373, 498 | "width": 121, 499 | "height": 10, 500 | "autoResize": false 501 | }, 502 | { 503 | "_type": "UMLReceptionCompartmentView", 504 | "_id": "AAAAAAFWfb/JgaY/y2o=", 505 | "_parent": { 506 | "$ref": "AAAAAAFWfb/JgaY37Ck=" 507 | }, 508 | "model": { 509 | "$ref": "AAAAAAFWfb/Jf6Y1KYA=" 510 | }, 511 | "visible": false, 512 | "enabled": true, 513 | "lineColor": "#000000", 514 | "fillColor": "#ffffff", 515 | "fontColor": "#000000", 516 | "font": "Arial;13;0", 517 | "showShadow": true, 518 | "containerChangeable": false, 519 | "containerExtending": false, 520 | "left": -8, 521 | "top": 0, 522 | "width": 10, 523 | "height": 10, 524 | "autoResize": false 525 | }, 526 | { 527 | "_type": "UMLTemplateParameterCompartmentView", 528 | "_id": "AAAAAAFWfb/JgqZAfOo=", 529 | "_parent": { 530 | "$ref": "AAAAAAFWfb/JgaY37Ck=" 531 | }, 532 | "model": { 533 | "$ref": "AAAAAAFWfb/Jf6Y1KYA=" 534 | }, 535 | "visible": false, 536 | "enabled": true, 537 | "lineColor": "#000000", 538 | "fillColor": "#ffffff", 539 | "fontColor": "#000000", 540 | "font": "Arial;13;0", 541 | "showShadow": true, 542 | "containerChangeable": false, 543 | "containerExtending": false, 544 | "left": -8, 545 | "top": 0, 546 | "width": 10, 547 | "height": 10, 548 | "autoResize": false 549 | } 550 | ], 551 | "visible": true, 552 | "enabled": true, 553 | "lineColor": "#000000", 554 | "fillColor": "#ffffff", 555 | "fontColor": "#000000", 556 | "font": "Arial;13;0", 557 | "showShadow": true, 558 | "containerChangeable": true, 559 | "containerExtending": false, 560 | "left": 88, 561 | "top": 338, 562 | "width": 121, 563 | "height": 45, 564 | "autoResize": false, 565 | "stereotypeDisplay": "label", 566 | "showVisibility": true, 567 | "showNamespace": false, 568 | "showProperty": true, 569 | "showType": true, 570 | "nameCompartment": { 571 | "$ref": "AAAAAAFWfb/JgaY47TQ=" 572 | }, 573 | "wordWrap": false, 574 | "suppressAttributes": false, 575 | "suppressOperations": false, 576 | "suppressReceptions": true, 577 | "showMultiplicity": true, 578 | "showOperationSignature": true, 579 | "attributeCompartment": { 580 | "$ref": "AAAAAAFWfb/JgaY94j4=" 581 | }, 582 | "operationCompartment": { 583 | "$ref": "AAAAAAFWfb/JgaY+DXU=" 584 | }, 585 | "receptionCompartment": { 586 | "$ref": "AAAAAAFWfb/JgaY/y2o=" 587 | }, 588 | "templateParameterCompartment": { 589 | "$ref": "AAAAAAFWfb/JgqZAfOo=" 590 | } 591 | }, 592 | { 593 | "_type": "UMLGeneralizationView", 594 | "_id": "AAAAAAFWfb/JrKZgVyY=", 595 | "_parent": { 596 | "$ref": "AAAAAAFF+qBtyKM79qY=" 597 | }, 598 | "model": { 599 | "$ref": "AAAAAAFWfb/JrKZeSmk=" 600 | }, 601 | "subViews": [ 602 | { 603 | "_type": "EdgeLabelView", 604 | "_id": "AAAAAAFWfb/JrKZhtPo=", 605 | "_parent": { 606 | "$ref": "AAAAAAFWfb/JrKZgVyY=" 607 | }, 608 | "model": { 609 | "$ref": "AAAAAAFWfb/JrKZeSmk=" 610 | }, 611 | "visible": false, 612 | "enabled": true, 613 | "lineColor": "#000000", 614 | "fillColor": "#ffffff", 615 | "fontColor": "#000000", 616 | "font": "Arial;13;0", 617 | "showShadow": true, 618 | "containerChangeable": false, 619 | "containerExtending": false, 620 | "left": 133, 621 | "top": 296, 622 | "width": 0, 623 | "height": 13, 624 | "autoResize": false, 625 | "alpha": 1.5707963267948966, 626 | "distance": 15, 627 | "hostEdge": { 628 | "$ref": "AAAAAAFWfb/JrKZgVyY=" 629 | }, 630 | "edgePosition": 1, 631 | "underline": false, 632 | "horizontalAlignment": 2, 633 | "verticalAlignment": 5 634 | }, 635 | { 636 | "_type": "EdgeLabelView", 637 | "_id": "AAAAAAFWfb/JrKZiAQY=", 638 | "_parent": { 639 | "$ref": "AAAAAAFWfb/JrKZgVyY=" 640 | }, 641 | "model": { 642 | "$ref": "AAAAAAFWfb/JrKZeSmk=" 643 | }, 644 | "visible": null, 645 | "enabled": true, 646 | "lineColor": "#000000", 647 | "fillColor": "#ffffff", 648 | "fontColor": "#000000", 649 | "font": "Arial;13;0", 650 | "showShadow": true, 651 | "containerChangeable": false, 652 | "containerExtending": false, 653 | "left": 118, 654 | "top": 296, 655 | "width": 0, 656 | "height": 13, 657 | "autoResize": false, 658 | "alpha": 1.5707963267948966, 659 | "distance": 30, 660 | "hostEdge": { 661 | "$ref": "AAAAAAFWfb/JrKZgVyY=" 662 | }, 663 | "edgePosition": 1, 664 | "underline": false, 665 | "horizontalAlignment": 2, 666 | "verticalAlignment": 5 667 | }, 668 | { 669 | "_type": "EdgeLabelView", 670 | "_id": "AAAAAAFWfb/JrKZjP7w=", 671 | "_parent": { 672 | "$ref": "AAAAAAFWfb/JrKZgVyY=" 673 | }, 674 | "model": { 675 | "$ref": "AAAAAAFWfb/JrKZeSmk=" 676 | }, 677 | "visible": false, 678 | "enabled": true, 679 | "lineColor": "#000000", 680 | "fillColor": "#ffffff", 681 | "fontColor": "#000000", 682 | "font": "Arial;13;0", 683 | "showShadow": true, 684 | "containerChangeable": false, 685 | "containerExtending": false, 686 | "left": 162, 687 | "top": 297, 688 | "width": 0, 689 | "height": 13, 690 | "autoResize": false, 691 | "alpha": -1.5707963267948966, 692 | "distance": 15, 693 | "hostEdge": { 694 | "$ref": "AAAAAAFWfb/JrKZgVyY=" 695 | }, 696 | "edgePosition": 1, 697 | "underline": false, 698 | "horizontalAlignment": 2, 699 | "verticalAlignment": 5 700 | } 701 | ], 702 | "visible": true, 703 | "enabled": true, 704 | "lineColor": "#000000", 705 | "fillColor": "#ffffff", 706 | "fontColor": "#000000", 707 | "font": "Arial;13;0", 708 | "showShadow": true, 709 | "containerChangeable": false, 710 | "containerExtending": false, 711 | "head": { 712 | "$ref": "AAAAAAFWfb8ht6WzRRc=" 713 | }, 714 | "tail": { 715 | "$ref": "AAAAAAFWfb/JgaY37Ck=" 716 | }, 717 | "lineStyle": 1, 718 | "points": "148:337;148:269", 719 | "stereotypeDisplay": "label", 720 | "showVisibility": true, 721 | "showProperty": true, 722 | "nameLabel": { 723 | "$ref": "AAAAAAFWfb/JrKZhtPo=" 724 | }, 725 | "stereotypeLabel": { 726 | "$ref": "AAAAAAFWfb/JrKZiAQY=" 727 | }, 728 | "propertyLabel": { 729 | "$ref": "AAAAAAFWfb/JrKZjP7w=" 730 | } 731 | }, 732 | { 733 | "_type": "UMLClassView", 734 | "_id": "AAAAAAFWfcCVWaZ3Ml0=", 735 | "_parent": { 736 | "$ref": "AAAAAAFF+qBtyKM79qY=" 737 | }, 738 | "model": { 739 | "$ref": "AAAAAAFWfcCVWKZ1uZ4=" 740 | }, 741 | "subViews": [ 742 | { 743 | "_type": "UMLNameCompartmentView", 744 | "_id": "AAAAAAFWfcCVWqZ47ac=", 745 | "_parent": { 746 | "$ref": "AAAAAAFWfcCVWaZ3Ml0=" 747 | }, 748 | "model": { 749 | "$ref": "AAAAAAFWfcCVWKZ1uZ4=" 750 | }, 751 | "subViews": [ 752 | { 753 | "_type": "LabelView", 754 | "_id": "AAAAAAFWfcCVWqZ5a1E=", 755 | "_parent": { 756 | "$ref": "AAAAAAFWfcCVWqZ47ac=" 757 | }, 758 | "visible": false, 759 | "enabled": true, 760 | "lineColor": "#000000", 761 | "fillColor": "#ffffff", 762 | "fontColor": "#000000", 763 | "font": "Arial;13;0", 764 | "showShadow": true, 765 | "containerChangeable": false, 766 | "containerExtending": false, 767 | "left": -16, 768 | "top": 32, 769 | "width": 0, 770 | "height": 13, 771 | "autoResize": false, 772 | "underline": false, 773 | "horizontalAlignment": 2, 774 | "verticalAlignment": 5 775 | }, 776 | { 777 | "_type": "LabelView", 778 | "_id": "AAAAAAFWfcCVWqZ6YvQ=", 779 | "_parent": { 780 | "$ref": "AAAAAAFWfcCVWqZ47ac=" 781 | }, 782 | "visible": true, 783 | "enabled": true, 784 | "lineColor": "#000000", 785 | "fillColor": "#ffffff", 786 | "fontColor": "#000000", 787 | "font": "Arial;13;1", 788 | "showShadow": true, 789 | "containerChangeable": false, 790 | "containerExtending": false, 791 | "left": 269, 792 | "top": 231, 793 | "width": 119, 794 | "height": 13, 795 | "autoResize": false, 796 | "underline": false, 797 | "text": "Creator", 798 | "horizontalAlignment": 2, 799 | "verticalAlignment": 5 800 | }, 801 | { 802 | "_type": "LabelView", 803 | "_id": "AAAAAAFWfcCVW6Z7SGA=", 804 | "_parent": { 805 | "$ref": "AAAAAAFWfcCVWqZ47ac=" 806 | }, 807 | "visible": false, 808 | "enabled": true, 809 | "lineColor": "#000000", 810 | "fillColor": "#ffffff", 811 | "fontColor": "#000000", 812 | "font": "Arial;13;0", 813 | "showShadow": true, 814 | "containerChangeable": false, 815 | "containerExtending": false, 816 | "left": -16, 817 | "top": 32, 818 | "width": 73, 819 | "height": 13, 820 | "autoResize": false, 821 | "underline": false, 822 | "text": "(from Model)", 823 | "horizontalAlignment": 2, 824 | "verticalAlignment": 5 825 | }, 826 | { 827 | "_type": "LabelView", 828 | "_id": "AAAAAAFWfcCVW6Z8J/c=", 829 | "_parent": { 830 | "$ref": "AAAAAAFWfcCVWqZ47ac=" 831 | }, 832 | "visible": false, 833 | "enabled": true, 834 | "lineColor": "#000000", 835 | "fillColor": "#ffffff", 836 | "fontColor": "#000000", 837 | "font": "Arial;13;0", 838 | "showShadow": true, 839 | "containerChangeable": false, 840 | "containerExtending": false, 841 | "left": -16, 842 | "top": 32, 843 | "width": 0, 844 | "height": 13, 845 | "autoResize": false, 846 | "underline": false, 847 | "horizontalAlignment": 1, 848 | "verticalAlignment": 5 849 | } 850 | ], 851 | "visible": true, 852 | "enabled": true, 853 | "lineColor": "#000000", 854 | "fillColor": "#ffffff", 855 | "fontColor": "#000000", 856 | "font": "Arial;13;0", 857 | "showShadow": true, 858 | "containerChangeable": false, 859 | "containerExtending": false, 860 | "left": 264, 861 | "top": 224, 862 | "width": 129, 863 | "height": 25, 864 | "autoResize": false, 865 | "stereotypeLabel": { 866 | "$ref": "AAAAAAFWfcCVWqZ5a1E=" 867 | }, 868 | "nameLabel": { 869 | "$ref": "AAAAAAFWfcCVWqZ6YvQ=" 870 | }, 871 | "namespaceLabel": { 872 | "$ref": "AAAAAAFWfcCVW6Z7SGA=" 873 | }, 874 | "propertyLabel": { 875 | "$ref": "AAAAAAFWfcCVW6Z8J/c=" 876 | } 877 | }, 878 | { 879 | "_type": "UMLAttributeCompartmentView", 880 | "_id": "AAAAAAFWfcCVW6Z9ucU=", 881 | "_parent": { 882 | "$ref": "AAAAAAFWfcCVWaZ3Ml0=" 883 | }, 884 | "model": { 885 | "$ref": "AAAAAAFWfcCVWKZ1uZ4=" 886 | }, 887 | "visible": true, 888 | "enabled": true, 889 | "lineColor": "#000000", 890 | "fillColor": "#ffffff", 891 | "fontColor": "#000000", 892 | "font": "Arial;13;0", 893 | "showShadow": true, 894 | "containerChangeable": false, 895 | "containerExtending": false, 896 | "left": 264, 897 | "top": 249, 898 | "width": 129, 899 | "height": 10, 900 | "autoResize": false 901 | }, 902 | { 903 | "_type": "UMLOperationCompartmentView", 904 | "_id": "AAAAAAFWfcCVW6Z+Eck=", 905 | "_parent": { 906 | "$ref": "AAAAAAFWfcCVWaZ3Ml0=" 907 | }, 908 | "model": { 909 | "$ref": "AAAAAAFWfcCVWKZ1uZ4=" 910 | }, 911 | "subViews": [ 912 | { 913 | "_type": "UMLOperationView", 914 | "_id": "AAAAAAFWfcGjjqbnGOI=", 915 | "_parent": { 916 | "$ref": "AAAAAAFWfcCVW6Z+Eck=" 917 | }, 918 | "model": { 919 | "$ref": "AAAAAAFWfcGjZKbkAdo=" 920 | }, 921 | "visible": true, 922 | "enabled": true, 923 | "lineColor": "#000000", 924 | "fillColor": "#ffffff", 925 | "fontColor": "#000000", 926 | "font": "Arial;13;0", 927 | "showShadow": true, 928 | "containerChangeable": false, 929 | "containerExtending": false, 930 | "left": 269, 931 | "top": 264, 932 | "width": 119, 933 | "height": 13, 934 | "autoResize": false, 935 | "underline": false, 936 | "text": "+FactoryMethod()", 937 | "horizontalAlignment": 0, 938 | "verticalAlignment": 5 939 | } 940 | ], 941 | "visible": true, 942 | "enabled": true, 943 | "lineColor": "#000000", 944 | "fillColor": "#ffffff", 945 | "fontColor": "#000000", 946 | "font": "Arial;13;0", 947 | "showShadow": true, 948 | "containerChangeable": false, 949 | "containerExtending": false, 950 | "left": 264, 951 | "top": 259, 952 | "width": 129, 953 | "height": 23, 954 | "autoResize": false 955 | }, 956 | { 957 | "_type": "UMLReceptionCompartmentView", 958 | "_id": "AAAAAAFWfcCVW6Z/r/U=", 959 | "_parent": { 960 | "$ref": "AAAAAAFWfcCVWaZ3Ml0=" 961 | }, 962 | "model": { 963 | "$ref": "AAAAAAFWfcCVWKZ1uZ4=" 964 | }, 965 | "visible": false, 966 | "enabled": true, 967 | "lineColor": "#000000", 968 | "fillColor": "#ffffff", 969 | "fontColor": "#000000", 970 | "font": "Arial;13;0", 971 | "showShadow": true, 972 | "containerChangeable": false, 973 | "containerExtending": false, 974 | "left": -8, 975 | "top": 16, 976 | "width": 10, 977 | "height": 10, 978 | "autoResize": false 979 | }, 980 | { 981 | "_type": "UMLTemplateParameterCompartmentView", 982 | "_id": "AAAAAAFWfcCVXKaAo8o=", 983 | "_parent": { 984 | "$ref": "AAAAAAFWfcCVWaZ3Ml0=" 985 | }, 986 | "model": { 987 | "$ref": "AAAAAAFWfcCVWKZ1uZ4=" 988 | }, 989 | "visible": false, 990 | "enabled": true, 991 | "lineColor": "#000000", 992 | "fillColor": "#ffffff", 993 | "fontColor": "#000000", 994 | "font": "Arial;13;0", 995 | "showShadow": true, 996 | "containerChangeable": false, 997 | "containerExtending": false, 998 | "left": -8, 999 | "top": 16, 1000 | "width": 10, 1001 | "height": 10, 1002 | "autoResize": false 1003 | } 1004 | ], 1005 | "visible": true, 1006 | "enabled": true, 1007 | "lineColor": "#000000", 1008 | "fillColor": "#ffffff", 1009 | "fontColor": "#000000", 1010 | "font": "Arial;13;0", 1011 | "showShadow": true, 1012 | "containerChangeable": true, 1013 | "containerExtending": false, 1014 | "left": 264, 1015 | "top": 224, 1016 | "width": 129, 1017 | "height": 58, 1018 | "autoResize": false, 1019 | "stereotypeDisplay": "label", 1020 | "showVisibility": true, 1021 | "showNamespace": false, 1022 | "showProperty": true, 1023 | "showType": true, 1024 | "nameCompartment": { 1025 | "$ref": "AAAAAAFWfcCVWqZ47ac=" 1026 | }, 1027 | "wordWrap": false, 1028 | "suppressAttributes": false, 1029 | "suppressOperations": false, 1030 | "suppressReceptions": true, 1031 | "showMultiplicity": true, 1032 | "showOperationSignature": true, 1033 | "attributeCompartment": { 1034 | "$ref": "AAAAAAFWfcCVW6Z9ucU=" 1035 | }, 1036 | "operationCompartment": { 1037 | "$ref": "AAAAAAFWfcCVW6Z+Eck=" 1038 | }, 1039 | "receptionCompartment": { 1040 | "$ref": "AAAAAAFWfcCVW6Z/r/U=" 1041 | }, 1042 | "templateParameterCompartment": { 1043 | "$ref": "AAAAAAFWfcCVXKaAo8o=" 1044 | } 1045 | }, 1046 | { 1047 | "_type": "UMLClassView", 1048 | "_id": "AAAAAAFWfcDnl6akvx0=", 1049 | "_parent": { 1050 | "$ref": "AAAAAAFF+qBtyKM79qY=" 1051 | }, 1052 | "model": { 1053 | "$ref": "AAAAAAFWfcDnlqaiycU=" 1054 | }, 1055 | "subViews": [ 1056 | { 1057 | "_type": "UMLNameCompartmentView", 1058 | "_id": "AAAAAAFWfcDnl6alh98=", 1059 | "_parent": { 1060 | "$ref": "AAAAAAFWfcDnl6akvx0=" 1061 | }, 1062 | "model": { 1063 | "$ref": "AAAAAAFWfcDnlqaiycU=" 1064 | }, 1065 | "subViews": [ 1066 | { 1067 | "_type": "LabelView", 1068 | "_id": "AAAAAAFWfcDnmKamicg=", 1069 | "_parent": { 1070 | "$ref": "AAAAAAFWfcDnl6alh98=" 1071 | }, 1072 | "visible": false, 1073 | "enabled": true, 1074 | "lineColor": "#000000", 1075 | "fillColor": "#ffffff", 1076 | "fontColor": "#000000", 1077 | "font": "Arial;13;0", 1078 | "showShadow": true, 1079 | "containerChangeable": false, 1080 | "containerExtending": false, 1081 | "left": 48, 1082 | "top": 0, 1083 | "width": 0, 1084 | "height": 13, 1085 | "autoResize": false, 1086 | "underline": false, 1087 | "horizontalAlignment": 2, 1088 | "verticalAlignment": 5 1089 | }, 1090 | { 1091 | "_type": "LabelView", 1092 | "_id": "AAAAAAFWfcDnmKan0qo=", 1093 | "_parent": { 1094 | "$ref": "AAAAAAFWfcDnl6alh98=" 1095 | }, 1096 | "visible": true, 1097 | "enabled": true, 1098 | "lineColor": "#000000", 1099 | "fillColor": "#ffffff", 1100 | "fontColor": "#000000", 1101 | "font": "Arial;13;1", 1102 | "showShadow": true, 1103 | "containerChangeable": false, 1104 | "containerExtending": false, 1105 | "left": 269, 1106 | "top": 345, 1107 | "width": 119, 1108 | "height": 13, 1109 | "autoResize": false, 1110 | "underline": false, 1111 | "text": "ConcreateCreator", 1112 | "horizontalAlignment": 2, 1113 | "verticalAlignment": 5 1114 | }, 1115 | { 1116 | "_type": "LabelView", 1117 | "_id": "AAAAAAFWfcDnmKaoHtQ=", 1118 | "_parent": { 1119 | "$ref": "AAAAAAFWfcDnl6alh98=" 1120 | }, 1121 | "visible": false, 1122 | "enabled": true, 1123 | "lineColor": "#000000", 1124 | "fillColor": "#ffffff", 1125 | "fontColor": "#000000", 1126 | "font": "Arial;13;0", 1127 | "showShadow": true, 1128 | "containerChangeable": false, 1129 | "containerExtending": false, 1130 | "left": 48, 1131 | "top": 0, 1132 | "width": 73, 1133 | "height": 13, 1134 | "autoResize": false, 1135 | "underline": false, 1136 | "text": "(from Model)", 1137 | "horizontalAlignment": 2, 1138 | "verticalAlignment": 5 1139 | }, 1140 | { 1141 | "_type": "LabelView", 1142 | "_id": "AAAAAAFWfcDnmKaptRE=", 1143 | "_parent": { 1144 | "$ref": "AAAAAAFWfcDnl6alh98=" 1145 | }, 1146 | "visible": false, 1147 | "enabled": true, 1148 | "lineColor": "#000000", 1149 | "fillColor": "#ffffff", 1150 | "fontColor": "#000000", 1151 | "font": "Arial;13;0", 1152 | "showShadow": true, 1153 | "containerChangeable": false, 1154 | "containerExtending": false, 1155 | "left": 48, 1156 | "top": 0, 1157 | "width": 0, 1158 | "height": 13, 1159 | "autoResize": false, 1160 | "underline": false, 1161 | "horizontalAlignment": 1, 1162 | "verticalAlignment": 5 1163 | } 1164 | ], 1165 | "visible": true, 1166 | "enabled": true, 1167 | "lineColor": "#000000", 1168 | "fillColor": "#ffffff", 1169 | "fontColor": "#000000", 1170 | "font": "Arial;13;0", 1171 | "showShadow": true, 1172 | "containerChangeable": false, 1173 | "containerExtending": false, 1174 | "left": 264, 1175 | "top": 338, 1176 | "width": 129, 1177 | "height": 25, 1178 | "autoResize": false, 1179 | "stereotypeLabel": { 1180 | "$ref": "AAAAAAFWfcDnmKamicg=" 1181 | }, 1182 | "nameLabel": { 1183 | "$ref": "AAAAAAFWfcDnmKan0qo=" 1184 | }, 1185 | "namespaceLabel": { 1186 | "$ref": "AAAAAAFWfcDnmKaoHtQ=" 1187 | }, 1188 | "propertyLabel": { 1189 | "$ref": "AAAAAAFWfcDnmKaptRE=" 1190 | } 1191 | }, 1192 | { 1193 | "_type": "UMLAttributeCompartmentView", 1194 | "_id": "AAAAAAFWfcDnmKaqWwk=", 1195 | "_parent": { 1196 | "$ref": "AAAAAAFWfcDnl6akvx0=" 1197 | }, 1198 | "model": { 1199 | "$ref": "AAAAAAFWfcDnlqaiycU=" 1200 | }, 1201 | "visible": true, 1202 | "enabled": true, 1203 | "lineColor": "#000000", 1204 | "fillColor": "#ffffff", 1205 | "fontColor": "#000000", 1206 | "font": "Arial;13;0", 1207 | "showShadow": true, 1208 | "containerChangeable": false, 1209 | "containerExtending": false, 1210 | "left": 264, 1211 | "top": 363, 1212 | "width": 129, 1213 | "height": 10, 1214 | "autoResize": false 1215 | }, 1216 | { 1217 | "_type": "UMLOperationCompartmentView", 1218 | "_id": "AAAAAAFWfcDnmaarL+U=", 1219 | "_parent": { 1220 | "$ref": "AAAAAAFWfcDnl6akvx0=" 1221 | }, 1222 | "model": { 1223 | "$ref": "AAAAAAFWfcDnlqaiycU=" 1224 | }, 1225 | "visible": true, 1226 | "enabled": true, 1227 | "lineColor": "#000000", 1228 | "fillColor": "#ffffff", 1229 | "fontColor": "#000000", 1230 | "font": "Arial;13;0", 1231 | "showShadow": true, 1232 | "containerChangeable": false, 1233 | "containerExtending": false, 1234 | "left": 264, 1235 | "top": 373, 1236 | "width": 129, 1237 | "height": 10, 1238 | "autoResize": false 1239 | }, 1240 | { 1241 | "_type": "UMLReceptionCompartmentView", 1242 | "_id": "AAAAAAFWfcDnmaaswic=", 1243 | "_parent": { 1244 | "$ref": "AAAAAAFWfcDnl6akvx0=" 1245 | }, 1246 | "model": { 1247 | "$ref": "AAAAAAFWfcDnlqaiycU=" 1248 | }, 1249 | "visible": false, 1250 | "enabled": true, 1251 | "lineColor": "#000000", 1252 | "fillColor": "#ffffff", 1253 | "fontColor": "#000000", 1254 | "font": "Arial;13;0", 1255 | "showShadow": true, 1256 | "containerChangeable": false, 1257 | "containerExtending": false, 1258 | "left": 24, 1259 | "top": 0, 1260 | "width": 10, 1261 | "height": 10, 1262 | "autoResize": false 1263 | }, 1264 | { 1265 | "_type": "UMLTemplateParameterCompartmentView", 1266 | "_id": "AAAAAAFWfcDnmaatbyE=", 1267 | "_parent": { 1268 | "$ref": "AAAAAAFWfcDnl6akvx0=" 1269 | }, 1270 | "model": { 1271 | "$ref": "AAAAAAFWfcDnlqaiycU=" 1272 | }, 1273 | "visible": false, 1274 | "enabled": true, 1275 | "lineColor": "#000000", 1276 | "fillColor": "#ffffff", 1277 | "fontColor": "#000000", 1278 | "font": "Arial;13;0", 1279 | "showShadow": true, 1280 | "containerChangeable": false, 1281 | "containerExtending": false, 1282 | "left": 24, 1283 | "top": 0, 1284 | "width": 10, 1285 | "height": 10, 1286 | "autoResize": false 1287 | } 1288 | ], 1289 | "visible": true, 1290 | "enabled": true, 1291 | "lineColor": "#000000", 1292 | "fillColor": "#ffffff", 1293 | "fontColor": "#000000", 1294 | "font": "Arial;13;0", 1295 | "showShadow": true, 1296 | "containerChangeable": true, 1297 | "containerExtending": false, 1298 | "left": 264, 1299 | "top": 338, 1300 | "width": 129, 1301 | "height": 45, 1302 | "autoResize": false, 1303 | "stereotypeDisplay": "label", 1304 | "showVisibility": true, 1305 | "showNamespace": false, 1306 | "showProperty": true, 1307 | "showType": true, 1308 | "nameCompartment": { 1309 | "$ref": "AAAAAAFWfcDnl6alh98=" 1310 | }, 1311 | "wordWrap": false, 1312 | "suppressAttributes": false, 1313 | "suppressOperations": false, 1314 | "suppressReceptions": true, 1315 | "showMultiplicity": true, 1316 | "showOperationSignature": true, 1317 | "attributeCompartment": { 1318 | "$ref": "AAAAAAFWfcDnmKaqWwk=" 1319 | }, 1320 | "operationCompartment": { 1321 | "$ref": "AAAAAAFWfcDnmaarL+U=" 1322 | }, 1323 | "receptionCompartment": { 1324 | "$ref": "AAAAAAFWfcDnmaaswic=" 1325 | }, 1326 | "templateParameterCompartment": { 1327 | "$ref": "AAAAAAFWfcDnmaatbyE=" 1328 | } 1329 | }, 1330 | { 1331 | "_type": "UMLGeneralizationView", 1332 | "_id": "AAAAAAFWfcDnz6bNFQY=", 1333 | "_parent": { 1334 | "$ref": "AAAAAAFF+qBtyKM79qY=" 1335 | }, 1336 | "model": { 1337 | "$ref": "AAAAAAFWfcDnz6bLnRg=" 1338 | }, 1339 | "subViews": [ 1340 | { 1341 | "_type": "EdgeLabelView", 1342 | "_id": "AAAAAAFWfcDn0KbOvoI=", 1343 | "_parent": { 1344 | "$ref": "AAAAAAFWfcDnz6bNFQY=" 1345 | }, 1346 | "model": { 1347 | "$ref": "AAAAAAFWfcDnz6bLnRg=" 1348 | }, 1349 | "visible": false, 1350 | "enabled": true, 1351 | "lineColor": "#000000", 1352 | "fillColor": "#ffffff", 1353 | "fontColor": "#000000", 1354 | "font": "Arial;13;0", 1355 | "showShadow": true, 1356 | "containerChangeable": false, 1357 | "containerExtending": false, 1358 | "left": 313, 1359 | "top": 302, 1360 | "width": 0, 1361 | "height": 13, 1362 | "autoResize": false, 1363 | "alpha": 1.5707963267948966, 1364 | "distance": 15, 1365 | "hostEdge": { 1366 | "$ref": "AAAAAAFWfcDnz6bNFQY=" 1367 | }, 1368 | "edgePosition": 1, 1369 | "underline": false, 1370 | "horizontalAlignment": 2, 1371 | "verticalAlignment": 5 1372 | }, 1373 | { 1374 | "_type": "EdgeLabelView", 1375 | "_id": "AAAAAAFWfcDn0KbPQx4=", 1376 | "_parent": { 1377 | "$ref": "AAAAAAFWfcDnz6bNFQY=" 1378 | }, 1379 | "model": { 1380 | "$ref": "AAAAAAFWfcDnz6bLnRg=" 1381 | }, 1382 | "visible": null, 1383 | "enabled": true, 1384 | "lineColor": "#000000", 1385 | "fillColor": "#ffffff", 1386 | "fontColor": "#000000", 1387 | "font": "Arial;13;0", 1388 | "showShadow": true, 1389 | "containerChangeable": false, 1390 | "containerExtending": false, 1391 | "left": 298, 1392 | "top": 302, 1393 | "width": 0, 1394 | "height": 13, 1395 | "autoResize": false, 1396 | "alpha": 1.5707963267948966, 1397 | "distance": 30, 1398 | "hostEdge": { 1399 | "$ref": "AAAAAAFWfcDnz6bNFQY=" 1400 | }, 1401 | "edgePosition": 1, 1402 | "underline": false, 1403 | "horizontalAlignment": 2, 1404 | "verticalAlignment": 5 1405 | }, 1406 | { 1407 | "_type": "EdgeLabelView", 1408 | "_id": "AAAAAAFWfcDn0KbQ9Xw=", 1409 | "_parent": { 1410 | "$ref": "AAAAAAFWfcDnz6bNFQY=" 1411 | }, 1412 | "model": { 1413 | "$ref": "AAAAAAFWfcDnz6bLnRg=" 1414 | }, 1415 | "visible": false, 1416 | "enabled": true, 1417 | "lineColor": "#000000", 1418 | "fillColor": "#ffffff", 1419 | "fontColor": "#000000", 1420 | "font": "Arial;13;0", 1421 | "showShadow": true, 1422 | "containerChangeable": false, 1423 | "containerExtending": false, 1424 | "left": 342, 1425 | "top": 303, 1426 | "width": 0, 1427 | "height": 13, 1428 | "autoResize": false, 1429 | "alpha": -1.5707963267948966, 1430 | "distance": 15, 1431 | "hostEdge": { 1432 | "$ref": "AAAAAAFWfcDnz6bNFQY=" 1433 | }, 1434 | "edgePosition": 1, 1435 | "underline": false, 1436 | "horizontalAlignment": 2, 1437 | "verticalAlignment": 5 1438 | } 1439 | ], 1440 | "visible": true, 1441 | "enabled": true, 1442 | "lineColor": "#000000", 1443 | "fillColor": "#ffffff", 1444 | "fontColor": "#000000", 1445 | "font": "Arial;13;0", 1446 | "showShadow": true, 1447 | "containerChangeable": false, 1448 | "containerExtending": false, 1449 | "head": { 1450 | "$ref": "AAAAAAFWfcCVWaZ3Ml0=" 1451 | }, 1452 | "tail": { 1453 | "$ref": "AAAAAAFWfcDnl6akvx0=" 1454 | }, 1455 | "lineStyle": 1, 1456 | "points": "328:337;328:282", 1457 | "stereotypeDisplay": "label", 1458 | "showVisibility": true, 1459 | "showProperty": true, 1460 | "nameLabel": { 1461 | "$ref": "AAAAAAFWfcDn0KbOvoI=" 1462 | }, 1463 | "stereotypeLabel": { 1464 | "$ref": "AAAAAAFWfcDn0KbPQx4=" 1465 | }, 1466 | "propertyLabel": { 1467 | "$ref": "AAAAAAFWfcDn0KbQ9Xw=" 1468 | } 1469 | }, 1470 | { 1471 | "_type": "UMLDependencyView", 1472 | "_id": "AAAAAAFWfcIXjKbu1u0=", 1473 | "_parent": { 1474 | "$ref": "AAAAAAFF+qBtyKM79qY=" 1475 | }, 1476 | "model": { 1477 | "$ref": "AAAAAAFWfcIXi6bsQW4=" 1478 | }, 1479 | "subViews": [ 1480 | { 1481 | "_type": "EdgeLabelView", 1482 | "_id": "AAAAAAFWfcIXjKbvQss=", 1483 | "_parent": { 1484 | "$ref": "AAAAAAFWfcIXjKbu1u0=" 1485 | }, 1486 | "model": { 1487 | "$ref": "AAAAAAFWfcIXi6bsQW4=" 1488 | }, 1489 | "visible": false, 1490 | "enabled": true, 1491 | "lineColor": "#000000", 1492 | "fillColor": "#ffffff", 1493 | "fontColor": "#000000", 1494 | "font": "Arial;13;0", 1495 | "showShadow": true, 1496 | "containerChangeable": false, 1497 | "containerExtending": false, 1498 | "left": 235, 1499 | "top": 369, 1500 | "width": 0, 1501 | "height": 13, 1502 | "autoResize": false, 1503 | "alpha": 1.5707963267948966, 1504 | "distance": 15, 1505 | "hostEdge": { 1506 | "$ref": "AAAAAAFWfcIXjKbu1u0=" 1507 | }, 1508 | "edgePosition": 1, 1509 | "underline": false, 1510 | "horizontalAlignment": 2, 1511 | "verticalAlignment": 5 1512 | }, 1513 | { 1514 | "_type": "EdgeLabelView", 1515 | "_id": "AAAAAAFWfcIXjKbw19g=", 1516 | "_parent": { 1517 | "$ref": "AAAAAAFWfcIXjKbu1u0=" 1518 | }, 1519 | "model": { 1520 | "$ref": "AAAAAAFWfcIXi6bsQW4=" 1521 | }, 1522 | "visible": null, 1523 | "enabled": true, 1524 | "lineColor": "#000000", 1525 | "fillColor": "#ffffff", 1526 | "fontColor": "#000000", 1527 | "font": "Arial;13;0", 1528 | "showShadow": true, 1529 | "containerChangeable": false, 1530 | "containerExtending": false, 1531 | "left": 235, 1532 | "top": 384, 1533 | "width": 0, 1534 | "height": 13, 1535 | "autoResize": false, 1536 | "alpha": 1.5707963267948966, 1537 | "distance": 30, 1538 | "hostEdge": { 1539 | "$ref": "AAAAAAFWfcIXjKbu1u0=" 1540 | }, 1541 | "edgePosition": 1, 1542 | "underline": false, 1543 | "horizontalAlignment": 2, 1544 | "verticalAlignment": 5 1545 | }, 1546 | { 1547 | "_type": "EdgeLabelView", 1548 | "_id": "AAAAAAFWfcIXjabxw3c=", 1549 | "_parent": { 1550 | "$ref": "AAAAAAFWfcIXjKbu1u0=" 1551 | }, 1552 | "model": { 1553 | "$ref": "AAAAAAFWfcIXi6bsQW4=" 1554 | }, 1555 | "visible": false, 1556 | "enabled": true, 1557 | "lineColor": "#000000", 1558 | "fillColor": "#ffffff", 1559 | "fontColor": "#000000", 1560 | "font": "Arial;13;0", 1561 | "showShadow": true, 1562 | "containerChangeable": false, 1563 | "containerExtending": false, 1564 | "left": 236, 1565 | "top": 339, 1566 | "width": 0, 1567 | "height": 13, 1568 | "autoResize": false, 1569 | "alpha": -1.5707963267948966, 1570 | "distance": 15, 1571 | "hostEdge": { 1572 | "$ref": "AAAAAAFWfcIXjKbu1u0=" 1573 | }, 1574 | "edgePosition": 1, 1575 | "underline": false, 1576 | "horizontalAlignment": 2, 1577 | "verticalAlignment": 5 1578 | } 1579 | ], 1580 | "visible": true, 1581 | "enabled": true, 1582 | "lineColor": "#000000", 1583 | "fillColor": "#ffffff", 1584 | "fontColor": "#000000", 1585 | "font": "Arial;13;0", 1586 | "showShadow": true, 1587 | "containerChangeable": false, 1588 | "containerExtending": false, 1589 | "head": { 1590 | "$ref": "AAAAAAFWfb/JgaY37Ck=" 1591 | }, 1592 | "tail": { 1593 | "$ref": "AAAAAAFWfcDnl6akvx0=" 1594 | }, 1595 | "lineStyle": 0, 1596 | "points": "264:360;208:360", 1597 | "stereotypeDisplay": "label", 1598 | "showVisibility": true, 1599 | "showProperty": true, 1600 | "nameLabel": { 1601 | "$ref": "AAAAAAFWfcIXjKbvQss=" 1602 | }, 1603 | "stereotypeLabel": { 1604 | "$ref": "AAAAAAFWfcIXjKbw19g=" 1605 | }, 1606 | "propertyLabel": { 1607 | "$ref": "AAAAAAFWfcIXjabxw3c=" 1608 | } 1609 | }, 1610 | { 1611 | "_type": "UMLTextView", 1612 | "_id": "AAAAAAFWfcKW+qcApd0=", 1613 | "_parent": { 1614 | "$ref": "AAAAAAFF+qBtyKM79qY=" 1615 | }, 1616 | "visible": true, 1617 | "enabled": true, 1618 | "lineColor": "#000000", 1619 | "fillColor": "#ffffff", 1620 | "fontColor": "#000000", 1621 | "font": "Arial;13;0", 1622 | "showShadow": true, 1623 | "containerChangeable": false, 1624 | "containerExtending": false, 1625 | "left": 184, 1626 | "top": 424, 1627 | "width": 167, 1628 | "height": 25, 1629 | "autoResize": false, 1630 | "text": "工厂方法模式通用UML类图", 1631 | "wordWrap": true 1632 | } 1633 | ] 1634 | }, 1635 | { 1636 | "_type": "UMLClass", 1637 | "_id": "AAAAAAFWfb8htaWx0s0=", 1638 | "_parent": { 1639 | "$ref": "AAAAAAFF+qBWK6M3Z8Y=" 1640 | }, 1641 | "name": "Product", 1642 | "ownedElements": [ 1643 | { 1644 | "_type": "UMLGeneralization", 1645 | "_id": "AAAAAAFWfb+CvaYFjLE=", 1646 | "_parent": { 1647 | "$ref": "AAAAAAFWfb8htaWx0s0=" 1648 | }, 1649 | "source": { 1650 | "$ref": "AAAAAAFWfb8htaWx0s0=" 1651 | }, 1652 | "target": { 1653 | "$ref": "AAAAAAFWfb+CiKXcIoo=" 1654 | }, 1655 | "visibility": "public" 1656 | } 1657 | ], 1658 | "visibility": "public", 1659 | "isAbstract": false, 1660 | "isFinalSpecialization": false, 1661 | "isLeaf": false, 1662 | "isActive": false 1663 | }, 1664 | { 1665 | "_type": "UMLClass", 1666 | "_id": "AAAAAAFWfb+CiKXcIoo=", 1667 | "_parent": { 1668 | "$ref": "AAAAAAFF+qBWK6M3Z8Y=" 1669 | }, 1670 | "name": "Class1", 1671 | "visibility": "public", 1672 | "isAbstract": false, 1673 | "isFinalSpecialization": false, 1674 | "isLeaf": false, 1675 | "isActive": false 1676 | }, 1677 | { 1678 | "_type": "UMLClass", 1679 | "_id": "AAAAAAFWfb/Jf6Y1KYA=", 1680 | "_parent": { 1681 | "$ref": "AAAAAAFF+qBWK6M3Z8Y=" 1682 | }, 1683 | "name": "ConcreteProduct", 1684 | "ownedElements": [ 1685 | { 1686 | "_type": "UMLGeneralization", 1687 | "_id": "AAAAAAFWfb/JrKZeSmk=", 1688 | "_parent": { 1689 | "$ref": "AAAAAAFWfb/Jf6Y1KYA=" 1690 | }, 1691 | "source": { 1692 | "$ref": "AAAAAAFWfb/Jf6Y1KYA=" 1693 | }, 1694 | "target": { 1695 | "$ref": "AAAAAAFWfb8htaWx0s0=" 1696 | }, 1697 | "visibility": "public" 1698 | }, 1699 | { 1700 | "_type": "UMLDependency", 1701 | "_id": "AAAAAAFWfcIXi6bsQW4=", 1702 | "_parent": { 1703 | "$ref": "AAAAAAFWfb/Jf6Y1KYA=" 1704 | }, 1705 | "source": { 1706 | "$ref": "AAAAAAFWfcDnlqaiycU=" 1707 | }, 1708 | "target": { 1709 | "$ref": "AAAAAAFWfb/Jf6Y1KYA=" 1710 | }, 1711 | "visibility": "public" 1712 | } 1713 | ], 1714 | "visibility": "public", 1715 | "isAbstract": false, 1716 | "isFinalSpecialization": false, 1717 | "isLeaf": false, 1718 | "isActive": false 1719 | }, 1720 | { 1721 | "_type": "UMLClass", 1722 | "_id": "AAAAAAFWfcCVWKZ1uZ4=", 1723 | "_parent": { 1724 | "$ref": "AAAAAAFF+qBWK6M3Z8Y=" 1725 | }, 1726 | "name": "Creator", 1727 | "visibility": "public", 1728 | "operations": [ 1729 | { 1730 | "_type": "UMLOperation", 1731 | "_id": "AAAAAAFWfcGjZKbkAdo=", 1732 | "_parent": { 1733 | "$ref": "AAAAAAFWfcCVWKZ1uZ4=" 1734 | }, 1735 | "name": "FactoryMethod", 1736 | "visibility": "public", 1737 | "isStatic": false, 1738 | "isLeaf": false, 1739 | "concurrency": "sequential", 1740 | "isQuery": false, 1741 | "isAbstract": false 1742 | } 1743 | ], 1744 | "isAbstract": false, 1745 | "isFinalSpecialization": false, 1746 | "isLeaf": false, 1747 | "isActive": false 1748 | }, 1749 | { 1750 | "_type": "UMLClass", 1751 | "_id": "AAAAAAFWfcDnlqaiycU=", 1752 | "_parent": { 1753 | "$ref": "AAAAAAFF+qBWK6M3Z8Y=" 1754 | }, 1755 | "name": "ConcreateCreator", 1756 | "ownedElements": [ 1757 | { 1758 | "_type": "UMLGeneralization", 1759 | "_id": "AAAAAAFWfcDnz6bLnRg=", 1760 | "_parent": { 1761 | "$ref": "AAAAAAFWfcDnlqaiycU=" 1762 | }, 1763 | "source": { 1764 | "$ref": "AAAAAAFWfcDnlqaiycU=" 1765 | }, 1766 | "target": { 1767 | "$ref": "AAAAAAFWfcCVWKZ1uZ4=" 1768 | }, 1769 | "visibility": "public" 1770 | } 1771 | ], 1772 | "visibility": "public", 1773 | "isAbstract": false, 1774 | "isFinalSpecialization": false, 1775 | "isLeaf": false, 1776 | "isActive": false 1777 | } 1778 | ], 1779 | "visibility": "public" 1780 | } 1781 | ] 1782 | } -------------------------------------------------------------------------------- /工厂方法模式/factoryUml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/工厂方法模式/factoryUml.png -------------------------------------------------------------------------------- /工厂方法模式/factoryresult.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/工厂方法模式/factoryresult.png -------------------------------------------------------------------------------- /工厂方法模式/lazyfactory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/工厂方法模式/lazyfactory.png -------------------------------------------------------------------------------- /工厂方法模式/morefactory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/工厂方法模式/morefactory.png -------------------------------------------------------------------------------- /策略模式.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 策略模式 3 | date: 2016-09-01 14:51:44 4 | tags: Java 设计模式 5 | --- 6 | 7 | **摘要:** 8 | 9 | 本篇主要讲Java设计模式之策略模式。 10 | 11 |    12 | 13 | ## 前言 14 | 15 | ​ 正所谓只要功夫深,铁杵磨成针,坚持不懈,水滴石穿。学习也要坚持不懈,慢慢积累,才能达到以量变促成质变。在前进的过程中也要保持好良好的心态,不急不燥,脚踏实地,一步一个脚印。 16 | 17 | ## 策略模式介绍 18 | 19 | ​ 策略模式也叫政策模式,是一种行为型设计模式,是一种比较简单的设计模式。策略模式采用了面向对象的继承和多态机制,下面让我们详细了解一下策略模式吧! 20 | 21 | ## 策略模式定义 22 | 23 | ​ 定义一组算法,将每个算法都封装起来,并且使他们之间可以互换。 24 | 25 | ## 策略模式使用场景 26 | 27 | * 多个类只有在算法或行为上稍有不同的场景。 28 | * 算法需要自由切换的场景。 29 | * 需要屏蔽算法规则的场景 30 | 31 | ## 策略模式通用UML类图 32 | 33 | ![clms1](策略模式/clms1.png) 34 | 35 | **说明:** 36 | 37 | * **Context** 38 | 39 | 他也叫作上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。 40 | 41 | * **Strategy ** 42 | 43 | 策略、算法家族的抽象。通常为接口,定义每个策略或算法必须具有的方法和属性。是策略的抽象。 44 | 45 | * **ConcreteStrategy** 46 | 47 | 具体的策略实现。该类含有具体的算法。 48 | 49 | ## 策略模式使用实例 50 | 51 | ​ 快过中秋了,小杨准备回家团圆,因为家距离自己上班的地方500KM,所以小杨想选择一个比较便宜的回家方式,小杨调查了一下可选择的出行有三种,一做飞机,二自己驾车,三乘火车。这三种乘坐方式的价格不一致,坐飞机大约是没千米50元,自己驾车大约是每千米0.5元,做火车呢,每KM大约是0.1元,现在就让我们用策略模式实现一下小杨要计算的回家费用吧! 52 | 53 | 1. **Strategy **,新建一个CalculateStrategy接口 54 | 55 | ```java 56 | package iuni.life; 57 | 58 | /** 59 | * Created by iuni.life on 16/9/5. 60 | * yangfei's computer 61 | * 计算接口 62 | */ 63 | public interface CalculateStrategy { 64 | float price(int km); 65 | } 66 | ``` 67 | 68 | ​ 69 | 70 | 2. **ConcreteStrategy**,新建CarStrategy、PlaneStrategy、TrainStrategy实现接口CalculateStrategy 71 | 72 | ```java 73 | package iuni.life; 74 | 75 | /** 76 | * Created by iuni.life on 16/9/5. 77 | * yangfei's computer 78 | * 自己开车 按每公里0.5元计算 79 | */ 80 | public class CarStrategy implements CalculateStrategy { 81 | @Override 82 | public float price(int km) { 83 | return (float) 0.5 * km; 84 | } 85 | } 86 | ``` 87 | 88 | ```java 89 | package iuni.life; 90 | /** 91 | * Created by iuni.life on 16/9/5. 92 | * yangfei's computer 93 | * 乘飞机 按每公里50元计算 94 | */ 95 | public class PlaneStrategy implements CalculateStrategy { 96 | @Override 97 | public float price(int km) { 98 | return 50 * km; 99 | } 100 | } 101 | ``` 102 | 103 | ```java 104 | package iuni.life; 105 | 106 | /** 107 | * Created by iuni.life on 16/9/5. 108 | * yangfei's computer 109 | * 乘火车 大约是每公里按0.1元计算 110 | */ 111 | public class TrainStrategy implements CalculateStrategy { 112 | @Override 113 | public float price(int km) { 114 | return (float) (0.1 * km); 115 | } 116 | } 117 | ``` 118 | 119 | 3. **Context** ,新建Client 120 | 121 | ```java 122 | package iuni.life; 123 | /** 124 | * Created by iuni.life on 16/9/5. 125 | * yangfei's computer 126 | */ 127 | public class Client { 128 | CalculateStrategy calculateStrategy; 129 | static int km = 500; 130 | 131 | public static void main(String[] args) { 132 | Client client = new Client(); 133 | //选择乘飞机的方式 134 | client.setCalculateStrategy(new PlaneStrategy()); 135 | System.out.println("乘坐飞机需要的费用为:¥" + client.getPrice(km)); 136 | //选择乘火车的方式 137 | client.setCalculateStrategy(new TrainStrategy()); 138 | System.out.println("乘坐火车需要的费用为:¥" + client.getPrice(km)); 139 | //选择自己驾车的方式 140 | client.setCalculateStrategy(new CarStrategy()); 141 | System.out.println("自己驾车需要的费用为:¥" + client.getPrice(km)); 142 | } 143 | 144 | /** 145 | * 设置出行方式 146 | * 147 | * @param calculateStrategy 148 | */ 149 | public void setCalculateStrategy(CalculateStrategy calculateStrategy) { 150 | this.calculateStrategy = calculateStrategy; 151 | } 152 | 153 | /** 154 | * 获得出行费用 155 | * 156 | * @param km 157 | * @return 158 | */ 159 | public float getPrice(int km) { 160 | return calculateStrategy.price(km); 161 | } 162 | } 163 | ``` 164 | 165 | 166 | 4. 运行结果 167 | 168 | ![clns2](策略模式/clns2.png) 169 | 170 | ## 策略模式优缺点 171 | 172 | ### 优点 173 | 174 | * 算法可以自由切换。 175 | * 结构清晰明了,使用简单直观。 176 | * 操作封装更为彻底,简化了操作。 177 | * 耦合度大大降低,只要实现接口即可,无需做其他修改。 178 | 179 | ### 缺点 180 | 181 | * 随着策略的增加,策略类会越来越多。 182 | * 所有的策略都要暴露出去。 183 | 184 | ## 策略模式的拓展 185 | 186 | * 策略枚举 187 | 188 | 上面的例子改成以下方式: 189 | 190 | 1. 定义一个枚举类,实现方式如下: 191 | 192 | ```java 193 | package iuni.life; 194 | 195 | /** 196 | * Created by iuni.life on 16/9/5. 197 | * yangfei's computer 198 | */ 199 | public enum Calculator { 200 | //自驾 201 | CAR { 202 | public float price(int km) { 203 | return (float) 0.5 * km; 204 | } 205 | }, 206 | PLANE {//飞机 207 | 208 | public float price(int km) { 209 | return (float) 50 * km; 210 | } 211 | }, 212 | TRAIN {//火车 213 | 214 | public float price(int km) { 215 | return (float) 0.1 * km; 216 | } 217 | }; 218 | 219 | Calculator() { 220 | 221 | } 222 | 223 | public abstract float price(int km); 224 | } 225 | ``` 226 | 227 | 2. 修改Client 228 | 229 | ```java 230 | package iuni.life; 231 | 232 | /** 233 | * Created by iuni.life on 16/9/5. 234 | * yangfei's computer 235 | */ 236 | public class Client { 237 | static int km = 500; 238 | 239 | public static void main(String[] args) { 240 | System.out.println("乘坐飞机需要的费用为:¥" + Calculator.PLANE.price(km)); 241 | System.out.println("乘坐火车需要的费用为:¥" + Calculator.TRAIN.price(km)); 242 | System.out.println("自己驾车需要的费用为:¥" + Calculator.CAR.price(km)); 243 | } 244 | } 245 | ``` 246 | ​ 247 | 248 | 3. 运行结果 249 | 250 | ![clns2](策略模式/clns2.png)​ 251 | 252 | 可以看出: 253 | 254 | * 该例子的Calculator是一个枚举。 255 | * Calculator是一个浓缩了策略模式的枚举。 256 | 257 | **注意:** 258 | 259 | 策略枚举是一个非常优秀和方便的模式,但是其受到枚举类型的限制,每个枚举项都是public、final、static的,拓展性受到了一定的约束,因此在系统开发中,枚举策略一般担当不经常发生变的角色。 260 | 261 | ## 后记 262 | 263 | ​ 文章不足之处,望大家多多指点,共同学习,共同进步。 264 | 265 | ## 参考资料 266 | 267 | * ***<<设计模式之蝉>>*** 秦小波 著 268 | 269 | ## 个人博客 270 | 271 | 如想获得更好阅读体验,请访问个人博客网站:[iplugin.cn](http://www.iplugin.cn) -------------------------------------------------------------------------------- /策略模式/clms1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/策略模式/clms1.png -------------------------------------------------------------------------------- /策略模式/clns2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/策略模式/clns2.png -------------------------------------------------------------------------------- /观察者模式.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 观察者模式 3 | date: 2016-08-29 16:19:08 4 | tags: Java 设计模式 5 | --- 6 | 7 | **摘要:** 8 | 9 | 本篇主要讲Java设计模式之观察者模式。 10 | 11 |    12 | 13 | [TOC] 14 | 15 | ## 前言 16 | 17 | ​ 当心浮气躁时,告诫自己要静下心来,一步一步来,不要急不要燥。 18 | 19 | ## 观察者模式介绍 20 | 21 | ​ 观察者模式也叫做**发布订阅模式**,是一种行为型设计模式。观察者模式最常用的地方是GUI系统、订阅---------发布系统。尤其是GUI系统,使用观察者模式可以使UI层与业务逻辑解耦。 22 | 23 | ## 观察者模式定义 24 | 25 | ​ 定义对象间一种一对多的依赖关系,使得每当一个对象改变状态。则所有依赖于它的对象都会得到通知并被自动更新。 26 | 27 | ## 观察者模式使用场景 28 | 29 | * **关联行为场景** 30 | 31 | 需要注意的是,关联行为是可以拆分的,并不是“组合”关系。 32 | 33 | * **事件多级触发场景。** 34 | 35 | * **跨系统的消息交换场景,如消息队列、事件总线的处理机制。** 36 | 37 | ​ 38 | 39 | ## 观察者模式通用UML类图 40 | 41 | ![gczms1](观察者模式/gczms1.png) 42 | 43 | **说明:** 44 | 45 | * **Subject** 46 | 47 | 被观察者,一般是抽象类或者是实现类,主要功能是管理观察者(动态的增加、取消观察者)并且通知观察者。 48 | 49 | * **ConCreteSubject** 50 | 51 | 具体的被观察者,定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。 52 | 53 | * **Observer** 54 | 55 | 观察者,一般是抽象类或者是实现类,对接收到的信息进行处理。 56 | 57 | * **ConcreteObserver** 58 | 59 | 具体的观察者,通过接收的信息,实现各个观察者自己的业务逻辑。 60 | 61 | ## 观察者模式使用实例 62 | 63 | ​ 现在有这样一个功能需求:在Android的一个界面上,有三个控件,分别为Edittext,TextView,ImageView,当EditText按下键盘的回车键(或者确认键)时,TextView显示EditText输入的文字,ImageView根据输入的文字显示相应的图片。如果运用观察者模式去做的话,EditText是被观察者,TextView和ImageView是观察者,当EditText输入的时候按下回车键,ImageView和TextView通过接受的信息根据自己的业务逻辑进行相应的处理。下面就让我们来实现一下。 64 | 65 | 1. 重写EditText,使其成为被观察者 66 | 67 | ```java 68 | package com.yf.designpatternandroid; 69 | 70 | import android.content.Context; 71 | import android.util.AttributeSet; 72 | import android.view.KeyEvent; 73 | import android.view.inputmethod.EditorInfo; 74 | import android.widget.EditText; 75 | import android.widget.TextView; 76 | 77 | import java.util.Observable; 78 | import java.util.Observer; 79 | /** 80 | * Created by iuni.life on 16/9/7. 81 | * yangfei's computer. 82 | */ 83 | public class MyEditText extends EditText { 84 | //使用内部类的方式实现被观察者 85 | private Content content; 86 | 87 | public MyEditText(Context context) { 88 | super(context); 89 | } 90 | 91 | public MyEditText(final Context context, AttributeSet attrs) { 92 | super(context, attrs); 93 | content = new Content(); 94 | //对输入的内容进行监听 95 | setOnEditorActionListener(new OnEditorActionListener() { 96 | @Override 97 | public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { 98 | if (i == EditorInfo.IME_ACTION_SEARCH || i == EditorInfo.IME_ACTION_DONE || 99 | keyEvent.getAction() == KeyEvent.ACTION_DOWN && 100 | keyEvent.getAction() == KeyEvent.KEYCODE_ENTER) { 101 | //触发各个Observer 102 | content.setEditTextContent(getText().toString()); 103 | 104 | } 105 | 106 | return false; 107 | } 108 | }); 109 | } 110 | 111 | public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) { 112 | super(context, attrs, defStyleAttr); 113 | } 114 | 115 | /** 116 | * 添加观察者 117 | * 118 | * @param observer 119 | */ 120 | public void addObserver(Observer observer) { 121 | content.addObserver(observer); 122 | } 123 | //被观察者需要继承Observable 124 | private class Content extends Observable { 125 | private String editTextContent; 126 | public void setEditTextContent(String editTextContent) { 127 | this.editTextContent = editTextContent; 128 | //标识状态或者内容发生改变 129 | setChanged(); 130 | //通知所有的观察者 131 | notifyObservers(editTextContent); 132 | } 133 | } 134 | 135 | } 136 | ``` 137 | 138 | 2. 重写TextView,使其成为观察者 139 | 140 | ```java 141 | 142 | package com.yf.designpatternandroid; 143 | 144 | import android.content.Context; 145 | import android.util.AttributeSet; 146 | import android.util.Log; 147 | import android.widget.TextView; 148 | 149 | import java.util.Observable; 150 | import java.util.Observer; 151 | 152 | /** 153 | * Created by iuni.life on 16/9/7. 154 | * yangfei's computer. 155 | * 观察者需要实现接口Observer,并在update方法中实现业务逻辑 156 | */ 157 | public class MyTextView extends TextView implements Observer { 158 | public MyTextView(Context context) { 159 | super(context); 160 | } 161 | 162 | public MyTextView(Context context, AttributeSet attrs) { 163 | super(context, attrs); 164 | } 165 | 166 | public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) { 167 | super(context, attrs, defStyleAttr); 168 | } 169 | 170 | @Override 171 | public void update(Observable observable, Object o) { 172 | Log.d("MyTextView", "Observer:MyTextView收到通知:" + o); 173 | setText(o.toString()); 174 | } 175 | } 176 | ``` 177 | 178 | 179 | 3. 重写ImageView,使其成为观察者 180 | 181 | ```java 182 | package com.yf.designpatternandroid; 183 | 184 | import android.content.Context; 185 | import android.media.Image; 186 | import android.util.AttributeSet; 187 | import android.util.Log; 188 | import android.widget.ImageView; 189 | 190 | import java.util.Observable; 191 | import java.util.Observer; 192 | 193 | /** 194 | * Created by iuni.life on 16/9/7. 195 | * yangfei's computer. 196 | * 观察者需要实现接口Observer,并在update方法中实现业务逻辑 197 | */ 198 | public class MyImageView extends ImageView implements Observer { 199 | public MyImageView(Context context) { 200 | super(context); 201 | } 202 | 203 | public MyImageView(Context context, AttributeSet attrs) { 204 | super(context, attrs); 205 | } 206 | 207 | public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) { 208 | super(context, attrs, defStyleAttr); 209 | } 210 | 211 | @Override 212 | public void update(Observable observable, Object o) { 213 | Log.d("MyImageView", "Observer:MyImageView收到通知:" + o); 214 | String content = o.toString(); 215 | if (o.equals("iuni")) { 216 | setImageResource(R.mipmap.ic_launcher); 217 | } else { 218 | setImageResource(R.mipmap.test); 219 | } 220 | } 221 | } 222 | 223 | ``` 224 | 225 | ​ 226 | 227 | 4. 在布局文件中引用重写的三个控件 228 | 229 | ```xml 230 | 231 | 241 | 242 | 247 | 248 | 252 | 253 | 258 | 259 | 260 | ``` 261 | 262 | ​ 263 | 264 | 5. 测试代码 265 | 266 | ```java 267 | package com.yf.designpatternandroid; 268 | 269 | import android.support.v7.app.AppCompatActivity; 270 | import android.os.Bundle; 271 | import android.view.View; 272 | import android.widget.AutoCompleteTextView; 273 | import android.widget.ImageView; 274 | import android.widget.Toast; 275 | 276 | public class MainActivity extends AppCompatActivity { 277 | 278 | private MyEditText myEditText; 279 | private MyTextView myTextView; 280 | private MyImageView myImageView; 281 | 282 | @Override 283 | protected void onCreate(Bundle savedInstanceState) { 284 | super.onCreate(savedInstanceState); 285 | setContentView(R.layout.activity_main); 286 | myEditText = (MyEditText) findViewById(R.id.id_et); 287 | myImageView = (MyImageView) findViewById(R.id.id_iv); 288 | myTextView = (MyTextView) findViewById(R.id.id_tv); 289 | 290 | myEditText.addObserver(myImageView); 291 | myEditText.addObserver(myTextView); 292 | } 293 | } 294 | 295 | ``` 296 | 297 | 6. 效果展示 298 | 299 | ![gczms](观察者模式/gczms.gif) 300 | 301 | 302 | 303 | ## 观察者模式优缺点 304 | 305 | ### 优点 306 | 307 | * **观察者和被观察者之间是抽象耦合。** 308 | * **可以建立一套触发机制。** 309 | * **增强系统的灵活性,可拓展性。** 310 | 311 | ### 缺点 312 | 313 | * **一个被观察者,多个观察者,开发效率和运行效率需要考虑。** 314 | * **一个被观察者,多个观察者,调试比较复杂。** 315 | * **Java中的消息通知默认是顺序执行,一个观察者卡壳,会影响整体的执行效率。(这种情况一般会采取异步的方式处理)** 316 | 317 | ## 后记 318 | 319 | ​ 文章不足之处,望大家多多指点,共同学习,共同进步。 320 | 321 | ## 参考资料 322 | 323 | - ***<<设计模式之蝉>>*** 秦小波 著 324 | 325 | ## 个人博客 326 | 327 | 若想获得更好阅读体验,请访问个人博客网站:[iplugin.cn](http://www.iplugin.cn) -------------------------------------------------------------------------------- /观察者模式/gczms.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/观察者模式/gczms.gif -------------------------------------------------------------------------------- /观察者模式/gczms1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OriginalLove/DesignPattern/b38c529e7455bba45453ef35448d9aaee2ab5238/观察者模式/gczms1.png --------------------------------------------------------------------------------