重构后的代码
本来写博客只希望自总结的经验不要忘记 看来还是有人想交流一下的
那就有必要细节化的记录下个人经验啦
少说废话吧 还是根据昨天那到题目来:如下
假设每个学生有3门课的成绩,从键盘接收用户的输入(要求用户按照一种良好的格式依次输入5名学生的姓名和成绩),在程序中按总分数从高到低的顺序将这5名学生信息按照一种良好的格式存放在“stu.txt”文件中。
首先把自己实现的类图贴上来有助于理解 类之间的关系 不会画图多见谅!

下面是根据昨天的问题重构后的代码,写的潦草
根据昨天的ClassSort类抽象出了算法父类 这样就可以灵活的切换算法 而丝毫不用改客户端的代码
如果要用新的算法实现 只要在 ToClient中 改变一下实例化子类的地方就完成了 实现了可扩展
代码 
  1 //这个类只能说是一个容器类 并不能说他就是排序算法类 因为我们只是借用了容器类通用的排序比较 如果要进行更复杂的排序
2 // 就要另外写一个真对算法的类,这里只是借用了api类当中的一些通用技巧罢了 还是不能灵活的变通应对算法的变化
3 //不过这样也算是达到了重构的目的了 只是真对两种排序的变化吗!
4 abstract class Operation<E>{
5 //既然是容器类那就用set吧
6 protected Set<E> set = null;
7 public Set<E> getSet(){
8 if(this.set == null)
9 return null;
10 return this.set;
11 }//end method
12 public void setSet(Set<E> set){
13 if(this.set == null)
14 this.set = set;
15 }//end method
16 }//end abstract class Operation
17
18 class ClassSort1 extends Operation{
19 private ClassSort1(){}
20 private static ClassSort1 sort = new ClassSort1();
21 public static Operation getInstence(){
22 return sort;
23 }
24
25 }//end class ClassSort
26
27 class WriteNative<T>{
28 private BufferedWriter bw = null;
29 private Set<T> set = null;
2 // 就要另外写一个真对算法的类,这里只是借用了api类当中的一些通用技巧罢了 还是不能灵活的变通应对算法的变化
3 //不过这样也算是达到了重构的目的了 只是真对两种排序的变化吗!
4 abstract class Operation<E>{
5 //既然是容器类那就用set吧
6 protected Set<E> set = null;
7 public Set<E> getSet(){
8 if(this.set == null)
9 return null;
10 return this.set;
11 }//end method
12 public void setSet(Set<E> set){
13 if(this.set == null)
14 this.set = set;
15 }//end method
16 }//end abstract class Operation
17
18 class ClassSort1 extends Operation{
19 private ClassSort1(){}
20 private static ClassSort1 sort = new ClassSort1();
21 public static Operation getInstence(){
22 return sort;
23 }
24
25 }//end class ClassSort
26
27 class WriteNative<T>{
28 private BufferedWriter bw = null;
29 private Set<T> set = null;
 30     public WriteNative(Set<T> set){
31 this.set = set;
32 }
33 public void Write() throws IOException{
34 File path = new File("D:\\MyTestWrite3.txt");
35 if(!path.exists())
36 path.createNewFile();
37 Write(path);
38 }
39 public void Write(File path) throws IOException{
40 if(path == null)
41 return;
42 if(bw == null)
43 bw = new BufferedWriter(new FileWriter(path,true));
44 if(set.size() != 0){
45 for(T t : set)
46 bw.write(t+"\r\n");
47 }
48 bw.close();
49
50 }//end method
51 }//end class WriteNative
52
53 //客户端针对接口调用即可
54 interface IClientProgram{
55 void writeIn(String info);
56 void writeNative();
57 }
58 //这个类应该依赖于抽象 而不应该依赖于具体实现
59 class ToClient implements IClientProgram{
60 //
31 this.set = set;
32 }
33 public void Write() throws IOException{
34 File path = new File("D:\\MyTestWrite3.txt");
35 if(!path.exists())
36 path.createNewFile();
37 Write(path);
38 }
39 public void Write(File path) throws IOException{
40 if(path == null)
41 return;
42 if(bw == null)
43 bw = new BufferedWriter(new FileWriter(path,true));
44 if(set.size() != 0){
45 for(T t : set)
46 bw.write(t+"\r\n");
47 }
48 bw.close();
49
50 }//end method
51 }//end class WriteNative
52
53 //客户端针对接口调用即可
54 interface IClientProgram{
55 void writeIn(String info);
56 void writeNative();
57 }
58 //这个类应该依赖于抽象 而不应该依赖于具体实现
59 class ToClient implements IClientProgram{
60 //
 61     private WriteNative writeNative = null;
62 private Operation sort = null;
63 String [] strs = new String[3];
64 Set<Student> set = null;
65 public void writeIn(String info){
66 split(info);//
67 sort = ClassSort1.getInstence(); //这里具体算法类实例实例化 这样就可以根据具体的算法不同去实例化不同的子类 实现了对扩展放
68 //这里我们把一个容器传入给排序类 用setSet
69 sort.setSet(new TreeSet<Student>(new Comparator<Student>(){
70 public int compare(Student stu1, Student stu2) {
71 long firstCompartor = stu1.getSum() - stu2.getSum();
72 if(firstCompartor == 0)
73 return stu1.getName().compareTo(stu2.getName());
74 return (int)firstCompartor;
75 }
76 }));//end anonymous innerclass
77 // sort.setSet(new HashSet<Student>());
78 //接下来却又通过getSet()方法得到我们刚刚传入的容器类
79 //这不是费二遍事儿吗,其实不然,这里你看到的只是一个容器而已,我们把容器看做是算法类,把需要排序的数据传入进去然后得到我们想要的数据才是目的
80
81 set = sort.getSet();
82 long english = Long.parseLong(strs[1]);
83 long math = Long.parseLong(strs[2]);
84 set.add(new Student(strs[0],(english + math)));
85
86 }//end method writenIn
87 public void writeNative(){
88 if(set == null)return;
89 writeNative = new WriteNative(set);
90 try {
91 writeNative.Write();
92 } catch (IOException e) {
93
94 e.printStackTrace();
95 }
96 }
97 private void split(String info){
98 if(info != null){
99 for(int i=0; i<3; i++){
100 strs[i] = info.split(" ")[i];
101 }
102 }
103 }//end method split
104
105 }//end class Client
106 class Student{
107 private String name;
108 private long sum;
109 public Student(String name,long sum){
110 this.name = name;
111 this.sum = sum;
112 }//end constructor
113 public String getName(){
114 return this.name;
115 }
116 public long getSum(){
117 return this.sum;
118 }
119 public String toString(){
120 return name +":"+ sum;
121 }
122 }//end innerclass
62 private Operation sort = null;
63 String [] strs = new String[3];
64 Set<Student> set = null;
65 public void writeIn(String info){
66 split(info);//
67 sort = ClassSort1.getInstence(); //这里具体算法类实例实例化 这样就可以根据具体的算法不同去实例化不同的子类 实现了对扩展放
68 //这里我们把一个容器传入给排序类 用setSet
69 sort.setSet(new TreeSet<Student>(new Comparator<Student>(){
70 public int compare(Student stu1, Student stu2) {
71 long firstCompartor = stu1.getSum() - stu2.getSum();
72 if(firstCompartor == 0)
73 return stu1.getName().compareTo(stu2.getName());
74 return (int)firstCompartor;
75 }
76 }));//end anonymous innerclass
77 // sort.setSet(new HashSet<Student>());
78 //接下来却又通过getSet()方法得到我们刚刚传入的容器类
79 //这不是费二遍事儿吗,其实不然,这里你看到的只是一个容器而已,我们把容器看做是算法类,把需要排序的数据传入进去然后得到我们想要的数据才是目的
80
81 set = sort.getSet();
82 long english = Long.parseLong(strs[1]);
83 long math = Long.parseLong(strs[2]);
84 set.add(new Student(strs[0],(english + math)));
85
86 }//end method writenIn
87 public void writeNative(){
88 if(set == null)return;
89 writeNative = new WriteNative(set);
90 try {
91 writeNative.Write();
92 } catch (IOException e) {
93
94 e.printStackTrace();
95 }
96 }
97 private void split(String info){
98 if(info != null){
99 for(int i=0; i<3; i++){
100 strs[i] = info.split(" ")[i];
101 }
102 }
103 }//end method split
104
105 }//end class Client
106 class Student{
107 private String name;
108 private long sum;
109 public Student(String name,long sum){
110 this.name = name;
111 this.sum = sum;
112 }//end constructor
113 public String getName(){
114 return this.name;
115 }
116 public long getSum(){
117 return this.sum;
118 }
119 public String toString(){
120 return name +":"+ sum;
121 }
122 }//end innerclass
在类图中就可以看出 ToClient是一个组合类 这个类依赖于其他三个类的实
现,这是一个高耦合的类,把客户端的实现转移到了这个类当中,作用就是实现与显示想分离,有利有弊,分离的结果是造就了一个高耦合的类体,哎!
代码的优化总是要在不断的重构中积累经验才能达到的 所以以后要坚持重构 重构 再重构!
                    
                

                
            
        
浙公网安备 33010602011771号