首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重构以修复架构错误

重构以修复架构错误
EN

Stack Overflow用户
提问于 2015-01-26 09:16:30
回答 3查看 30关注 0票数 0

在一种工作的应用程序中,我看到了这个可怕的代码:

代码语言:javascript
复制
class SomeUglyClass extends Thread {
    ArrayList<SomeData> someDataStructure = new ArrayList<SomeData>();
    Handler mHandler = new Handler() {
        // a lot
        // writing to someDataStructure
    }
    public void run() {
        int some_count, ...;
        while(true) {
            // a lot
            // r/w access to someDataStructure

            try {
                Thread.sleep(1, 0);
            } catch (Exception e) {
                break;
            }               
        }
    } // end of run(), total 500 lines of code
} // end of SomeUglyClass, total 4K lines of code

也许您已经看到了这段代码的问题。如果没有,它们在这里:

  1. mHandler附加到UI线程(因为它是由加载类的线程创建的,类是主线程)。
  2. 没有活套(事实上是,bug,)
  3. 线程浪费CPU时间,耗尽电池。
  4. someDataStructure并不是线程安全的,但是同步基本访问操作不会有帮助;在一个没完没了的循环中同步大块代码可能会阻塞受保护的资源,并使它对其他线程不可用;最后,它不仅是someDataStructure,整个类都基于这样的假设,即只有一个线程可以运行其代码。
  5. 我不能仅仅添加活套,因为必须运行run()中的无穷无尽的循环,而Looper.loop();也是一个无限循环。一个线程不能运行两个无限循环。

尽管这个宏伟的架构失败了,但代码确实在做一些事情,它不能立即重写,它是4K行代码,而且我常常只能猜测代码到底做了什么。

我要重建它。它应该是一系列保持功能的小步骤。

如何重构这段很棒的代码?

EN

回答 3

Stack Overflow用户

发布于 2015-01-26 10:00:46

您应该尝试使用分离关注点:首先尝试将整个类划分为多个最小的类,每个类负责做/处理一件事情。

您可能有一些用于数据访问(读/写数据)、服务(独立业务逻辑)和UI的内容。您可以使用事件总线在对象之间进行解耦(考虑奥托),并且可能是依赖注入(考虑短剑)。

这种分离过程将帮助您理解每一段代码所做的事情以及不同部分之间的依赖关系,从而使编写单元/集成测试变得更加容易。

票数 1
EN

Stack Overflow用户

发布于 2015-01-26 09:32:36

添加大量的测试,使用版本控制,然后以您需要的速度工作。

票数 0
EN

Stack Overflow用户

发布于 2015-01-27 11:41:38

第一步是改变:

代码语言:javascript
复制
    public void run() {
        int some_count, ...;
        while(true) {
            // a lot
            // r/w access to someDataStructure

            try {
                Thread.sleep(1, 0);
            } catch (Exception e) {
                break;
            }               
        }
    }

至:

代码语言:javascript
复制
    @Override
    public void run() {
        Looper.prepare();
        mHandler = new MyHandler();
        mHandler.post(run_step);
        Looper.loop();
    }

    Runnable run_step = new Runnable() {
        int some_count, ...;

        @Override
        public void run()
        {
            //while(true) {
                // a lot
                // r/w access to someDataStructure

                mIntoThreadHandler.postDelayed(this, 1);
            //}
        }
    }

这保留了功能,但仍然浪费CPU时间。紧急问题已经解决,问题已经解决,我不能把“必须重构以杀死可怕的代码”卖给我的管理人员,但我可以卖给“如果我重构就能更快地工作”,于是又开了一个新的单独的问题。啊!

没有机会出售“大量的测试”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28147313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档