50行代码实现简单网站服务器 1
在上一讲我们介绍了如何利用java语言只用50行代码就可以实现一个简单的网站服务器,该服务器的功能是当我们在浏览器的地址栏输入localhost:8080的时候,我们会看到"hello, this is my web server!"。如下:
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讲的基础上,提出了一个新的需求,通过不断的分析问题和解决问题,发现最新提出的方案还是不能很好的解决问题。如需了解更多,欢迎持续关注微信公众号“算法与编程之美”,获得更好的阅读体验。