尽可能的构建一个拓展性比"较好"的项目,会让你后期迭代好受点

转载请注明出处:王亟亟的大牛之路

这礼拜基本都在忙自己项目上的事,然后之后会“重新整理”后把这部分的功能开源出来,这里@下队友 NeglectedByBoss

本周还是没有停更收纳库,继续安利:https://github.com/ddwhan0123/Useful-Open-Source-Android (把疑难杂症给拆出去了,还剩资料,工具类和自定义控件的细分工作)

这一篇来简单的模拟一个读书的业务流程来谈一下代码拓展性的问题

建立模型

首先我们得 建立书的对象

public class Book<T> {

   public String Name; //书名
   public int PageCount; //总页数
   public int NowPage; //当前页数
   public T BookMoreMSG; //附加信息
   /**
   * get set等其他方法省略
   */

因为我们读一本书 肯定有他的一些基本信息,这里就 设置了书名,总页数,当然还可以有作者,出版日期等等等,我们只是例子不需要太复杂

NowPage 用来判断读书进展

BookMoreMSG 这是个泛型,也就是我们的补充项,让每一本书的对象更鲜活。而让代码实现也更灵活,增强了我们的拓展性,他可以是一句话 ,可以是一个对象 等等等。


读书状态回调

写的时候其实我没有刻意的要想怎么去假设,怎么去设计也就是写着写着改着改着(这种方式本身不太好,还是建议大家在开始敲代码之前好好的想想怎么做更好)

那既然读书,肯定是要慢条斯理的,而且还肯定要有状态于是我就让这个读书的行为用一个子线程然后让他 .Sleep()下来模拟正在读书的行为

先创建一个读书状态无非是 开始读书,正在读书,读完了 那么我们就用一个接口去实现

public interface ReadListener<T> {
    //开始读书
    void start();

    //正在读书
    void doing(T t);

    //读完了
    void finish(T t);
}

因为我们书有一系列的属性,所以我们把书的状态作为参数传入,又因为这个接口(可能)可以在别的地方复用 所以传入的参数还是用了泛型


填充数据

读书之前我们得有书,所以我们得填充下数据,这本奥特曼打怪兽 我们给他一个描述语句 是神秘的反派角色 ,他总共 15页,我们的小宝宝从头开始读

  /*
    * 模拟数据
    * */
    private Book<String> addBook() {
        book = new Book<>();
        book.setBookMoreMSG("神秘的反派角色");
        book.setName("奥特曼打怪兽");
        book.setPageCount(15);
        book.setNowPage(0);
        return book;
    }

读书的实现

读书的状态跟视图(也就是Activity/Fragment)没什么关系,所以为了让视图视图 让一个类在子线程去读书吧,如果想在页面上展示进度直接用接口传递就好了,So Easy!!

那我们再写个接口,让他作为传播媒介告诉UI好了

public interface CommunicateListener {
    void setMsg(Message msg);
}

非常简单的一个接口,传递一个Message对象,你想给UI传啥都行了。

既然要实现读书,那肯定要实现读书状态的回调,那我们就来实现他

因为上面确定了,我们图书的附加内容是一句话,那泛型的书就都成了Book<String>类型的Book了

public class ReadImp implements ReadListener<Book<String>> {
    Book<String> book;
    CommunicateListener communicate;

    public void setMessager(CommunicateListener communicate) {
        this.communicate = communicate;
    }

    public ReadImp(Book<String> book) {
        this.book = book;
    }

    @Override
    public void start() {
        Log.d("--->", "ReadImp 开始读书");
    }

    @Override
    public void doing(Book<String> book) {
        Log.d("--->", "现在读到第 " + book.getNowPage() + "页");
    }

