面向介面程式設計-應用審批
阿新 • • 發佈:2022-05-08
需求如上,上次已經 使用策略模式 和工廠將審批的動作實現了:
public enum AuditActionEnum {
commit("commit", "提交稽核"),
approvePass("approvePass", "稽核通過"),
approveReject("approveReject", "稽核拒絕");
private String key;
private String desc;
AuditActionEnum(String key, String desc) {
this.key = key;
this.desc = desc;
}
public String getKey() {
return this.key;
}
public String getDesc() {
return this.desc;
}
public static AuditActionEnum match(String key) {
for (AuditActionEnum e : AuditActionEnum.values()) {
if (e.getKey().equals(key)) {
return e;
}
}
return null;
}
}
@Component
public interface IAuditStrategy {
void doAction(IService service , Long id , AuditCommitResDto auditCommitResDto);
}
具體實現子類:
@Component("commit")
public class CommitAuditStrategy implements IAuditStrategy {
@Override
public void doAction(IService service, Long id, AuditCommitResDto auditCommitResDto) {
service.update(new UpdateWrapper<>()
.set("audit_id", auditCommitResDto.getAuditId())
.set("commit_time", auditCommitResDto.getCommitTime())
.set("audit_state", auditCommitResDto.getAuditState())
.eq("id", id)
);
}
}
@Component("approvePass")
public class ApprovePassAuditStrategy implements IAuditStrategy {
@Override
public void doAction(IService service, Long id, AuditCommitResDto auditCommitResDto) {
//稽核通過先把之前資料失效 ,在把通過的這條生效
service.update(new UpdateWrapper<>()
.set("is_effective", EffectMasterEnum.effect.getKey())
.eq("master_id", id)
);
service.update(new UpdateWrapper<>()
.set("is_effective", EffectMasterEnum.effect.getKey())
.set("audit_time", auditCommitResDto.getAuditTime())
.set("audit_state", auditCommitResDto.getAuditState())
.eq("id", id)
);
}
}
再仔細看看,發現其實做的事情都是同樣的:即 對
is_effective 生效
audit_time 審批時間
audit_state 審批狀態
這三個欄位進行更新。
例子:假如對商品進行審批 (用 @Data 省略了 set get 方法)
@Data
ProductEntity {
id
productName
isEffective
auditTime
auditState
}
對銷量進行審批:
@Data
SellEntity {
id
count
isEffective
auditTime
auditState
}
通過觀察不難發現 :只要 需要進行審批 就必須 有
is_effective 生效
audit_time 審批時間
audit_state 審批狀態
這三個欄位,於是想通過 將三個欄位提取出來為一個類:
@Data
AuditEntity {
isEffective
auditTime
auditState
}
@Data
ProductEntity extends AuditEntity {
id
productName
}
對銷量進行審批:
@Data
SellEntity extends AuditEntity
{
id
count
}
然後 對策略開始修改:
@Component("commit")
public class CommitAuditStrategy implements IAuditStrategy {
@Override
public void doAction(Audit audit , AuditCommitResDto auditCommitResDto) {
audit.setAuditTime(auditCommitResDto.getCommitTime())
audit.setAuditState(auditCommitResDto.getAuditState())
);
}
}
呼叫:
如果是商品審批
ProductEntity product = new ProductEntity
auditCommitResDto = 調介面返回
auditStrategyMap.get(dto.getAuditAction()).doAction(product ,auditCommitResDto);
this.update (product )
SellEntity sell= new SellEntity
auditCommitResDto = 調介面返回
auditStrategyMap.get(dto.getAuditAction()).doAction(sell,auditCommitResDto);
this.update (sell)
到這裡看起就已經將需求實現了,但仍然有問題。 使用 繼承不易於拓展 ,並且entity,java 中不允許使用多繼承,所以組長希望叫我改成介面方式,於是改將audit 改成介面:
interface IAuditEntity {
void setIsEffective(Integer isEffective);
void setAuditState(String auditState);
void setAuditTime(Date auditTime);
}
@Data
ProductEntity implements IAuditEntity {
id
productName
isEffective
auditTime
auditState
}
對銷量進行審批:
@Data
SellEntity implements IAuditEntity {
id
count
isEffective
auditTime
auditState
}
然後 對策略開始修改:
@Component("commit")
public class CommitAuditStrategy implements IAuditStrategy {
@Override
public void doAction(IAuditEntity audit , AuditCommitResDto auditCommitResDto) {
audit.setAuditTime(auditCommitResDto.getCommitTime())
audit.setAuditState(auditCommitResDto.getAuditState())
);
}
}
呼叫:
如果是商品審批
ProductEntity product = new ProductEntity
auditCommitResDto = 調介面返回
auditStrategyMap.get(dto.getAuditAction()).doAction(product ,auditCommitResDto);
this.update (product )
SellEntity sell= new SellEntity
auditCommitResDto = 調介面返回
auditStrategyMap.get(dto.getAuditAction()).doAction(sell,auditCommitResDto);
this.update (sell)
用介面 還有一個好處,其一是介面可以多實現 ,更易於拓展。其二 只要涉及審批相關的實體,倒逼著開發一定要有審批相關的幾個欄位。(因為entity 用mybatits plus 綁定了資料庫表字段 所以表設計的時候就不會漏欄位)
這時才想起來 介面的意義:定義規範。 並且這體現java語言的多型,
IAuditEntity product= new ProductEntity
IAuditEntity product= new SellEntity
這裡和 List list = new ArrayList() List list = new LinkList() 一樣。