50行代码实现简单的网站服务器 2

50行代码实现简单网站服务器 1 https://my.oschina.net/gschen/blog/853408

在上一讲我们介绍了如何利用java语言只用50行代码就可以实现一个简单的网站服务器,该服务器的功能是当我们在浏览器的地址栏输入localhost:8080的时候,我们会看到"hello, this is my web server!"。如下:

50行代码实现简单的网站服务器 2

本讲我们将介绍在此基础上,添加新的功能。

1问题描述

对于上述的网站服务器,我们想要在启动之前打印"some operations before server start!",在服务器销毁之前打印"some operations before server destroy!"。

2问题分析

通过对需求的分析,我们发现该需求就是在网站服务器启动前执行某些操作,在服务器销毁前再执行某些操作。初步感觉不是很难实现。

网站服务器的核心代码在run方法内,如下所示:

public void run() throws IOException {

Socket socket = serverSocket.accept();

PrintWriter writer = null;

BufferedReader reader = null;

try {

// 处理http请求

reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

String line = null;

while (!(line = reader.readLine()).equals("")) {

System.out.println(line);

}

// 返回http响应

writer = new PrintWriter(socket.getOutputStream());

writer.print("HTTP/1.1 200 OK\r\n");

writer.print("\r\n");

writer.print("hello,this is my web server!");

writer.flush();

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

socket.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

该代码主要包含两部分,一是处理http请求,二是处理http响应。

故为了实现项目需求,我们能够想到的最直接的方法便是:

public void run() throws IOException {

System.out.println("some operations before server start!");

//省略核心代码

System.out.println("some operations before server destroy!");

}

在核心代码之前和之后分别加上我们需要执行的代码,如红色字体所示。

该方法确实能够满足需求解决问题,但是假如我的需求是这样呢。

public void run() throws IOException {

System.out.println("operation 1 before server start!");

System.out.println("operation 2 before server start!");

//...

System.out.println("operation N before server start!");

// 核心代码部分省略

System.out.println("operation1 before server destroy!");

System.out.println("operation2 before server destroy!");

// ...

System.out.println("operationN before server destroy!");

}

你会发现,随着需求的不断变更,你需要不断的在WebServer中加入新的代码,随着新的代码的不断加入,你会发现WebServer类出现bug的概率将会逐渐升高,另外这也严重违反了面向对象的重要设计原则 --开闭原则。

如何解决该问题?我们将初始化和销毁的操作分别封装在一个类的两个方法里面,因此引入了一个新的类叫WebServerAction,如下:

public class WebServerAction {

public void start(){

System.out.println("operation 1 before server start!");

System.out.println("operation 2 before server start!");

//...

System.out.println("operation N before server start!");

}

public void destroy(){

System.out.println("operation1 before server destroy!");

System.out.println("operation2 before server destroy!");

// ...

System.out.println("operationN before server destroy!");

}

}

有了这个类之后,WebServer类就可以进行下面的修改:

public class WebServer {

private ServerSocket serverSocket;

private WebServerAction webServerAction; //将新的类作为私有变量

WebServer() throws IOException {

serverSocket = new ServerSocket(WebConfig.SERVER_PORT);

webServerAction = new WebServerAction();//初始化

}

public void run() throws IOException {

webServerAction.start();//执行服务器启动初始化工作

//省略核心代码

webServerAction.destroy();//执行服务器销毁工作

}

//...

}

经过上面的修改之后,你会发现今后有新的初始化和销毁需求,我们都不用再修改WebServer核心类,而是在WebServerAction类的两个方法中实现需求。

引入WebServerAction类,在一定程度上改善了代码结构,使代码整体上更可读。但是细心的你会发现,这只不过是一种任务的转移而已。以前需求的变化,你需要不停的修改WebServer类,而现在你是不停的修改WebServerAction类,所以其本质并未改变。

针对此问题,你有什么好的解决思路呢?欢迎留言交流,也欢迎继续关注后续文章。

3总结

本文在第1讲的基础上,提出了一个新的需求,通过不断的分析问题和解决问题,发现最新提出的方案还是不能很好的解决问题。如需了解更多,欢迎持续关注微信公众号“算法与编程之美”,获得更好的阅读体验。

50行代码实现简单的网站服务器 2

上一篇:Java happens-before


下一篇:前端基础HTML---伪元素(:before与:after的运用)