网站设计稿,2144网页游戏大厅,湖南政务服务网,在那些网站可以接兼职做1.1 分公司不就是一部门吗#xff1f; 我们公司最近接了一个项目#xff0c;是为一家在全国许多城市都有分销机构的大公司做办公管理系统#xff0c;总部有人力资源、财务、运营等部门。 这是很常见的OA系统#xff0c;需求分析好的话#xff0…1.1 分公司不就是一部门吗 我们公司最近接了一个项目是为一家在全国许多城市都有分销机构的大公司做办公管理系统总部有人力资源、财务、运营等部门。 这是很常见的OA系统需求分析好的话应该不难开发的。 是呀我开始也这么想这家公司试用了我们开发的系统后感觉不错他们希望可以在他们的全部分公司推广一起使用。他们在北京有总部在全国几大城市设有分公司比如上海设有华东区分部然后在一些省会城市还设有办事处比如南京办事处、杭州办事处。现在有个问题是总公司的人力资源部、财务部等办公管理功能在所有的分公司或办事处都需要有。你说怎么办 你打算怎么办呢大鸟不答反问道。 因为你之前讲过简单复制是最糟糕的设计所以我的想法是共享功能到各个分公司也就是让总部、分公司、办事处用同一套代码只是根据ID的不同来区分。 要糟了。 你怎么知道的确是不行因为他们的要求总部、分部和办事处是成树状结构的也就是有组织结构的不可以简单地平行管理。这下我就比较痛苦了因为实际开发时就得一个一个地判断它是总部还是分公司的财务然后再执行其相应的方法。 你有没有发现类似的这种部分与整体情况很多见例如卖电脑的商家可以卖单独配件也可以卖组装整机又如复制文件可以一个一个文件复制粘贴还可以整个文件夹进行复制再比如文本编辑可以给单个字加粗、变色、改字体当然也可以给整段文字做同样的操作。其本质都是同样的问题。 你的意思是分公司或办事处与总公司的关系就是部分与整体的关系 对的你希望总公司的组织结构比如人力资源部、财务部的管理功能可以复用于分公司。这其实就是整体与部分可以被一致对待的问题。 哈我明白了就像你举的例子对于Word文档里的文字对单个字的处理和对多个字甚至整个文档的处理其实是一样的用户希望一致对待程序开发者也希望一致处理。但具体怎么做呢 首先我们来分析一下你刚才讲到的这个项目如果把北京总公司当作一棵大树的根部的话它的下属分公司其实就是这棵树的什么 是树的分枝哦至于各办事处是更小的分支而它们的相关的职能部门由于没有分枝了所以可以理解为树叶。 尽管天下没有两片相同的树叶但同一棵树上长出来的树叶样子也不会相差到哪去。也就是说你所希望的总部的财务部管理功能也最好是能复用到子公司那么最好的办法就是我们在处理总公司的财务管理功能和处理子公司的财务管理功能的方法都是一样的。
1.2 组合模式 组合模式Composite将对象组合成树形结构以表示部分-整体的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。DP 组合模式Composite结构图 组合模式Composite将对象组合成树形结构以表示部分-整体的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。DP 组合模式Composite结构图 Component为组合中的对象声明接口在适当情况下实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件。 Leaf在组合中表示叶节点对象叶节点没有子节点。 Composite定义有枝节点行为用来存储子部件在Component接口中实现与子部件有关的操作比如增加add和删除remove。 客户端代码能通过Component接口操作组合部件的对象。
package code.chapter19.component1;import java.util.ArrayList;public class Test {public static void main(String[] args){System.out.println(**********************************************); System.out.println(《大话设计模式》代码样例);System.out.println(); ConcreteCompany root new ConcreteCompany(北京总公司);root.add(new HRDepartment(总公司人力资源部));root.add(new FinanceDepartment(总公司财务部));ConcreteCompany comp new ConcreteCompany(上海华东分公司);comp.add(new HRDepartment(华东分公司人力资源部));comp.add(new FinanceDepartment(华东分公司财务部));root.add(comp);ConcreteCompany comp2 new ConcreteCompany(南京办事处);comp2.add(new HRDepartment(南京办事处人力资源部));comp2.add(new FinanceDepartment(南京办事处财务部));comp.add(comp2);ConcreteCompany comp3 new ConcreteCompany(杭州办事处);comp3.add(new HRDepartment(杭州办事处人力资源部));comp3.add(new FinanceDepartment(杭州办事处财务部));comp.add(comp3);System.out.println(结构图);root.display(1);System.out.println(职责);root.lineOfDuty();System.out.println();System.out.println(**********************************************);}
}//公司抽象类
abstract class Company{protected String name;public Company(String name){this.name name;}public abstract void add(Company company); //增加public abstract void remove(Company company); //移除public abstract void display(int depth); //显示public abstract void lineOfDuty(); //履行职责
}//具体分公司类树枝节点
class ConcreteCompany extends Company{protected ArrayListCompany children new ArrayListCompany();public ConcreteCompany(String name){super(name);}public void add(Company company){children.add(company);}public void remove(Company company){children.remove(company);}public void display(int depth) { for(int i0;idepth;i)System.out.print(-);System.out.println(name);for(Company item : children){item.display(depth2);}} //履行职责public void lineOfDuty(){for(Company item : children){item.lineOfDuty();}}
}//人力资源部树叶节点
class HRDepartment extends Company{public HRDepartment(String name){super(name);}public void add(Company company){}public void remove(Company company){}public void display(int depth) { for(int i0;idepth;i)System.out.print(-);System.out.println(name);} //履行职责public void lineOfDuty(){System.out.println(name 员工招聘培训管理);}
}//财务部树叶节点
class FinanceDepartment extends Company{public FinanceDepartment(String name){super(name);}public void add(Company company){}public void remove(Company company){}public void display(int depth) { for(int i0;idepth;i)System.out.print(-);System.out.println(name);} //履行职责public void lineOfDuty(){System.out.println(name 公司财务收支管理);}
}
1.3 透明方式与安全方式 树可能有无数的分枝但只需要反复用Composite就可以实现树状结构了。 有点懂但还是有点疑问为什么Leaf类当中也有add和remove树叶不是不可以再长分枝吗 是的这种方式叫作透明方式也就是说在Component中声明所有用来管理子对象的方法其中包括add、remove等。这样实现Component接口的所有子类都具备了add和remove。这样做的好处就是叶节点和枝节点对于外界没有区别它们具备完全一致的行为接口。但问题也很明显因为Leaf类本身不具备add、remove方法的功能所以实现它是没有意义的。 哦那么如果我不希望做这样的无用功呢也就是Leaf类当中不用add和remove方法可以吗 当然是可以那么就需要安全方式也就是在Component接口中不去声明add和remove方法那么子类的Leaf也就不需要去实现它而是在Composite中声明所有用来管理子类对象的方法这样做就不会出现刚才提到的问题不过由于不够透明所以树叶和树枝类将不具有相同的接口客户端的调用需要做相应的判断带来了不便。 我喜欢透明式那样就不用做任何判断了。 开发怎么能随便有倾向性两者各有好处视情况而定吧。
1.4 何时使用组合模式 什么地方用组合模式比较好呢 当你发现需求中是体现部分与整体层次的结构时以及你希望用户可以忽略组合对象与单个对象的不同统一地使用组合结构中的所有对象时就应该考虑用组合模式了。 哦我想起来了。Java开发窗体用的容器控件java.awt.Container它继承于java.awt.Component就有add方法和remove方法所以在它上面增加控件比如Button、Label、Checkbox等控件就变成很自然的事情这就是典型的组合模式的应用。 哦对的对的这就是部分与整体的关系。
1.5 公司管理系统 package code.chapter19.component0;import java.util.ArrayList;public class Test {public static void main(String[] args){System.out.println(**********************************************); System.out.println(《大话设计模式》代码样例);System.out.println(); Composite root new Composite(root);root.add(new Leaf(Leaf A));root.add(new Leaf(Leaf B));Composite comp new Composite(Composite X);comp.add(new Leaf(Leaf XA));comp.add(new Leaf(Leaf XB)); root.add(comp);Composite comp2 new Composite(Composite XY);comp2.add(new Leaf(Leaf XYA));comp2.add(new Leaf(Leaf XYB));comp.add(comp2);Leaf leaf new Leaf(Leaf C);root.add(leaf);Leaf leaf2 new Leaf(Leaf D);root.add(leaf2);root.remove(leaf2);root.display(1);System.out.println();System.out.println(**********************************************);}
}abstract class Component{protected String name;public Component(String name){this.name name;}public abstract void add(Component component);public abstract void remove(Component component);public abstract void display(int depth);
}class Leaf extends Component{public Leaf(String name){super(name);}public void add(Component component){System.out.println(Cannot add to a leaf.);}public void remove(Component component){System.out.println(Cannot remove from a leaf.);}public void display(int depth){//叶节点的具体显示方法此处是显示其名称和级别for(int i0;idepth;i)System.out.print(-);System.out.println(name);}
}class Composite extends Component{private ArrayListComponent children new ArrayListComponent();//一个子对象集合用来存储其下属的枝节点和叶节点public Composite(String name){super(name);}public void add(Component component){children.add(component);}public void remove(Component component){children.remove(component);}public void display(int depth){//显示其枝节点名称for(int i0;idepth;i)System.out.print(-);System.out.println(name);//对其下级进行遍历for(Component item : children){item.display(depth2);}}
}
1.6 组合模式好处 组合模式这样就定义了包含人力资源部和财务部这些基本对象和分公司、办事处等组合对象的类层次结构。基本对象可以被组合成更复杂的组合对象而这个组合对象又可以被组合这样不断地递归下去客户代码中任何用到基本对象的地方都可以使用组合对象了。 我感觉用户是不用关心到底是处理一个叶节点还是处理一个组合组件也就用不着为定义组合而写一些选择判断语句了。 简单点说就是组合模式让客户可以一致地使用组合结构和单个对象。 这也就是说那家公司开多少个以及多少级办事处都没问题了。哪怕开到地级市、县级市、镇、乡、村、户…… 喂发什么神经了。大鸟提醒道开办事处到户你有毛病呀。 不过理论上用了组合模式在每家每户设置一个人力资源部和财务部也是很正常的。哪家不需要婚丧嫁娶、增丁添口等家务事哪家不需要柴米油盐、衣食住行等流水账。