在上一讲我们针对需求提出了一种新的解决方案,经过分析我们发现这种方法虽然在某种程度上改善了代码的结构,但是本质上只是一种任务的转移,并未解决问题。本讲我们将提出一种新的解决方案。
1 问题描述
对于之前的网站服务器,我们想要在启动之前打印"some operations before server start!",在服务器销毁之前打印"some operations before server destroy!"。
2 问题分析
上一讲提出的解决方案本质问题在于需求改变时,需要不停的去修改WebServerAction类,这严重的违反了开闭原则。
我们希望达到的效果是,当需求改变时,我们希望实现现有的接口或继承现有的类或增加新的类来达到目的。
为了实现该目标,我们提出下面新的解决方案。
1) 设计新的接口ServerListener,该接口具有两个方法,分别是服务器启动和销毁时对应的操作。
public interface ServerListener {
public void start();
public void destroy();
}
2)第一个需求来临时,实现该接口。
public class OneServerListener implements ServerListener {
@Override
public void start() {
System.out.println("> This is operation 1 before server start!");
}
@Override
public void destroy() {
System.out.println("> This is operation 1 before server destroy!");
}
}
3)WebServer增加成员变量List<ServerListener>,并做初始化操作。
privateList<ServerListener> serverListenerList;
WebServer() throws IOException {
serverSocket = newServerSocket(WebConfig.SERVER_PORT);
serverListenerList= new ArrayList<ServerListener>();
}
4) run方法开始和结束前,执行所有实现了ServerListener接口的方法。
public void run() throwsIOException {
for (ServerListener listener : serverListenerList)
listener.start();
// ...
for (ServerListener listener:serverListenerList)
listener.destroy();
}
5) 初始化WebServer时,添加所有的ServerListener。
WebServer webServer = new WebServer();
webServer.addListener(newOneServerListener());
webServer.run();
6) 当有新的需求时,我们需要做的工作是:
- 实现ServerListener接口,完成新的需求;
- webserver初始化的时候,调用addListener方法。
3 总结
本讲针对上一讲提出的问题,经过细致分析,发现问题并提出了一种新的解决方案,该方案能够较好的应对需求的变化,符合面向对象的设计原则-开闭原则。为了更好的适应需求变化,后面我们可以将listener的信息在配置文件中进行配置。