Java 编写 CMP 关于 “软件过程管理里的项目预期”的算法实现-【经过设计模式改造和算法优化】
日期:2020.03.06
博客期:162
星期五
【博客前言】
我们在数据结构里面已经学会了 CMP 的基本用法,软件过程管理这门课又讲到了 CMP ,两个知识点有什么区别吗?我们首先要知道 “算法与数据结构”这门课呢,是一个专业基础课,为的是给后面的像“软件过程管理”这样的课打基础,那么,我们有没有什么新内容呢?我觉得首先更新了几个概念,最早完成时间、最晚完成时间、最早开始时间、最晚开始时间等等,要说新接触的怕不是总缓冲期、干预缓冲期和空闲缓冲区了! 公式:总缓冲期 = 干预缓冲期 + 空闲缓冲期!
【实装代码】
我在这里展示一下代码吧!
com.imp.cmp 包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp; 2 3 import java.util.Scanner; 4 5 import com.imp.cmp.node.LinkedNode; 6 7 //--------------------------- 8 //---【主进程】 9 //-- 10 //- 11 // 12 public class Client { 13 //基本构件 14 protected Scanner sc; 15 protected Controler con; 16 protected CMPViewer cmpv; 17 //临时数据 18 private String sc_str; 19 //结束本程序 20 private void stop() { 21 this.sc.close(); 22 } 23 //开始本程序 24 public void start() { 25 this.process_print_nodes(); 26 this.process_print_line(); 27 this.process_display(); 28 this.stop(); 29 } 30 //---[过程] 31 //输入结点 32 private void process_print_nodes() { 33 System.out.println(" #:Please print all nodes but 'start' and 'end' ..."); 34 System.out.println(" Print Example: 8, A.FindAnswer"); 35 System.out.println(" End With: #END#"); 36 this.sc_str = sc.nextLine(); 37 while(this.sc_str.compareTo("#END#")!=0) 38 { 39 String [] tmps = this.sc_str.split(","); 40 double ans = Double.parseDouble(tmps[0]); 41 String tmp = tmps[1]; 42 this.con.addNode(new LinkedNode(tmp,ans)); 43 this.sc_str = sc.nextLine(); 44 } 45 this.con.retireEndNode(); 46 System.out.println(); 47 System.out.println(" @:OK"); 48 System.out.println(); 49 50 //con.displayOnlyNode(); 51 this.cmpv.displayOnlyNode(this.con.ng); 52 } 53 //输入连线 54 private void process_print_line() { 55 System.out.println(); 56 System.out.println(" #:Please print all lines between the nodes ..."); 57 System.out.println(" Print Example: 0,1"); 58 System.out.println(" End With: #END#"); 59 this.sc_str = this.sc.nextLine(); 60 while(this.sc_str.compareTo("#END#")!=0) 61 { 62 String [] tmps = this.sc_str.split(","); 63 int seat1 = Integer.parseInt(tmps[0]); 64 int seat2 = Integer.parseInt(tmps[1]); 65 this.con.addLine(seat1, seat2); 66 this.sc_str = sc.nextLine(); 67 } 68 System.out.println(); 69 System.out.println(" @:OK"); 70 this.con.build(); 71 System.out.println(); 72 System.out.println(); 73 } 74 //剩余展示 75 private void process_display() { 76 //con.displayAllNodeInfo(); 77 cmpv.displayAllNodeInfo(con.ng, con.onig, con.llg); 78 79 System.out.println(); 80 System.out.println(); 81 82 cmpv.displayTerm(con); 83 cmpv.displayKeyRoad(con.ng, con.onig, con.llg); 84 //con.displayTerm(); 85 //con.displayKeyRoad(); 86 87 System.out.println(); 88 System.out.println(); 89 } 90 //构造方法 91 public Client() { 92 this.sc = new Scanner(System.in); 93 this.con = new Controler(); 94 this.cmpv = new CMPViewer(); 95 } 96 public static void main(String[] args) { 97 Client cli = new Client(); 98 cli.start(); 99 } 100 101 } 102 //--------------------- 103 //---[测试用例] 104 /* 105 3,A 106 5,B 107 2,C 108 #END# 109 110 0,1 111 0,2 112 1,3 113 2,3 114 3,4 115 #END# 116 */
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp; 2 3 import com.imp.cmp.line.LinkLine; 4 import com.imp.cmp.line.LinkLineGroup; 5 import com.imp.cmp.node.Node; 6 import com.imp.cmp.node.NodeGroup; 7 import com.imp.cmp.otherinfo.OtherNodeInfo; 8 import com.imp.cmp.otherinfo.OtherNodeInfoGroup; 9 10 //--------------------------- 11 //---【视图模块】 12 //-- 13 //- 14 // 15 public class CMPViewer { 16 //只展示结点基本信息 17 public void displayOnlyNode(NodeGroup ng) { 18 int leng = ng.size(); 19 System.out.println("chara"+"\t"+"term"); 20 for(int i=0;i<leng;++i) 21 { 22 Node node = ng.get(i); 23 if(node.getChara().compareTo("Start")==0||node.getChara().compareTo("End")==0) 24 { 25 System.out.println(node.getChara()); 26 continue; 27 } 28 System.out.println(node.getChara()+"\t"+node.getTime()); 29 } 30 } 31 //只展示结点连接信息 32 public void displayLine(NodeGroup ng,LinkLineGroup llg) { 33 int leng = llg.size(); 34 System.out.println("Start"+"\t"+"End"); 35 for(int i=0;i<leng;++i) 36 { 37 LinkLine ll = llg.get(i); 38 System.out.println(ng.get(ll.start)+"\t"+ng.get(ll.end)); 39 } 40 } 41 //展示结点所有信息 42 public void displayAllNodeInfo(NodeGroup ng,OtherNodeInfoGroup onig,LinkLineGroup llg) { 43 int leng = ng.size(); 44 System.out.println("chara"+"\t"+"term"+"\t"+"st_ear"+"\t"+"end_ear"+"\t"+"st_la"+"\t"+"end_la"+"\t"+"int_bp"+"\t"+"ldl_bp"+"\t"+"bp"); 45 for(int i=0;i<leng;++i) 46 { 47 Node node = ng.get(i); 48 if(node.getChara().compareTo("Start")==0||node.getChara().compareTo("End")==0) 49 { 50 System.out.println(node.getChara()); 51 continue; 52 } 53 OtherNodeInfo oni = onig.get(i); 54 55 System.out.println(node.getChara()+"\t"+node.getTime()+"\t"+oni.start_early+"\t"+oni.end_early+"\t"+oni.start_late+"\t"+oni.end_late+"\t"+oni.inter_buffer_period+"\t"+oni.ldle_buffer_period+"\t"+oni.buffer_period); 56 } 57 } 58 //展示总周期 59 public void displayTerm(Controler con) { 60 System.out.println(" @: Term of the project: "+con.getSumPeriod()); 61 } 62 //展示关键路径 63 public void displayKeyRoad(NodeGroup ng,OtherNodeInfoGroup onig,LinkLineGroup llg) { 64 int seat = 0; 65 int leng = ng.size() - 1; 66 System.out.print(" @: KeyRoad : "); 67 System.out.print(ng.get(seat).getChara()); 68 while(seat!=leng) 69 { 70 LinkLineGroup ll = llg.selectWhereStartEquals(seat); 71 int size = ll.size(); 72 for(int i=0;i<size;++i) 73 { 74 int end = ll.get(i).end; 75 if(onig.get(end).buffer_period==0.0) 76 { 77 seat = end; 78 break; 79 } 80 } 81 82 System.out.print(" -> "); 83 System.out.print(ng.get(seat).getChara()); 84 } 85 } 86 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp; 2 3 import com.imp.cmp.line.LinkLine; 4 import com.imp.cmp.line.LinkLineGroup; 5 import com.imp.cmp.node.EndNode; 6 import com.imp.cmp.node.Node; 7 import com.imp.cmp.node.NodeGroup; 8 import com.imp.cmp.node.StartNode; 9 import com.imp.cmp.otherinfo.OtherNodeInfo; 10 import com.imp.cmp.otherinfo.OtherNodeInfoGroup; 11 import com.imp.cmp.tool.VisitedTool; 12 13 //--------------------------- 14 //---【程序编制器】 15 //-- 16 //- 17 // 18 public class Controler { 19 //-------------------------------------<内部成员>-------------------------------------// 20 //-- 21 //---[可访问数据] 22 //所有的连线 23 protected LinkLineGroup llg; 24 //所有的结点 25 protected NodeGroup ng; 26 //---[辅助信息集合] 27 protected OtherNodeInfoGroup onig; 28 //-------------------------------------<方法成员>-------------------------------------// 29 //-- 30 //---[常用方法] 31 //连接结点 32 public void addLine(int start,int end) { 33 this.llg.addLine(start, end); 34 } 35 //添加结点 36 public void addNode(Node node) { 37 this.ng.add(node); 38 } 39 //恢复结束结点 40 public void retireEndNode() { 41 this.ng.add(new EndNode(0.0)); 42 } 43 //---[进阶方法] 44 //建立总期限 45 public void buildSumPeriod() { 46 int sead = this.ng.size() - 1; 47 48 LinkLineGroup llg_s = this.llg.selectWhereEndEquals(sead); 49 50 int leng = llg_s.size(); 51 52 double early = -10.0; 53 54 for(int i=0;i<leng;++i) 55 { 56 LinkLine ll = llg_s.get(i); 57 58 double num = 0.0; 59 60 //如果是起始结点就是0,否则就是 最早完成时间 61 if(ll.start==0) 62 num = this.ng.get(ll.start).getTime(); 63 else 64 num = this.onig.get(ll.start).end_early; 65 66 if(num>early) 67 early = num; 68 } 69 70 ((EndNode)this.ng.get(sead)).setDTime(early); 71 } 72 //获取总期限 73 public double getSumPeriod() { 74 return this.ng.get(this.ng.size()-1).getTime(); 75 } 76 //开始建立辅助信息 77 public void build() { 78 79 this.build_other_info_init(); 80 this.build_early(); 81 this.buildSumPeriod(); 82 this.build_late(); 83 } 84 //---[内部方法] 85 //配给OtherNodeInfo的信息 86 private void build_other_info_init() { 87 int leng = this.ng.size(); 88 89 for(int i=0;i<leng;++i) 90 { 91 this.onig.add(new OtherNodeInfo()); 92 } 93 } 94 //建立最早的两个数据 95 private void build_early() { 96 int leng = this.ng.size(); 97 98 VisitedTool vt = new VisitedTool(leng); 99 100 vt.set(0); 101 vt.set(leng-1); 102 103 while(!vt.isAllAccess()) 104 { 105 for(int i=1;i<leng-1;++i) 106 if(!vt.isVisited(i)) 107 build_early(i,vt); 108 } 109 } 110 private void build_early(int sead,VisitedTool vt) { 111 LinkLineGroup llg_s = this.llg.selectWhereEndEquals(sead); 112 113 int leng = llg_s.size(); 114 115 boolean isAccess = true; 116 117 for(int i=0;i<leng;++i) 118 { 119 LinkLine ll = llg_s.get(i); 120 if(!vt.isVisited(ll.start)) 121 { 122 isAccess = false; 123 break; 124 } 125 } 126 127 if(isAccess) 128 { 129 double early = -10.0; 130 for(int i=0;i<leng;++i) 131 { 132 LinkLine ll = llg_s.get(i); 133 134 double num = 0.0; 135 136 //如果是起始结点就是0,否则就是最早完成时间 137 if(ll.start==0) 138 num = this.ng.get(ll.start).getTime(); 139 else 140 num = this.onig.get(ll.start).end_early; 141 142 if(num>early) 143 early = num; 144 } 145 146 OtherNodeInfo oni = this.onig.get(sead); 147 148 oni.start_early = early; 149 oni.end_early = early + this.ng.get(sead).getTime(); 150 151 this.onig.set(sead, oni); 152 153 vt.set(sead); 154 } 155 } 156 //建立最晚的两个数据 157 private void build_late() { 158 int leng = this.ng.size(); 159 160 VisitedTool vt = new VisitedTool(leng); 161 162 vt.set(0); 163 vt.set(leng-1); 164 165 while(!vt.isAllAccess()) 166 { 167 for(int i=leng-2;i>0;--i) 168 if(!vt.isVisited(i)) 169 build_late(i,vt); 170 } 171 } 172 private void build_late(int sead,VisitedTool vt) { 173 LinkLineGroup llg_s = this.llg.selectWhereStartEquals(sead); 174 int leng = llg_s.size(); 175 176 boolean isAccess = true; 177 178 for(int i=0;i<leng;++i) 179 { 180 LinkLine ll = llg_s.get(i); 181 if(!vt.isVisited(ll.end)) 182 { 183 isAccess = false; 184 break; 185 } 186 } 187 188 if(isAccess) 189 { 190 double late = 100000.0; 191 double menaral = 0.0; 192 for(int i=0;i<leng;++i) 193 { 194 LinkLine ll = llg_s.get(i); 195 196 double num = 0.0; 197 198 //如果是终止结点就是 leng - 1 ,否则就是最晚开始时间 199 if(ll.end==this.ng.size()-1) 200 num = this.ng.get(ll.end).getTime(); 201 else 202 num = this.onig.get(ll.end).start_late; 203 204 if(num<late) 205 late = num; 206 if(ll.end==this.ng.size()-1) 207 menaral = this.getSumPeriod(); 208 else 209 menaral = this.onig.get(ll.end).start_early; 210 } 211 212 OtherNodeInfo oni = this.onig.get(sead); 213 214 oni.end_late = late; 215 oni.start_late = late - this.ng.get(sead).getTime(); 216 oni.buffer_period = oni.start_late - oni.start_early; 217 218 oni.ldle_buffer_period = menaral - oni.end_early; 219 oni.inter_buffer_period = oni.buffer_period - oni.ldle_buffer_period; 220 221 this.onig.set(sead, oni); 222 223 vt.set(sead); 224 } 225 } 226 //---[信息展示方法]-------------//经过设计摸索改造,View 部分分离到 CMPViewer中 227 //只展示结点基本信息 228 /* 229 public void displayOnlyNode() { 230 int leng = this.ng.size(); 231 System.out.println("chara"+"\t"+"term"); 232 for(int i=0;i<leng;++i) 233 { 234 Node node = this.ng.get(i); 235 if(node.getChara().compareTo("Start")==0||node.getChara().compareTo("End")==0) 236 { 237 System.out.println(node.getChara()); 238 continue; 239 } 240 System.out.println(node.getChara()+"\t"+node.getTime()); 241 } 242 } 243 //只展示结点连接信息 244 public void displayLine() { 245 int leng = this.llg.size(); 246 System.out.println("Start"+"\t"+"End"); 247 for(int i=0;i<leng;++i) 248 { 249 LinkLine ll = this.llg.get(i); 250 System.out.println(this.ng.get(ll.start)+"\t"+this.ng.get(ll.end)); 251 } 252 } 253 //展示结点所有信息 254 public void displayAllNodeInfo() { 255 int leng = this.ng.size(); 256 System.out.println("chara"+"\t"+"term"+"\t"+"st_ear"+"\t"+"end_ear"+"\t"+"st_la"+"\t"+"end_la"+"\t"+"int_bp"+"\t"+"ldl_bp"+"\t"+"bp"); 257 for(int i=0;i<leng;++i) 258 { 259 Node node = this.ng.get(i); 260 if(node.getChara().compareTo("Start")==0||node.getChara().compareTo("End")==0) 261 { 262 System.out.println(node.getChara()); 263 continue; 264 } 265 OtherNodeInfo oni = this.onig.get(i); 266 267 System.out.println(node.getChara()+"\t"+node.getTime()+"\t"+oni.start_early+"\t"+oni.end_early+"\t"+oni.start_late+"\t"+oni.end_late+"\t"+oni.inter_buffer_period+"\t"+oni.ldle_buffer_period+"\t"+oni.buffer_period); 268 } 269 } 270 //展示总周期 271 public void displayTerm() { 272 System.out.println(" @: Term of the project: "+this.getSumPeriod()); 273 } 274 //展示关键路径 275 public void displayKeyRoad() { 276 int seat = 0; 277 int leng = this.ng.size() - 1; 278 System.out.print(" @: KeyRoad : "); 279 System.out.print(this.ng.get(seat).getChara()); 280 while(seat!=leng) 281 { 282 LinkLineGroup ll = this.llg.selectWhereStartEquals(seat); 283 int size = ll.size(); 284 for(int i=0;i<size;++i) 285 { 286 int end = ll.get(i).end; 287 if(this.onig.get(end).buffer_period==0.0) 288 { 289 seat = end; 290 break; 291 } 292 } 293 294 System.out.print(" -> "); 295 System.out.print(this.ng.get(seat).getChara()); 296 } 297 } 298 */ 299 //---[构造方法] 300 public Controler() { 301 this.llg = new LinkLineGroup(); 302 this.ng = new NodeGroup(); 303 this.ng.add(new StartNode()); 304 this.onig = new OtherNodeInfoGroup(); 305 } 306 }
com.imp.cmp.line 包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.line; 2 3 //--------------------------- 4 //---【连线】 5 //-- 6 //- 7 // 8 public class LinkLine { 9 //-------------------------------------<内部成员>-------------------------------------// 10 //起始位置 11 public int start; 12 //结束位置 13 public int end; 14 //-------------------------------------<方法成员>-------------------------------------// 15 //---[构造方法] 16 public LinkLine() { 17 super(); 18 // TODO Auto-generated constructor stub 19 } 20 public LinkLine(int start, int end) { 21 super(); 22 this.start = start; 23 this.end = end; 24 } 25 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.line; 2 3 import java.util.ArrayList; 4 5 //--------------------------- 6 //---【连线组】 7 //-- 8 //- 9 // 10 public class LinkLineGroup extends ArrayList<LinkLine>{ 11 //-------------------------------------<内部成员>-------------------------------------// 12 //串行标识 13 private static final long serialVersionUID = 1L; 14 //-------------------------------------<方法成员>-------------------------------------// 15 //-- 16 //---[常用方法] 17 //添加一个连线 18 public void addLine(int start,int end) { 19 super.add(new LinkLine(start,end)); 20 } 21 //索引起始符 22 public LinkLineGroup selectWhereStartEquals(int start) { 23 LinkLineGroup llg = new LinkLineGroup(); 24 25 int leng = super.size(); 26 27 for(int i=0;i<leng;++i) 28 { 29 LinkLine ll = super.get(i); 30 if(ll.start==start) 31 llg.add(ll); 32 } 33 34 return llg; 35 } 36 //索引结束符 37 public LinkLineGroup selectWhereEndEquals(int end) { 38 LinkLineGroup llg = new LinkLineGroup(); 39 40 int leng = super.size(); 41 42 for(int i=0;i<leng;++i) 43 { 44 LinkLine ll = super.get(i); 45 if(ll.end==end) 46 llg.add(ll); 47 } 48 49 return llg; 50 } 51 //---[构造方法] 52 public LinkLineGroup() { 53 super(); 54 } 55 }
com.imp.cmp.tool 包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.tool; 2 3 //--------------------------- 4 //---【遍历工具】 5 //-- 6 //- 7 // 8 public class VisitedTool { 9 //-------------------------------------<内部成员>-------------------------------------// 10 //存储区 11 private int [] jer; 12 //长度 13 private int leng; 14 //-------------------------------------<方法成员>-------------------------------------// 15 //-- 16 //---[基本方法] 17 public boolean isAllAccess() { 18 19 for(int i=0;i<leng;++i) 20 if(jer[i]==0) 21 return false; 22 23 return true; 24 } 25 //设置某一项可以通过 26 public void set(int x) { 27 if(x>=0&&x<this.leng) 28 this.jer[x] = 1; 29 30 } 31 //访问是否已经访问 32 public boolean isVisited(int x){ 33 return this.jer[x]!=0; 34 } 35 //重新设置 36 public void reset() { 37 this.jer = new int [this.leng]; 38 for(int i=0;i<this.leng;++i) 39 jer[i] = 0; 40 } 41 public void reset(int leng) { 42 this.leng = leng; 43 this.jer = new int [leng]; 44 for(int i=0;i<leng;++i) 45 jer[i] = 0; 46 } 47 //---[构造方法] 48 public VisitedTool(int leng) { 49 this.leng = leng; 50 this.jer = new int [leng]; 51 for(int i=0;i<leng;++i) 52 jer[i] = 0; 53 } 54 55 }
com.imp.cmp.otherinfo 包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.otherinfo; 2 3 //--------------------------- 4 //---【额外信息】 5 //-- 6 //- 7 // 8 public class OtherNodeInfo { 9 //-------------------------------------<内部成员>-------------------------------------// 10 //最早开始时间 11 public double start_early; 12 //最早结束时间 13 public double end_early; 14 //最晚开始时间 15 public double start_late; 16 //最晚结束时间 17 public double end_late; 18 //总缓冲期 19 public double buffer_period; 20 //干预缓冲期 21 public double inter_buffer_period; 22 //空闲缓冲期 23 public double ldle_buffer_period; 24 //-------------------------------------<方法成员>-------------------------------------// 25 //---[构造方法] 26 public OtherNodeInfo() { 27 this.start_early = 0.0; 28 this.end_early = 0.0; 29 this.buffer_period = 0.0; 30 this.inter_buffer_period = 0.0; 31 this.ldle_buffer_period = 0.0; 32 this.end_late = 0.0; 33 this.start_late = 0.0; 34 } 35 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.otherinfo; 2 3 import java.util.ArrayList; 4 5 //--------------------------- 6 //---【额外信息组】 7 //-- 8 //- 9 // 10 public class OtherNodeInfoGroup extends ArrayList<OtherNodeInfo>{ 11 //-------------------------------------<内部成员>-------------------------------------// 12 //串行标识 13 private static final long serialVersionUID = 1L; 14 //-------------------------------------<方法成员>-------------------------------------// 15 //-- 16 //---[添加方法] 17 //添加一个额外信息 18 public void addInfo() { 19 super.add(new OtherNodeInfo()); 20 } 21 //---[构造方法] 22 public OtherNodeInfoGroup() { 23 super(); 24 } 25 }
com.imp.cmp.node 包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.node; 2 3 //--------------------------- 4 //---【节点类】 5 //-- 6 //- 7 // 8 public abstract class Node { 9 //-------------------------------------<内部成员>-------------------------------------// 10 //结点描述 11 protected String chara; 12 //-------------------------------------<方法成员>-------------------------------------// 13 //-- 14 //---[set、get方法] 15 //get 16 public String getChara() { 17 return chara; 18 } 19 //set 20 public void setChara(String chara) { 21 this.chara = chara; 22 } 23 //---[构造方法] 24 public Node() { 25 super(); 26 this.chara = ""; 27 } 28 public Node(String chara) { 29 super(); 30 this.chara = chara; 31 } 32 //---[附加方法] 33 //因实际类型可复制,所以可以获取实际值 34 public abstract double getTime(); 35 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.node; 2 3 import java.util.ArrayList; 4 5 //--------------------------- 6 //---【节点组】 7 //-- 8 //- 9 // 10 public class NodeGroup extends ArrayList<Node>{ 11 //-------------------------------------<内部成员>-------------------------------------// 12 //串行标识 13 private static final long serialVersionUID = 1L; 14 //-------------------------------------<方法成员>-------------------------------------// 15 public NodeGroup() { 16 super(); 17 } 18 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.node; 2 3 //--------------------------- 4 //---【边缘节点】 5 //-- 6 //- 7 // 8 public class BasicNode extends Node { 9 //-------------------------------------<内部成员>-------------------------------------// 10 //实际期限 11 protected double savedTime; 12 //-------------------------------------<方法成员>-------------------------------------// 13 //-- 14 //---[set、get方法] 15 //set 16 public double getSavedTime() { 17 return savedTime; 18 } 19 //get 20 public void setSavedTime(double savedTime) { 21 this.savedTime = savedTime; 22 } 23 //---[构造方法] 24 public BasicNode() { 25 super(); 26 // TODO Auto-generated constructor stub 27 } 28 public BasicNode(String chara) { 29 super(chara); 30 // TODO Auto-generated constructor stub 31 } 32 public BasicNode(String chara,double savedTime) { 33 super(chara); 34 this.savedTime = savedTime; 35 // TODO Auto-generated constructor stub 36 } 37 public BasicNode(double savedTime,String chara) { 38 super(chara); 39 this.savedTime = savedTime; 40 // TODO Auto-generated constructor stub 41 } 42 //---[复写方法] 43 @Override 44 public double getTime() { 45 // TODO Auto-generated method stub 46 return this.savedTime; 47 } 48 49 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.node; 2 3 //--------------------------- 4 //---【中间节点】 5 //-- 6 //- 7 // 8 public class LinkedNode extends Node { 9 //-------------------------------------<内部成员>-------------------------------------// 10 //每一件活动的时期 11 protected double buffer_period; 12 //-------------------------------------<方法成员>-------------------------------------// 13 //-- 14 //---[set、get方法] 15 //get 16 public double getBuffer_period() { 17 return buffer_period; 18 } 19 //set 20 public void setBuffer_period(double buffer_period) { 21 this.buffer_period = buffer_period; 22 } 23 //---[复写方法] 24 @Override 25 public double getTime() { 26 // TODO Auto-generated method stub 27 return this.buffer_period; 28 } 29 //---[构造方法] 30 public LinkedNode() { 31 super(); 32 // TODO Auto-generated constructor stub 33 } 34 public LinkedNode(double buffer_period) { 35 super(); 36 this.buffer_period = buffer_period; 37 } 38 public LinkedNode(String chara) { 39 super(chara); 40 // TODO Auto-generated constructor stub 41 } 42 public LinkedNode(String chara,double buffer_period) { 43 super(chara); 44 // TODO Auto-generated constructor stub 45 this.buffer_period = buffer_period; 46 } 47 public LinkedNode(double buffer_period,String chara) { 48 super(chara); 49 // TODO Auto-generated constructor stub 50 this.buffer_period = buffer_period; 51 } 52 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.node; 2 3 //--------------------------- 4 //---【起始节点】 5 //-- 6 //- 7 // 8 public class StartNode extends BasicNode { 9 //---[构造方法] 10 public StartNode() { 11 super(0.0,"Start"); 12 } 13 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.node; 2 3 //--------------------------- 4 //---【结束节点】 5 //-- 6 //- 7 // 8 public class EndNode extends BasicNode { 9 //---[构造方法] 10 public EndNode(double dTime) { 11 super(dTime,"End"); 12 } 13 //---[set方法] 14 public void setDTime(double dTime) { 15 this.savedTime = dTime; 16 } 17 }
【项目结构图】
【类图】
这个类图的话,我还是只花类名和类之间的关系好了,具体每一个类有什么方法和参数,大家看我的例子好了
【使用到的设计模式】
1、MVC模式:Controler类对应C,CMPViewer对应的是V,而M与之对应的是NodeGroup、LinkLineGroup、OtherNodeInfoGroup三个类!
2、外观模式: 使用Client类,将整个程序的执行分成了四部分,也就是四个子系统,对这四个子系统的统一调用是属于外观模式的。
3、策略模式: 使用不同的Node类型是对工作结点的正确划分,我们实际上选用的还是具体某一类的结点。
4、代理模式:我们的 BasicNode 和 EndNode 之间是一个代理的,至少从程序员的角度来说是代理模式没错了。
5、适配器模式: 您可能会问啊,这有关联的地方明显没有继承关系啊!连对象适配器模式都不算吧?您先别急,听听我的理解——在我的程序中实际上LinkedNode的信息是不全的,很明显OtherNodeInfo的信息是作为LinkedNode的信息的补充,那么为什么不用继承呢?因为说到底这两部分信息不是同一时间改造的,你要喜欢就加一个 CompleteLinkedNode类,让它继承LinkedNode类,将OtherNodeInfo作为它的数据成员,形成 完整的中间节点类,这个时候就是完美的适配器模式了。
【测试】
1、测试用例1
输入用例:
3,A 5,B 2,C #END# 0,1 0,2 1,3 2,3 3,4 #END#
输出结果:
2、测试用例2
输入用例:
3,A 5,B 1,C 3,D 5,E 4,F 3,G 4,H #END# 0,1 1,2 2,3 1,4 4,5 3,6 5,6 3,7 5,7 6,8 7,8 8,9 #END#
输出结果:
【测试图中的表与之对应的中文释义】
参照下表: