小談實踐封裝與多態

梳理

最近在重構一段代碼,發現之前的流程大概是如下圖,這樣的設計結構。

1_20141009110611.jpg

一、這是一個發送消息的流程,長長的一段代碼,通過依賴構成整個流程的架構。整個流程依賴三個環節:適配、發送、保存,其中發送又依賴消息體生成。

二、由於消息類型不同,適配、發送、保存的具體實現不同,所以代碼中大量的充斥着if ... else ...的判斷語句。

這不僅導致代碼可讀性很差,而且還產生了大量冗餘代碼。

重構

針對如上問題,首先是通過組合的方式重新封裝。

1_20141009111610.jpg

一、提取一個更高的抽象(Mesasge),這裏組合了Sender和Saver兩個行爲,這裏只組合行爲,不組合實現。

這樣的好處,是外觀代碼變得更加清晰,如下面代碼:

Message message = adapterService.adapter(jsonMessage);
message.getSender().send();
message.getSaver().save();

之前和同事討論這裏,很形象的比如成,Sender像一張弓,Message像一支箭,getSender()可以獲取不同的弓,Message也可以是不同的箭,通過不同的實現隨意組合。

二、這裏以服務號消息(ServiceNoMessage)爲例,SamplerMessage是Message的一種具體實現,其中SamplerSender和SamplerSaver分別是Sender和Saver的具體實現。

通過組合的方式,就可以在不改變外觀行爲的框架下,構造針對不同特定的具體實現。

1_20141009113721.jpg

抽象封裝Message,以及組合Sender和Saver可以參見如下代碼:

public class SamplerMessage implements Message {
 
    private Sender sender;
    private Saver saver;
 
    private String jsonMessage;
 
    private MessageSenderService messageSenderService;
    private MessageBodyService messageBodyService;
 
    public SamplerMessage(String jsonMessage, MessageSenderService messageSenderService, MessageBodyService messageBodyService) {
        this.jsonMessage= jsonMessage;
        // 封裝service到Message
        this.messageSenderService = messageSenderService;
        this.messageBodyService= messageBodyService;
    }
 
    public Sender getSender() throws Exception {
        sender = new SamplerSender(jsonMessage, messageSenderService, messageBodyService);
        return sender;
    }
 
    public Saver getSaver() {
        saver = new SamplerSaver(jsonMessage);
        return saver;
    }
}

優化

在重構中,提取一些共性的行爲和屬性,通過繼承,在子類封裝每個特性的行爲和屬性。

在實現MessageBodyService服務時,發現不同實現中,有着很多共性的一些,所以通過抽象類的方式,封裝共性的,在具體的實現中,封裝特性的。

以MessageBodyService爲例,不同的實現都會調用初始init()方法,但是generate()會有所不同,如下圖:

1_20141009105427.jpg

AbsMessageBodyService的抽象實現如下:

public abstract class AbsMessageBodyService implements MessageBodyService {
    
    public void init() throws Exception {
        ...
        generate();
        ...
    }
 
    protected abstract void generate() throws Exception;
}

ServiceNoMessageBodyServiceImpl的具體實現:

public class ServiceNoMessageBodyServiceImpl extends AbsMessageBodyService {
 
    protected String generate() throws Exception {
        ...
    }
}

MessageBody的調用:

public class SamplerMessageBody implements MessageBody {
 
    private MessageBodyService messageBodyService;
 
    public SamplerMessageBody() throws Exception {
        this.messageBodyService= new ServiceNoMessageBodyServiceImpl();
 
        initMessageBody();
    }
 
    private void initMessageBody() throws Exception {
        messageBodyService.init();
    }
}

—————————— 本文同步發佈於 ZHANGSR 我的個人博客  ——————————



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章