小谈实践封装与多态

梳理

最近在重构一段代码,发现之前的流程大概是如下图,这样的设计结构。

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 我的个人博客  ——————————



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