这本书我买的是第二版,第一版是java的,第二版以js作为例子。这有点不太好,虽然高手觉得编程语言都一样,落花飞叶皆可伤人。但是我觉得还是有点痛苦。读这本书的感觉是最主要要有代码优化的思维,有了思维才好操作,
比如以前写代码都是照着业务逻辑,只要实现了,只要跑的没Bug,一切完美,没问题。然而这本书的思路不是从机器的角度跑起来就完事了,而是从人的角度来看,比如让你接受一个新系统,你是否看代码好看,理解的快,是否修改起来方便,易于维护?
所以里面大量的操作都是把代码方法拆的非常碎,非常碎就意味着要经常测试,经常发布,每次新增加的代码都是回去看看是否整体代码还能优化,而不是我们以前的项目,做完就扔了,要维护就专门维护,我承认这么搞很累,但是效果确实好一点点,书里说的代码应该时时维护,而不是像一个水果一样,任由它腐烂掉。还提到了敏捷编程,极限编程,tdd,最终目的还是为了保证代码的质量。而不是我以前理解的敏捷开发,我以前觉得,敏捷就是催着你玩命的干,不是这样的。举个具体的例子,假如你的代码有大量的if else
那么怎么维护?怎么优化?比如一屏幕的If else,看着头疼,我自己写的我也不一定记得清楚,要是别人写的心里肯定骂,什么垃圾啊,这么多。然后我就想办法优化它,首先想到的是switch case,然后加上设计模式的策略模式,这天然就可以消灭if else,比如
switch type
case type1
return new Service1
用简单工厂封个策略包,然后想想有什么更好的办法,能不能不用switch case,因为这个也得看也得费脑子,而网上的太麻烦了,于是用了@postconsturct加上枚举就完事了,简单明了
第一步
写枚举,里面就是大量的逻辑分支,比如我的工单里面有充值工单,修改时间工单,重置密码工单
public enum Type {
CHARGE(true), UPDATE_DURATION(true), SUSPEND(true), RESET_PASSWORD(false), ENABLE(true);
boolean needApprove;
Type(boolean needApprove) {
this.needApprove = needApprove;
}
public boolean isNeedApprove() {
return needApprove;
}
}
第二步
利用java8的行为参数化
@FunctionalInterface
public interface WorkOrderProvider {
Map<WorkOrder.Type, Function<CreateWorkOrderRequest, WorkOrder>> _PROVIDER = new ConcurrentHashMap<>();
WorkOrder create(CreateWorkOrderRequest request);
static WorkOrderProvider provider(WorkOrder.Type type) {
Assert.isTrue(_PROVIDER.containsKey(type), "cannot find provider for type: " + type.name());
return _PROVIDER.get(type)::apply;
}
static void register(WorkOrder.Type type, Function<CreateWorkOrderRequest, WorkOrder> provider) {
_PROVIDER.putIfAbsent(type, provider);
}
}
我的入参是CreateWorkOrderRequest,出参是WorkOrder,那么我就定义一个function,当执行::apply的时候就会执行
WorkOrder workOrder = WorkOrderProvider.provider(request.getType()).create(request);
第三步 执行逻辑
@PostConstruct
public void postConstruct() {
WorkOrderProvider.register(WorkOrder.Type.CHARGE, this::createWorkOrder);
}
public WorkOrder createWorkOrder(CreateWorkOrderRequest request) {.....}
用postConstruct目的是把这个枚举类型注入到spring工厂,这样springboot启动的时候就可以把这个类型注入,然后找到相应的方法。
这样就符合设计模式里面的对外开放修改,对内封闭的原则,如果有新的类型,我只要在枚举里加上enum,然后对应的逻辑用postconstruct挂上就好了。
这块我要说明下其实是java8以后的行为参数化,所有的行为都是根据传入的参数决定的,WorkOrderProvider.register(WorkOrder.Type.CHARGE, this::createWorkOrder);
用枚举CHARGE,那么就是充值的逻辑,如果用SUSPEND,那么就走暂停账号的逻辑,最好再写一个service类。