场景:
保存数据多种表单时,数据库抽取了共性为表 base_biz差异分别保存自己表中如下图:
A_self_biz、B_self_biz、C_self_biz 自身业务表。
java程序使用模板模式开发,定义公共算法,和差异算法。
但是此时在模板中的公共算法即保存数据到 base_biz 时需要spring注入 baseDao。习惯了注解懒得一逼,就是不想用xml。但是抽象父类没有注入spring自然引用不了baseDao。傻人想傻办法。在子类中注入baseDao让抽象父类使用。
模板方法:具体细节不在此展示
public abstract class AbstractServiceTemplate { BaseBizService baseBizService; BaseConfigService baseConfigService; OperationLogService operationLogService; /** ** 方法说明 : 子类通过重写本方法为抽象类注入 *
*/ protected abstract void setTemplateRef( BaseBizService baseBizService, BaseConfigService baseConfigService, OperationLogService operationLogService); /** * 方法说明 : 保存表所共同遵循的算法框架 */ public final void save(BizTable bt, Object selfBt) { // 业务逻辑验证工单数据 verifyBase(bt, selfBt); // 保存公共业务并获取公共保存的id Integer code = saveBaseBiz(bt); // 保存自身 if (isNeedSaveSelf()) { saveSelf(code, selfBt); } // 保存操作日志 operationLogService(wo); }}
子类继承父类并注入值: (特别注意:这里破坏了:Dependence Inversion Principle:依赖倒置原则
依赖倒置原则在java语言中的体现:
①模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;
②接口或抽象类不依赖于实现类;
③实现类依赖接口或抽象类。
使用原则:
依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独立,不互相影响,实现模块间的松耦合,我们怎么在项目中使用这个规则呢?只要遵循以下的几个规则就可以:
①每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备
②变量的表面类型尽量是接口或者是抽象类
③任何类都不应该从具体类派生(只要不超过两层的继承是可以忍受的)
④尽量不要复写基类的方法
⑤结合里氏替换原则使用
)
/** ** ItemsRecoveredSaveService描述 : ASelfService *
* * @author lienbo * @since 0.0.1 */@Service("aSelfService")public class ASelfService extends AbstractServiceTemplate { @Autowired BaseBizService baseBizService; @Autowired BaseConfigService baseConfigService; @Autowired OperationLogService operationLogService; /** * 方法说明 : 子类通过重写本方法为抽象类注入 */ @Autowired @Override protected void setTemplateRef( BaseBizService baseBizService, BaseConfigService baseConfigService, OperationLogService operationLogService) { super.baseBizService = baseBizService; super.baseConfigService = baseConfigService; super.operationLogService = operationLogService; }}
所以我改了这部分代码。在抽象父类注入。
另外:这种依赖关系,对多个表进行操作事务一定记得事务控制。
在分层数量上我遵循了 controller 对表单进行验证,处理数据格式。
在service层使用模板控制各个业务的逻辑。很多的是用了抛出自定义异常处理业务逻辑。
改进后:
public abstract class AbstractWorkOrderServiceTemplate { BaseBizService baseBizService; BaseConfigService baseConfigService; OperationLogService operationLogService; /** * 方法说明 : 父类注入 */ @Autowired public void setTemplateRef(BaseBizService baseBizService,BaseConfigService baseConfigService,OperationLogService operationLogService) { this.baseBizService= baseBizService; this.baseConfigService= baseConfigService; this.operationLogService= operationLogService; }}