心外无物
仍然记得在高中阶段,总是为了没有解题思路而苦恼。现在回想起来,总算有点感悟——执着于做题、刷题,却忽视了最本质的思考,为什么可以有这样的解题思路,别人是如何想到这种解题思路的。
这正是心学所提倡的,我们需要“心外无物”。所有事物的本质,并不在事物之中,而在我们自己心里。我们必须用自己心来掌控知识。学习一门知识,并不是知道其原理,而是需要体会到这样的设计、思路到底体现了怎样的思想。
关于思维方式的陷阱
我们经常在网络上看到类似“xxx的13种定级思维方式”的视频或者文章。读了之后,略有感触,但却无法实际运用。这其实是将所有情况都罗列出来,“总有一款适合你”,从而导致我们掉入选择的陷阱。
真正适用自己的思维方式,一定是自己体悟出来的
我无法认同那些“n种顶级思维方式”的说法。因为真正适合自己的,仅仅只有一种,而且,完全是个人体悟出来的。当然,这种体悟可能是在接收了大量信息后,瞬间感悟到的,
我无法认同那些“n种顶级思维方式”的说法。因为真正适合自己的,仅仅只有一种,而且,完全是个人体悟出来的。当然,这种体悟可能是在接收了大量信息后,瞬间感悟到的,
具体到技术而言,在解决某个问题,或者重构某段代码后,我往往会问自己,这到底体现了一种什么样的思想。并不断思考这个问题,试图从庞大的汉语言文化中,用两个字来概括这种思想。直至找到那个关键词。而这个关键词只有两三个字,并且能够真正直击个人心里,让自己瞬间感觉对于整个事情的认知尽在掌握之中。而且这两个字能够触动自己的思想。凭借这种方法来强迫自己的思考,不断思考,不断挖掘自己大脑中思考的深度。这是一个反复的过程,你会想到各种词语进行概括,但只有一个词能够让你满意。我想,这可能才是心学所提倡的“心外无物”。
首先要解决的问题——精确
在程序员的日常思维里,一旦说到代码划分,最容易想到的就是代码的分层。以最常见的MVC或者DDD为例,常见的代码结构划分如下:
无论是MVC还是DDD的概念中,代码层次是从所担负的职责来划分的。例如,Controller层负责处理控制;Service层负责处理业务逻辑;DAO层负责处理数据库操作。除了xxxContoller, xxxService,xxxDAO等类之外。常规的代码还包含了DO,DTO,VO,以及一些Convert类。
一个常见的DO类如下所示:
@Data
public class CommonDO {
public static final String FIELD_ID = "ID";
/**
* 自增id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 创建人id
*/
@TableField(value = "create_user_id", fill = FieldFill.INSERT)
private Long createUserId;
/**
* 创建人
*/
@TableField(value = "create_user", fill = FieldFill.INSERT)
private String createUser;
/**
* 创建时间
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 最后修改者
*/
@TableField(value = "update_user", fill = FieldFill.INSERT_UPDATE)
private String updateUser;
/**
* 最后修改时间
*/
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}
DAO层往往用于与数据库打交道。一个典型的Repository类的示例代码如下:
@Service
public class SubjectRepositoryImpl implements SubjectRepository {
@Resource
private SubjectMapper subjectMapper;
@Override
public Long addSubject(Subject subject) {
SubjectDO subjectDo = SubjectDoConvert.INSTANCE.dto2Do(subject);
subjectMapper.insert(subjectDo);
return subjectDo.getId();
}
@Override
public int updateSubject(Subject subject) {
SubjectDO subjectDo = SubjectDoConvert.INSTANCE.dto2Do(subject);
return subjectMapper.updateById(subjectDo);
}
@Override
public Subject findById(Long id) {
SubjectDO subjectDo = subjectMapper.selectById(id);
return SubjectDoConvert.INSTANCE.do2Dto(subjectDo);
}
}
很明显,DO类,往往与数据表结构一一对应;而Repository类(及其接口)也都以增删改查的操作为基础。这些代码,往往都是有一定规则的;而且不涉及复杂的业务逻辑。我们可以认为,这些代码都是模板代码。
无论采用MVC还是DDD,对于数据表的增删改查往往是绕不过去的。而对应于单个数据表所产生的类,可能会达到10个之多。在一个典型项目中,可能会出现如下Java类:
DO、DTO、VO、Service、ServiceImpl、Repository、RepositoryImpl、Mapper、Controller、DOConvert、DTOConvert
这些类的代码,是完全有规律可循的。例如,类所处的模块和包的位置、类的命名、类中的属性命名、方法的基本内容、局部变量的命名、各类之间相互的引用关系等等。严格说来,程序员必须遵循统一的标准来编写这些类。也只有遵循统一的标准,才能让所有模块的代码看起来,如同出自同一人之手。无论是后期的维护还是扩展,每位项目成员都可以做到轻车熟路。
对于这类代码,我们可以用精确来概括。一方面是说,代码的编写有迹可循,不应该出现不同风格;另外一方面也是说,它们完全是可以自动化生成的。
利用插件生成精确代码
根据当前公司使用的代码框架和所使用的IDE,开发对应的插件来生成模板代码,是目前最好的方案。利用插件来生成代码,可以无缝集成到IDE、自动将生成的代码置入对应的module,并自动完成相互引用、自动编译等动作。
以上个人开发的集成到Itellij和Eclipse编写的插件,用于生成模板代码。这样生成的代码,无需程序员关注,并且精确生成到各个子模块、包中。
从精确代码中解放出来
一旦解决了日常没有太多技术含量的模板代码,我们的注意力,便可以集中到如何提升技术认知上来了。