关于Coding的一些思考


前言

前段时间有个朋友跟我说,你好像很久没写博客了。

我说是,最近工作比较饱和,业余时间整理的东西,暂时存到了笔记里,没有梳理好,不想拿出来“误人子弟”。

他说,那是你懒。

扎心了,老铁。

仔细想想,他说的对。做人做事,当始终如一。不忘初心,方得始终。

那今天就跟大家分享一下我最近的一些思考,起于代码,而不止于代码。

分而治之

分而治之,即通过各种灵活巧妙的方式方法,将较大的构成拆分成相互关联的较小的子系统。

说到这里我们来思考一下组件化的策略,它将复杂系统分解为更好管理的组件,使得系统更容易维护和扩展。其实这就是一种类似分而治之的思想。

举一反三,如果我们某个页面的逻辑变得越来越复杂怎么办?我们是不是也可以把页面的逻辑也拆分成一个一个的小组件呢?如果可以,我们应该怎么拆分呢?其他臃肿的结构我们是不是也可以这样处理呢?

其实拆分的方案有很多种,因地制宜。这里我先列出几种,大家如果有好的方案可以一起讨论:

  1. 多个自定义控件。

  2. 多个Fragment。

  3. 或者自己实现一个比Fragment更轻量的类,把逻辑拆分之后,委托给多个这样的类去处理,目前我们项目中有些地方是这样处理的。

    public abstract class BaseViewHolder {
    
        private final Unbinder mUnbinder;
    
        protected BaseViewHolder(View rootView) {
            mUnbinder = ButterKnife.bind(this, rootView);
        }
    
        public void unbind() {
            mUnbinder.unbind();
        }
    }

    逻辑比较简单,这里就不赘述了。如果需要特殊操作,比如绑定到Fragment的生命周期之类的,另行处理就好。

写代码和写作

好的代码就像好的小说一样,是不断改出来的。

如果你觉得当前项目中哪里写的很不舒服,那么改造它吧。

举个例子,社交App的聊天列表可能会有好多不同类型的消息,我们一般用 RecyclerView 来实现。

最初的实现可能是这样的:

public class MultipleItemAdapter extends RecyclerView.Adapter {

    //定义类型

    @Override
    public int getItemViewType(int position) {
        //根据数据的type,返回对应的类型
        return super.getItemViewType(position);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //根据类型初始化对应的ViewHolder
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        //根据类型绑定数据
    }

    @Override
    public int getItemCount() {
        return 0;
    }
}

迭代了一个版本之后,产品经理说,我们需要再加两种类型。这个时候我们该怎么办呢,是继续在这个类里添加类型还是重构一下呢?

如果你的项目里也有类似的代码,我的建议是重构。理由如下:

  1. 项目更容易维护和扩展

  2. 提升自己设计代码和编写代码的能力

那我们要重构成什么样子呢?我在前边也说了,好的代码是不断改出来的,我们可以先给自己定个小目标:每个类型的逻辑放到自己的类里去维护,做到单一职责。像这样:

public class Animal implements TypeInterface {

    @Override
    public int getLayoutRes() {
        return R.layout.item_test;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(View view) {
        return new AnimalVH(view);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, ViewModelInterface data) {
        AnimalInfo animalInfo = (AnimalInfo) data;
        AnimalVH animalVH = (AnimalVH) holder;
        animalVH.mTextView.setText("animal:" + animalInfo.toString());
    }

    static class AnimalVH extends RecyclerView.ViewHolder {

        public TextView mTextView;

        public AnimalVH(View itemView) {
            super(itemView);
            mTextView = (TextView) itemView.findViewById(R.id.test);
        }
    }
}

那我们怎么实现呢,其实就是把逻辑委托出去。我简单写了下,可能比较粗暴,但已经实现了我们的需求。

public interface TypeInterface {

    int getLayoutRes();

    RecyclerView.ViewHolder onCreateViewHolder(View view);

    void onBindViewHolder(RecyclerView.ViewHolder holder, ViewModelInterface data);
}

public interface ViewModelInterface {

    int getType();
}

public abstract class BaseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    public Map<Integer, TypeInterface> mTypes;

    public List<ViewModelInterface> mDatas;

    protected BaseAdapter() {
        mTypes = new HashMap<>();
        mDatas = new ArrayList<>();
    }

    @Override
    public int getItemViewType(int position) {
        // TODO: 2017/11/3 将数据映射到对应的实现类型
        return mDatas.get(position).getType();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // TODO: 2017/11/3 由对应的实现类型创建holder
        View v = LayoutInflater.from(parent.getContext())
                .inflate(mTypes.get(viewType).getLayoutRes(), parent, false);
        return mTypes.get(viewType).onCreateViewHolder(v);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        // TODO: 2017/11/3 根据holder或者数据对应回实现类型,由实现类型对象绑定数据
        mTypes.get(mDatas.get(position).getType()).onBindViewHolder(holder, mDatas.get(position));
    }

    @Override
    public int getItemCount() {
        return mDatas == null ? 0 : mDatas.size();
    }
}

代码比较简单,我也就不过多叙述了,其实重要的是这种重构代码的意识,如果觉得哪里写的不舒服,那就改造它吧。

方向很重要

古语有云,凡事预则立,不预则废。

当我们拿到一个需求的时候,我们首先要做的就是把需求分析清楚,不明白的地方及时沟通,否则做的越多,错的也就越多。也就是思考要高于实现。

其实方案出来之后不妨和周围同事讨论一下,可能会发现一些更好的思路也说不定。总之有了对的思路,才能做出来对的事情。

