重构后的代码

本来写博客只希望自总结的经验不要忘记 看来还是有人想交流一下的
那就有必要细节化的记录下个人经验啦
少说废话吧 还是根据昨天那到题目来:如下

假设每个学生有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;                 
 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     //
 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 

 

 

在类图中就可以看出 ToClient是一个组合类 这个类依赖于其他三个类的实

现,这是一个高耦合的类,把客户端的实现转移到了这个类当中,作用就是实现与显示想分离,有利有弊,分离的结果是造就了一个高耦合的类体,哎!

代码的优化总是要在不断的重构中积累经验才能达到的 所以以后要坚持重构 重构 再重构!

 

 

posted @ 2009-12-18 17:44  小喆  阅读(1637)  评论(1)    收藏  举报