├── .gitignore ├── README.md ├── coloruml.puml └── samples └── bookstore.puml /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Example user template template 3 | ### Example user template 4 | 5 | # IntelliJ project files 6 | .idea 7 | *.iml 8 | out 9 | gen 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于PlantUML 的4色 领域模型建模 2 | 3 | 4 | ## coloruml 5 | 6 | 这个项目是在[PlantUML](http://plantuml.com)的基础上的定制,支持快速绘制领域模型图. 7 | 8 | 结合[C4 Model](http://c4model.com),基本可以实现从业务到技术架构的完整设计,C4 model参考另外一个项目: [C4-PlantUML](https://www.github.com/gnodux/C4-PlantUML) 9 | 10 | PlantUML是一个开源项目,支持"写文字"的方式快速绘制多种图形UML及非UML图形。 11 | 具体语法可以参考:[PlantUML](http://plantuml.com) 12 | 13 | ## 关于4色领域模型建模 14 | 15 | 4色领域模型的概念来自 [Java Modeling In Color With UML](https://book.douban.com/subject/1440291/) 16 | 17 | 18 | _Peter Coad提出的几类基本元模型对于实际进行建模工作有着非比寻常的指导价值——当大多数人在分析业务领域模型时,Peter Coad在分析业务领域的元模型,其“鬼才”由此可见一斑。至于“带颜色的UML”,无非是对元模型的一种直观描述而已。对于面向对象(而非面向用例)的企业应用业务建模,这本“小书”便是首屈一指的最佳实践指南._ 19 | 20 | 在这本小书里,archetype 被分为: 21 | 22 | - Moment-Interval 23 | - Role 24 | - Description 25 | - "Party,Place, or Thing" 26 | 27 | 4种类型。通过对对象的分类,快速抓住关键业务控制点。 28 | 29 | 领域模型建模的相关概念及链接: 30 | 31 | * [https://www.infoq.cn/article/xh-four-color-modeling](https://www.infoq.cn/article/xh-four-color-modeling) 32 | * [从“四色建模法”到“限界纸笔建模法”](https://insights.thoughtworks.cn/paper-pen-modeling/) 33 | * [谈谈领域建模](http://fanyilun.me/2018/04/08/%E8%B0%88%E8%B0%88%E9%A2%86%E5%9F%9F%E5%BB%BA%E6%A8%A1/) 34 | 35 | ## Getting start 36 | 37 | 在绘制领域模型图的时候,直接引用: 38 | 39 | ``` 40 | !include https://raw.githubusercontent.com/gnodux/coloruml/master/coloruml.puml 41 | ``` 42 | 43 | 例如一个简单的示例: 44 | 45 | [Book Store](samples/bookstore.puml) 46 | 47 | ```csharp 48 | @startuml Book Store sample 49 | 50 | '!include https://raw.githubusercontent.com/gnodux/coloruml/master/coloruml.puml 51 | 52 | !include ../coloruml.puml 53 | 'left_to_right 54 | 55 | moment(订单,Order){ 56 | int OrderId 57 | int Status 58 | 59 | } 60 | moment(Bill) 61 | moment(Delivery) 62 | thing(Book) 63 | desc(Comments) 64 | role(Customer) 65 | thing(Employee){ 66 | String Name 67 | Date Birthday 68 | int Status() 69 | } 70 | thing(Author) 71 | role(Courier) 72 | role(Accounting) 73 | 74 | Courier from(Employee) 75 | Accounting from(Employee) 76 | 77 | Book contains(Comments) 78 | Book has_d(Author) 79 | Order contains(Bill) 80 | Order contains(Delivery) 81 | Order has(Book) 82 | Bill has(Accounting) 83 | Delivery has(Courier) 84 | Customer has(Order) 85 | Customer has(Comments) 86 | 87 | Bill layout_u(Delivery) 88 | 89 | @enduml 90 | ``` 91 | ![Book Store](http://www.plantuml.com/plantuml/svg/NL4xJiGm4ErzYcorYOIIdcu_5Dj0iGU8J3ARMDYUrNWCH8WZK7813i2ja3W6Jh9EbhYmz6QUtvjvNYbRQLz3qZAVtMrHa7p96yMjV_GEg4BBO3clq1IDnTg_5XLg96zqOQHZe0ddvt09iLv5nJnVzDOQJbmobgIQbeKmQ89s-llzzVFnUVD0DL3s9f9mbELam8TwmaUMx9qGx_7TLccTHR07hPw1kanmgsoJRX6VCb63gz8TcfxYCa6e8Trvn-4DHUQTEMli02xMHwPGJUwbWG7l9KEoLSHjBRl5C6aMfXbLDfvRf6Y1dXH4jAagz9O3AnFYqafEX6Qs5ZDdsH7z9ad_3r9PTxNCK6-bA-l9V8Xiveu1BOfpK6CZA5p2wka3l1uuqeV6j5VCSAYE7_U_DeyvochPeUVINzd_0G00 "Book store") 92 | 93 | ## IntelliJ IDEA 集成 94 | 95 | ### IntelliJ IDEA 96 | * 在JetBrains 下载IntelliJ IDEA [Download IntelliJ IDEA](https://www.jetbrains.com/idea/download/) 97 | * 安装Plugins: PlantUML Integration / PlantUML Syntax Checker 98 | 99 | ### Visual studio code 100 | 101 | 安装 [PlantUML extension](https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml) 102 | 103 | ## 开始绘制你的领域模型 104 | 105 | ### 引入定义模型定义 106 | 107 | 使用plantuml `include`预处理关键字引入模型 108 | 109 | ```csharp 110 | !include https://raw.githubusercontent.com/gnodux/coloruml/master/coloruml.puml 111 | ``` 112 | ### 领域对象的绘制 113 | 114 | 领域对象的绘制比较简单,使用封装的函数即可,以4色领域模型为例: 115 | 116 | - moment(label,alias)|{}: moment-of-interval对象 117 | - thing/party/place(label,alias)|{} : thing/party/place 118 | - desc(label,alias)|{}: description描述对象 119 | - role(label,alias)|{}: role 角色 120 | 121 | ```csharp 122 | @startuml example 123 | !include https://raw.githubusercontent.com/gnodux/coloruml/master/coloruml.puml 124 | moment(订单,Order) 125 | thing(书,Book) 126 | @enduml 127 | ``` 128 | 129 | 130 | ![example](http://www.plantuml.com/plantuml/svg/FSgn3S8m443HtbE4Bf6YkAUAM80PZ7rA8dntqVbEP0bA5g2Wf6SVa1W3LpHV-j8RYmPHmzp05d3Du7OBnMm9cbbrBNll9Lo6QT7PJbP08fC2wH0P_KISRFEHCujXzXYAWln_M6iSCbRVVf_tp_NM7oM1T4xdXQRs_Nhq1-PpvqQWLF4F) 131 | 132 | 接下来我们为领域对象添加一些属性和方法: 133 | 134 | ```csharp 135 | @startuml example 136 | !include https://raw.githubusercontent.com/gnodux/coloruml/master/coloruml.puml 137 | moment(订单,Order) 138 | thing(书,Book){ 139 | string Title 140 | int AuthorId 141 | string ISBN 142 | } 143 | @enduml 144 | ``` 145 | 146 | ![Field example](http://www.plantuml.com/plantuml/svg/JOqnQWCn44LxdKBfTc5PzQassssJ5Ca556bOYKYQPJGY2yP7SEaBk73ftlUnmSUmS64ynS1_FFuVCclY4eE4LSSbW7ZpoOHYGJhc9RyhHVg_dpsxybioaC74aBWt6DMSq9PL6Gn8jK95dHdecVkbFX4nLh-vdGxNtRxx8WlK2dO-pStbVEn6nBzs8sIzp5If_F4Su05yOlbHs25DzjMOliTFiHK395iNxW00) 147 | 148 | ### 领域模型的关系 149 | 150 | 主要包含以下关系: 151 | 152 | - has: 可能包含 153 | - contains: 父子关系 154 | - rel: 引用 155 | 156 | 描述关系的时候使用has[_r/l/u/d],其中r(ight)/l(eft)/u(p)/d(own)可以进行简单布局。 157 | contains和rel类似。 例如 158 | 159 | ```csharp 160 | @startuml example 161 | !include https://raw.githubusercontent.com/gnodux/coloruml/master/coloruml.puml 162 | moment(订单,Order) 163 | thing(书,Book){ 164 | string Title 165 | int AuthorId 166 | string ISBN 167 | } 168 | 169 | Order has(Book) 170 | 171 | @enduml 172 | ``` 173 | 174 | ![relation example](http://www.plantuml.com/plantuml/svg/JOmnIWOn48NxEKNizeUVJM-rRhUD5dg1c0oRO3ApJ2Qu81x1qWjOMDfx7mMFOTX2VCM3z_7ufgfEj9LiS7TbomWNYNnk0KrKtUgbjU8UnpLfRFUjedWcHTBHSx4hSMYxzPnPki8MLnNbRuzRBoXSa7Ju-NZxVdaztqX0EO76HElmzVb-dfaVJazWUgfAf-OkQSO3959prJIoBE7_OxcTh-4Pu92PwEfmM00cfD1A_WK0) 175 | 176 | 更复杂的管理参考 [bookstore.puml](samples/bookstore.puml) 177 | 178 | ### 其他 179 | 180 | #### 备注:可以给领域模型添加备注或说明 181 | 182 | 183 | ```csharp 184 | @startuml example 185 | !include https://raw.githubusercontent.com/gnodux/coloruml/master/coloruml.puml 186 | moment(订单,Order) 187 | note right of Order: 订单对象是有状态的 188 | note left of Order 189 | ===订单对象流转说明 190 | * 订单状态包含... 191 | * 订单审批流程... 192 | end note 193 | @enduml 194 | ``` 195 | 196 | ![notes examples](http://www.plantuml.com/plantuml/svg/SoWkIImgAStDKKYjICmjo4dbKipCIyufJKbLo2WfAIYsqjSlIYpNIyyioIXDAYrEBKhEpoj9pIlHIyxFrK_FoqyfhT1Fpi_9Bm8QeP-RM5oIMWJdwnK02QxS_5oWUeqNwnOzxPsgur-KabgaoPMNNvAgK9IPdb6Ya9-c01QqKe0eURf-vukD2v_DMFziJkVphctF6XgVpsg1QCX9JKEevxArjKNHiRNnnTurBzPlUJQZZqiBQXZ4WASzhKydhDRJquEBFrsty5ddJg2MvokwGUAfUIaA82ku780ieAi1) 197 | 198 | 199 | ### 预制函数 200 | 201 | - hand_write():手写 202 | - legend(): 图例 203 | - hard_line(): 直线连接 204 | - left_to_right() :从左到右布局 205 | - title : 标题 206 | 207 | ```csharp 208 | @startuml Book Store sample 209 | !include https://raw.githubusercontent.com/gnodux/coloruml/master/coloruml.puml 210 | 211 | title 书店简单领域模型图 212 | 213 | left_to_right() 214 | hand_write() 215 | hard_line() 216 | legend() 217 | 218 | moment(订单,Order){ 219 | int OrderId 220 | int Status 221 | 222 | } 223 | moment(Bill) 224 | moment(Delivery) 225 | thing(Book) 226 | desc(Comments) 227 | role(Customer) 228 | thing(Employee){ 229 | String Name 230 | Date Birthday 231 | int Status() 232 | } 233 | thing(Author) 234 | role(Courier) 235 | role(Accounting) 236 | 237 | Courier from(Employee) 238 | Accounting from(Employee) 239 | 240 | Book contains(Comments) 241 | Book has_d(Author) 242 | Order contains(Bill) 243 | Order contains(Delivery) 244 | Order has(Book) 245 | Bill has(Accounting) 246 | Delivery has(Courier) 247 | Customer has(Order) 248 | Customer has(Comments) 249 | 250 | Bill layout_u(Delivery) 251 | @enduml 252 | ``` 253 | 254 | ![book store hand written](http://www.plantuml.com/plantuml/svg/NL4zZzGm4EtzAqoNI6ZJKztj7GKD5Fo0bOc7nCBshCPZZWYTH4M3A1454YUkG5JRGy6l8Npy2-nalO6ayfjvyzxCorbWHHoT5NUCRstK87lcVRZNDAIkDftXFZw90QX5p-1vqw9hEeywlcXQj4Xfj74gCD09R_PPZmrRa3--VXw_lVzrU3M-VVVdzlLuS_FpowVnuvlnmtSXUkNrxeeCGrKdG7fdZSzl2nrudHx2eKkkrU_3RHAu-uWqKFrIoFGPptB23_G9FsR5CGXnNUQsnjgwW4kmvZdGK0lkZU-gBUApMcW8RNM1BbD2BGWjL1SnS9gXmhplzXO7WDawsL2goeVAmOGl5OFS6k9Ugs6rJ3hY-gXo7hb7AXOOoK11vssBqNDYfPkFBVcKq2tMOk6iEo9V8lCVKiQ7vPYvtgkmqoVpARA5EmUqAfQWIYCf7CFAz0p_MxZGSsEvgsGuLRFEkhQiESjQDM3aNVp7_WoyZix-1G00http://www.plantuml.com/plantuml/svg/NL4zZzGm4EtzAqoNI6ZJKztj7GKD5FS38XFFnHQsPpKUSqJe92eQH8aea3Yn1QBQ7Wf-3U7ZNn1damqabT-Rv_SyBsUH5N7oJjopeN59WpJCk_YWgaZTR5hB9ZrD4QZ1m11uqw2lse0wlQWQT4Z3rSgho40dlDbbFxRiGFxu-hd_zlxNuLN_zjsV_Ul-xkxdbq_znpVzX-_2mJNNZ3NPrd1H2gE2hc_8Ceo0TErio6S7BGGz78H73u6BtuVzu7V_2McWygMGmsS3on4_qYTynOfJ5E9slhUrpfKpk0HddmDrfM1ZGrji4P-LGaDiYWlqMH9BGUYWk4YHqGFDoeT-vx03cAAlc0PMFbOUHdof6EJM4XkjkjLZXYLk9vVpn0PfZi145cPqtZIO0W-gKeXf9Ay9_H8j5irw8l8cClymPKDSbZdoHiLQdyB7oXPjBcXDBaKT1zbXAYlBC_plmRCy3vQzvWv7DlkikUMPHrkdEanSft_Ypo3evDrV) -------------------------------------------------------------------------------- /coloruml.puml: -------------------------------------------------------------------------------- 1 | @startuml "4color domain model" 2 | 3 | 4 | !define THING_COLOR #CCFFAF 5 | !define ROLE_COLOR #FEFFAF 6 | !define MOMENT_COLOR #FFB7AF 7 | !define DESC_COLOR #AFD1FF 8 | !define BORDER_COLOR #666666 9 | 10 | skinparam { 11 | defaultFontName "Microsoft YaHei" 12 | 'LineType ortho 13 | Shadowing false 14 | } 15 | 16 | !procedure hard_line() 17 | skinparam LineType ortho 18 | !endprocedure 19 | 20 | !procedure left_to_right() 21 | left to right direction 22 | !endprocedure 23 | !procedure top_to_bottom() 24 | top to bottom direction 25 | !endprocedure 26 | 27 | !procedure hand_write() 28 | skinparam handwritten true 29 | skinparam defaultFontName "Comic Sans MS" 30 | center footer Warning:Discussion only. 31 | !endprocedure 32 | 33 | 34 | !procedure legend() 35 | hide stereotype 36 | legend right 37 | |= Color |= Type | 38 | | | Thing/Place/Party | 39 | | | Moment of interval | 40 | | | Role | 41 | | | Description | 42 | endlegend 43 | !endprocedure 44 | 45 | skinparam package{ 46 | BorderColor #666666 47 | } 48 | skinparam rectangle{ 49 | BorderStyle dashed 50 | } 51 | skinparam note{ 52 | BackgroundColor White 53 | BorderColor #666666 54 | FontSize 9 55 | FontStyle italic 56 | } 57 | skinparam class{ 58 | BorderColor BORDER_COLOR 59 | BorderThickness 0.8 60 | FontSize 12 61 | AttributeFontSize 9 62 | BackgroundColor<> THING_COLOR 63 | BackgroundColor<> THING_COLOR 64 | BackgroundColor<> THING_COLOR 65 | BackgroundColor<> MOMENT_COLOR 66 | BackgroundColor<> DESC_COLOR 67 | BackgroundColor<> ROLE_COLOR 68 | Shadowing false 69 | } 70 | 71 | 72 | skinparam object{ 73 | BorderColor BORDER_COLOR 74 | BorderThickness 0.8 75 | FontSize 12 76 | AttributeFontSize 9 77 | BackgroundColor<> THING_COLOR 78 | BackgroundColor<> THING_COLOR 79 | BackgroundColor<> THING_COLOR 80 | BackgroundColor<> MOMENT_COLOR 81 | BackgroundColor<> DESC_COLOR 82 | BackgroundColor<> ROLE_COLOR 83 | Shadowing false 84 | } 85 | skinparam Arrow{ 86 | Color blue 87 | } 88 | 89 | 90 | 91 | skinparam wrapWidth 200 92 | 93 | !global $default_type = "class" 94 | 95 | !define model(category,label,alias,spot) $default_type "label" as alias <><<(spot,#CABAF5)>> 96 | !define model(category,label,spot) $default_type label <><<(spot,#CABAF5)>> 97 | 98 | !define thing(label,alias) model("thing",label,alias,T) 99 | !define thing(label) model("thing",label,T) 100 | !define place(label,alias) model("place",label,alias,P) 101 | !define place(label) model("place",label,P) 102 | !define party(label,alias) model("party",label,alias,P) 103 | !define party(label) model("party",label,P) 104 | !define role(label,alias) model("role",label,alias,R) 105 | !define role(label) model("role",label,R) 106 | !define moment(label,alias) model("moment-interval",label,alias,M) 107 | !define moment(label) model("moment-interval",label,M) 108 | !define desc(label,alias) model("description",label,alias,D) 109 | !define desc(label) model("description",label,D) 110 | 111 | 112 | ' connect object 113 | !define rel(obj1,obj2) obj1 . obj2 114 | !define rel(o) . o 115 | 116 | 117 | ' has defined 118 | !define has(obj) o-- obj 119 | !define has_r(obj) has(obj) 120 | !define has_l(obj) o-left- obj 121 | !define has_u(obj) o-up- obj 122 | !define has_d(obj) o-down- obj 123 | !define has(obj,label1,label2) "label1" o-right- "label2" obj 124 | 125 | !define onetomany(obj1,obj2) obj1 has(obj2) 126 | !define onetoone(obj1,obj2) obj1 -- obj2 127 | 128 | !define contains(obj) --* obj 129 | !define contains_r(obj) contains(obj) 130 | !define contains_l(obj) -left-* obj 131 | !define contains_u(obj) -up-* obj 132 | !define contains_d(obj) -down-* obj 133 | 134 | 135 | !define from(obj) --|> obj 136 | 137 | 'layouts 138 | 139 | !define link(o1,o2) o1 -[hidden]- o2 140 | !define layout_r(obj1) -[hidden]right- obj1 141 | !define layout_l(o1) -[hidden]left- o1 142 | !define layout_u(o1) -[hidden]up- o1 143 | !define layout_d(o1) -[hidden]down- o1 144 | 145 | !define domain(label,alias) rectangle "==label" as alias 146 | !define domain(label) rectangle "==label" 147 | 148 | 149 | 150 | 151 | @enduml -------------------------------------------------------------------------------- /samples/bookstore.puml: -------------------------------------------------------------------------------- 1 | @startuml Book Store sample 2 | 3 | '!include https://raw.githubusercontent.com/gnodux/coloruml/master/coloruml.puml 4 | 5 | !include ../coloruml.puml 6 | 'left_to_right() 7 | 8 | moment(订单,Order){ 9 | int OrderId 10 | int Status 11 | 12 | } 13 | moment(Bill) 14 | moment(Delivery) 15 | thing(Book) 16 | desc(Comments) 17 | role(Customer) 18 | thing(Employee){ 19 | String Name 20 | Date Birthday 21 | int Status() 22 | } 23 | thing(Author) 24 | role(Courier) 25 | role(Accounting) 26 | 27 | Courier from(Employee) 28 | Accounting from(Employee) 29 | 30 | Book contains(Comments) 31 | Book has_d(Author) 32 | Order contains(Bill) 33 | Order contains(Delivery) 34 | Order has(Book) 35 | Bill has(Accounting) 36 | Delivery has(Courier) 37 | Customer has(Order) 38 | Customer has(Comments) 39 | 40 | Bill layout_u(Delivery) 41 | 42 | @enduml --------------------------------------------------------------------------------