    @Override
    public void finish(Book<String> book) {
        Log.d("--->", "读完了,总共读了 " + book.getNowPage() + "页");
        Message message = Message.obtain();
        message.obj = book.getBookMoreMSG();
        communicate.setMsg(message);
    }
}

这里没有让消息一直刷UI就 读书读完了 让他 把他读完的消息发出去。


逻辑实现算是通了,那我们来看下UI咯

主UI

这里写图片描述

下面还有个TextView,因为一开始宝宝没有读完书,所以没字。

public class MainActivity extends AppCompatActivity implements View.OnClickListener, CommunicateListener {
    private Button read_btn, send_text;
    private ReadImp readImp;
    private EditText edit_baobao;
    private ReadThread readThread;
    private Thread thread;
    private volatile Book<String> book;
    private ReadBookTextView read_text;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }

    private void init() {
        Log.d("--->", "主线程的 ID 是 " + Thread.currentThread().getId());
        //给书赋值
        addBook();
        readImp = new ReadImp(book);
        readImp.setMessager(this);
        readThread = new ReadThread(book, readImp);
        thread = new Thread(readThread);
        initWidget();
    }

    @Override
    protected void onStart() {
        super.onStart();
        thread.start();
        Log.d("--->", "开启的线程 ID 是 " + thread.getId());
    }

    @Override
    protected void onStop() {
        super.onStop();
        thread.interrupt();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        thread = null;
        readThread = null;
    }

    private void initWidget() {
        read_text = (ReadBookTextView) findViewById(R.id.read_text);
        read_btn = (Button) findViewById(R.id.read_btn);
        send_text = (Button) findViewById(R.id.send_text);
        edit_baobao = (EditText) findViewById(R.id.edit_baobao);
        send_text.setOnClickListener(this);
        read_btn.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.read_btn:
                read_text.setText("");
                thread.interrupt();
                break;
            case R.id.send_text:
                if (edit_baobao.getText().toString().trim().length() > 0) {
                    read_text.setText(edit_baobao.getText().toString().trim());
                }

                break;
        }
    }

    @Override
    public void setMsg(Message msg) {
        read_text.setText("补充内容是 " + msg.obj.toString());
    }


    /*
    * 模拟数据
    * */
    private Book<String> addBook() {
        book = new Book<>();
        book.setBookMoreMSG("神秘的反派角色");
        book.setName("奥特曼打怪兽");
        book.setPageCount(15);
        book.setNowPage(0);
        return book;
    }
}

我们的MainActivity 实现了 看消息的 CommunicateListener接口

所以在实现类读完了书会告诉我们他要告诉我们的Message

补充下 ReadBookTextView这个类是我零时改的一个 自定义TextView,可以在子线程修改,之前的博客介绍过,直接COPY过来改了改

传送门:http://blog.csdn.net/ddwhan0123/article/details/50956307

也就是说我们读书的过程都是在子线程读的,我们读完书的结果也是在子线程刷新的UI。

OK,那整个DEMO要阐明什么?
  • 共有的一些逻辑/概念/行为,可以抽象的一定要抽象,好处在于 1省代码,2维护性好,3拓展性强。(这本书无论换什么类型的描述字段我们都可以用一套代码来实现,最多加不同的IMP实现,当然你可以在IMP实现上再加一层封装,那更SO EASY了!)

  • 频繁的刷UI本身就是对MainThread进行“摧残”,但是有些时候我们还真没办法,那简单的一些刷UI的工作就可以放到子线程里去做,诸如各种setText,set…set…等等等,当然这个还是要取决于 “团队可用于子线程刷新的组件的厚度”,反正是能往子线程丢就丢。(Rx套餐其实是把非UI的行为全挪走了,我们这里的做法就是能分担多少就分担多少,充分利用现在手机多CPU的特性)

  • 项目结构,其实也不用盲目的 MVC MVP MVVP什么的,适合自己项目实际场景的才是最好的(虽然我不知道怎么的写着写着这个例子有点MVP的味道)

  • 多利用OOP的特性

补一些过程中的图吧

读书的过程

