现在的位置: 首页 > 综合 > 正文

不良代码展示-高耦合度代码的例子

2012年08月20日 ⁄ 综合 ⁄ 共 2334字 ⁄ 字号 评论关闭

 原创文章,如有转载,请注明出处:http://blog.csdn.net/yihui823/article/details/6833131

 

前段时间,看到别人的一段代码,其实没什么逻辑,却做的丰富异常。

代码运行极其不稳定,却无从下手去改动。后来下定决心重写了。

昨晚有空,把原来不良代码抽取出来,供大家参考。

 

package testpj;

import java.util.Timer;
import java.util.TimerTask;

/**
 * 高耦合的展示类
 * @author yihui823
 */
public class CouplingTester {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        Connect conn = new Connect();
        Listener l = new Listener(conn);
        conn.setListener(l);
        l.onConnFailed("first connect");

        //循环查看Connect的对象
        while(true) {
            System.out.println(l.getConnect().hashCode());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
            }
        }
    }

    /**
     * 模拟一个连接类
     */
    private static class Connect extends Thread {

        //监听器
        private Listener listener;

        /**
         * 设置监听器
         * @param listener 监听器
         */
        public void setListener(Listener listener) {
            this.listener = listener;
        }

        /**
         * 线程方法,开始进行连接.
         */
        public void run() {
            //假设连接失败
            try {
                //保持连接
                Thread.sleep(2000);
                listener.onConnFailed("Connecting error!");
                System.out.println("连接失败.");
            } catch (InterruptedException ex) {
            }
            
            //假设连接成功
//            System.out.println("连接成功.");
//            while (true) {
//                try {
//                    //保持连接
//                    Thread.sleep(2000);
//                    System.out.println("保持连接.");
//                } catch (InterruptedException ex) {
//                }
//            }
        }
    }

    /**
     * 模拟监听器
     */
    private static class Listener {

        private Connect conn;
        private Timer timer = null;

        public Listener(Connect conn) {
            this.conn = conn;
        }
        
        public Connect getConnect() {
            return conn;
        }

        /**
         * 连接失败时调用
         * @param msg 失败消息
         */
        public void onConnFailed(String msg) {

            System.out.println("Connect failued : " + msg);
            timer = new Timer();
            ConnectTask ct = new ConnectTask(timer, conn);
            timer.schedule(ct, 3000, 100);
        }
    }

    /**
     * 一个连接任务类
     */
    public static class ConnectTask extends TimerTask {

        private Connect conn;
        private Timer timer = null;

        public ConnectTask(Timer timer, Connect conn) {
            this.timer = timer;
            this.conn = conn;
        }

        public void run() {
            if (conn.isAlive()) {
                System.out.println(conn.hashCode() + " is still alive.");
                if (timer != null) {
                    timer.cancel();
                    timer = null;
                }
            } else {
                System.out.println(conn.hashCode() + " is not alive.");
                conn = new Connect();
                conn.setListener(new Listener(conn));
                conn.start();
            }
        }
    }
}

Connect类里的run方法,原来是做连接用的,这里用简单的代码去模拟了。

我们可以看到,这段代码的逻辑,其实是要做一个重连接。

也就是说,当连接断了之后,自动触发onConnFailed事件,然后再次去做连接。

在这个例子里面,Connect里面保存了Listener,而Listener里面又保存了Connect,

ConnectTask里面也保存了Connect。三个类紧紧的耦合在一起,

一个简单的逻辑有两个线程在运作。其结果,是一旦有一次失败了,

则会多一个Timer在后台持续运行,而这个Timer不会被标记停止。

 

这里主要的问题,就是三个类的高耦合。而良好的代码,是需要做到:高内聚,低耦合的。也就是说,类与类之间的关系,越松散越好,最好能相互独立。

 

解耦改动的方法:

1,Connect里面设置Listener。但是,Listener里面,不记录Connect实例。

2,在onConnFailed事件中,只是做启动连接的动作,不要启动线程。再次连接之前,暂停一段时间即可。

 

具体代码就不贴出来了。重点就是:不要高耦合。

 

 

抱歉!评论已关闭.