勤于梳理

所谓梳理,在我看来就是对一段时间内做过的事情做一个简单的分析。梳理的过程也是沉淀的过程。

拿记笔记来说,可能一个月的笔记就有十几篇。就像入冬的时候我们想找去年冬天的衣服可能要翻箱倒柜一样,可能一段时间之后,我们都不知道自己之前的笔记记了什么。那我们不妨抽一些时间出来梳理这些笔记,梳理的过程中可以对这些笔记做一个整合或者删减,方便管理。

做项目也是一样,我们对每个版本变化的点也要时常梳理,可能1.0版本的时候加入的功能到1.3版本完全不需要了,我们则需要精确的对这部分差异代码做一些处理。

面向文档编程

忘了从哪里看过一句话是这样说的,好的程序员文档和代码的量大概是1:1。1:1可能有些夸张,但一个项目如果能有一个详细的文档是非常不错的。

从技术调研到方案的确定,再到版本变更,这些东西是很有必要记录的。既方便自己梳理,避免遗漏一些东西,也方便新人熟悉项目,好处多多。

所以,养成写文档的好习惯吧。

后记

暂时就这些吧,希望今天的分享能给大家带来一些小启发。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Qt面试中,coding环节通常是测试应聘者Qt编程技能和经验的重要部分。对于Qt面试的coding部分,可能会涉及以下几个方面: 1. Qt基础知识:应聘者需要掌握Qt的基本概念和常用类,了解Qt的对象模型和信号槽机制。可能会出现一些关于Qt类的使用和常见操作的问题。 2. UI设计与开发:这部分可能会要求应聘者根据一些需求或UI设计稿实现一个界面。应聘者需要使用Qt的UI设计工具,例如Qt Designer,完成界面的设计和布局,并用C++代码实现界面的功能。 3. 数据处理与算法:有时候面试官会出一些与数据处理或算法有关的问题,以考察应聘者对Qt的灵活运用能力。例如,要求实现一个基于Qt的文本编辑器,或者对一组数据进行排序等。 4. 多线程编程:对于需要处理并发或耗时操作的问题,可能会考察应聘者的多线程编程能力。这包括使用Qt提供的多线程类或库函数,以及保证线程安全性和避免资源竞争的经验。 5. 调试与问题解决能力:面试过程中可能会有意设置一些错误或问题,观察应聘者的调试和解决问题的能力。应聘者需要能够熟练使用Qt的调试工具,查找和修复代码中的问题和错误。 在Qt面试的coding环节中,关键是熟练掌握Qt的基本特性和常用类,以及对数据处理、UI设计、多线程和问题解决的经验和能力。同时,良好的编码风格和规范也是考察的一项重点。通过练习和实际项目的积累,不断提升自己的Qt编程技能,才能在Qt面试中有较好的表现。 ### 回答2: QT面试coding主要是针对QT编程技能的考察。在QT面试coding过程中,通常会给出一些编程问题或者需要完成一些编程任务。 首先,面试官可能会问一些基础的QT问题,例如QT的信号与槽机制、布局管理器、窗口部件等等。回答这些问题需要我们对QT的相关概念有一定的了解和掌握。 其次,面试官可能会给出一些具体的编程问题,要求我们使用QT进行解答。这些问题可能涉及到QT的各种功能和模块,例如窗口的绘制、界面的响应事件、文件的读写等。在解答这些问题时,我们需要灵活运用QT的相关函数和类进行编程实现。 最后,面试官可能会要求我们完成一些编程任务,例如实现一个简单的QT应用程序、设计一个界面等等。在这些任务中,我们需要运用QT的各种功能和UI设计技巧来完成。 总的来说,QT面试coding主要考察我们对QT编程的熟练程度和实际应用能力。我们需要熟悉QT的相关知识,并能够灵活运用QT进行编程。通过在面试中展示我们的编程能力,我们能够更好地展现自己的优势,提高获得工作机会的几率。 ### 回答3: 在qt面试的coding环节中,通常会要求应聘者完成一个具体的编程任务来评估其在qt开发方面的能力。 首先,面试官可能会询问应聘者是否有qt编程经验以及相关项目经验。这些问题旨在了解应聘者是否熟悉qt框架,是否能够独立开发qt应用程序,并根据具体需求进行调试和优化。 接下来,面试官可能会给应聘者一个具体的编程问题,要求应聘者使用qt编写代码解决该问题。这个问题可能涉及到窗口和控件的创建、布局、信号与槽的连接、界面交互等方面。 在解决问题的过程中,应聘者需要熟悉qt的基本概念和常用的类,比如QWidget、QBoxLayout、QPushButton、QLineEdit等。同时,还需要掌握qt的常用功能,比如事件处理、界面设计和绘图等。 应聘者需要根据问题的要求编写代码,并确保代码的可读性、可维护性和效率。在编程过程中,应聘者需要熟练运用qt的API,同时遵循良好的编码规范,确保代码的质量。 此外,应聘者还可以采取一些额外的措施来提高代码的质量和可扩展性,比如使用设计模式、封装可复用的代码、添加注释和文档等。 最后,面试官可能会与应聘者讨论和评价其代码的质量和实现细节。这个过程中,应聘者需要清楚地解释和展示自己的代码实现,并回答面试官的问题和疑问。 在qt面试的coding环节中,关键是理解问题、熟练使用qt的API和功能,并能够用清晰、简洁、高效的代码解决问题。同时,代码的可读性和可维护性也是重要的考察因素。通过合理的思考和实现,展示自己在qt开发方面的能力和经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值