这里写图片描述

项目结构

这里写图片描述

当然这篇完全是我随手写出来的,真是想到哪写到哪,最后写完了才发现 嘿?好像可以来篇Blog什么的解释下,如果有不对的地方请大家指出(肯定有很多不足的地方,但是思路大家可以参考下)。

(其实最初是想写关于Number的,哈哈哈)

git地址:https://github.com/ddwhan0123/BlogSample/tree/master/NumberDemo

附件下载地址:https://github.com/ddwhan0123/BlogSample/blob/master/NumberDemo/NumberDemo.zip?raw=true

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: 敏捷项目进度跟踪工具-迭代燃尽图.xls 是一种非常有用的敏捷开发工具,它可以帮助团队更好地跟踪项目进度和实现更高的生产力。通过迭代燃尽图,团队可以直观地了解每个迭代的工作量和时间,从而更好地安排工作,及时解决问题,提高开发效率。 在迭代燃尽图中,横轴为时间,纵轴为工作量。其中,每个迭代都有一个横向的线,代表团队预计在该迭代中完成的工作量。另外,还一个斜线,代表每天实际完成的工作量。当实际完成工作量和预计完成工作量相等时,表示该迭代已经完成。如果实际完成工作量低于预计完成工作量,需要团队加紧工作,以确保项目能够按时完成。如果实际完成工作量超过预计完成工作量,则说明团队效率很高,可以在该迭代中增加一些额外的任务,以更好地利用时间。 总之,敏捷项目进度跟踪工具-迭代燃尽图.xls 为敏捷开发项目迭代管理提供了重要帮助。团队可以根据每个迭代的情况及时做出调整,以确保项目按时完成,同时提高生产力和效率。 ### 回答2: 敏捷项目进度跟踪工具-迭代燃尽图.xls(Iteration Burn Down Chart)是一种用于敏捷项目管理的进度跟踪工具,旨在帮助项目团队追踪项目进度,了解工作量和任务状态,及时发现并解决问题,确保项目按时高质量完成。 燃尽图以时间为横轴,任务完成情况为纵轴,将整个项目的工作量分解为小的任务,在每个迭代期间测量任务完成情况,反映出项目进度和任务完成的速度,通过对迭代燃尽图的跟踪和分析,团队可以更好地掌握整个项目的进展情况和任务完成情况,及时调整工作进度和优化工作流程,以保证项目按时、高质量完成。 此外,迭代燃尽图不仅可以帮助团队进行进度跟踪和问题管理,还可以用于沟通交流和计划制定,同时也是团队协作和团队成员之间透明度的一个体现。因此,掌握好迭代燃尽图的使用和分析,对于项目管理和团队协作都有着非常重要的意义。 ### 回答3: 敏捷项目进度跟踪工具-迭代燃尽图.xls是敏捷开发项目管理中经常用到的工具,用于跟踪团队在迭代期间完成的工作量和剩余工作量,并通过图形化展示来帮助项目经理和团队监控项目进度。 该工具主要由一个由横轴和纵轴组成的表格构成,每个迭代在表格中新建一列,横轴为时间轴,列出迭代期间的每一天,纵轴为任务量,按照团队正在解决的任务进行排列。团队在每天结束时在表格中记录下已完成的任务量和还剩余的任务量,通过这些数据进行计算,可以得到每个迭代日的完成率和剩余工作量。 利用这些数据,工具生成一张燃尽图,通过图形化呈现,让用户可以更清晰的了解到团队当前的任务完成情况,以及所处迭代的总任务量、已完成的任务量和剩余的任务量。这使得项目经理和团队可以更加及时地调整团队工作计划,提高生产效率,保证项目按时完成。 总之,敏捷项目进度跟踪工具-迭代燃尽图.xls是一个十分实用的项目管理工具,可帮助团队和项目经理更好地跟踪团队的进度和任务完成情况,提高项目成功率。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值