责任链模式平常没怎么用过,今天看到了责任链模式的基本构成。大体就是把一件事情分给n个互相有引用的类去执行。比如解析ip地址。过程如图:
package com.cn.test;
import java.util.Random;
/**
* Created by user on 2015/9/17.
*/
public abstract class DnsServer {
private DnsServer upper;
public final Recorder resolver(String domain){
Recorder recorder=null;
if(isLocal(domain)){
recorder=echo(domain);
}else {
recorder=upper.resolver(domain);
}
return recorder;
}
public void setUpperServer(DnsServer _upperServer){
this.upper=_upperServer;
}
protected abstract boolean isLocal(String domain);
protected Recorder echo(String domain){
Recorder recorder=new Recorder();
recorder.setIp(getIpAddress());
recorder.setDomain(domain);
return recorder;
}
private String getIpAddress(){
Random random =new Random();
String address=random.nextInt(255)+"."+random.nextInt(255)+"."+random.nextInt(255)+"."+random.nextInt(255);
return address;
}
}
package com.cn.test;
/**
* Created by user on 2015/9/17.
*/
public class SHDnsServer extends DnsServer {
@Override
protected boolean isLocal(String domain) {
return domain.endsWith(".sh.cn");
}
protected Recorder echo(String domain){
Recorder recorder=super.echo(domain);
recorder.setOwner("上海服务器");
recorder.setDomain(domain);
return recorder;
}
}
package com.cn.test;
/**
* Created by user on 2015/9/17.
*/
public class ChinaTopDnsServer extends DnsServer {
@Override
protected boolean isLocal(String domain) {
return domain.endsWith(".cn");
}
protected Recorder echo(String domain){
Recorder recorder=super.echo(domain);
recorder.setOwner("中国服务器");
recorder.setDomain(domain);
return recorder;
}
}
package com.cn.test;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* Created by user on 2015/9/17.
*/
public class TopDnsServer extends DnsServer {
@Override
protected boolean isLocal(String domain) {
return domain.endsWith(".cn");
}
protected Recorder echo(String domain){
Recorder recorder=super.echo(domain);
recorder.setOwner("定级服务器");
recorder.setDomain(domain);
return recorder;
}
public static void main(String[] args) throws Exception{
DnsServer shdnsServer = new SHDnsServer();
DnsServer chinaServer =new ChinaTopDnsServer();
DnsServer topDnsServer =new TopDnsServer();
chinaServer.setUpperServer(topDnsServer);
shdnsServer.setUpperServer(chinaServer);
System.out.println("解析过程开始---------------");
while(true){
System.out.println("\n输入域名,n退出");
String domain =(new BufferedReader(new InputStreamReader(System.in))).readLine();
if(domain.equalsIgnoreCase("n")){
return;
}else{
Recorder recorder=shdnsServer.resolver(domain);
System.out.println("解析结果------------");
System.out.println(recorder);
}
}
}
}
结果:
解析过程开始---------------
输入域名,n退出
www.baidu.cn
解析结果------------
域名:www.baidu.cn
IP地址:217.131.195.29
解析者:中国服务器
输入域名,n退出
www.baidu.sh.cn
解析结果------------
域名:www.baidu.sh.cn
IP地址:91.109.63.60
解析者:上海服务器
输入域名,n退出
n
观察者模式可以和责任链模式结合,这种结合的好处就是能够屏蔽一些责任链的细节,把责任链的低端(上海服务器)给观察者,那么责任就沿着链一直上传解决。
package com.cn.test;
import java.util.Observable;
import java.util.Observer;
import java.util.Random;
/**
* Created by user on 2015/9/17.
*/
public abstract class DnsServerObserver extends Observable implements Observer{
public void update(Observable arg0,Object arg1){
Recorder recorder=(Recorder)arg1;
if(isLocal(recorder)){
recorder.setIp(getIpAddress());
}else{
responseFromUpperServer(recorder);
}
sign(recorder);
}
protected abstract void sign(Recorder recorder);
public void setUpperServer(DnsServerObserver dnsServer){
super.deleteObservers();
super.addObserver(dnsServer);
}
private void responseFromUpperServer(Recorder recorder){
super.setChanged();;
super.notifyObservers(recorder);
}
protected abstract boolean isLocal(Recorder domain);
protected Recorder echo(String domain){
Recorder recorder=new Recorder();
recorder.setIp(getIpAddress());
recorder.setDomain(domain);
return recorder;
}
private String getIpAddress(){
Random random =new Random();
String address=random.nextInt(255)+"."+random.nextInt(255)+"."+random.nextInt(255)+"."+random.nextInt(255);
return address;
}
}
package com.cn.test;
/**
* Created by user on 2015/9/17.
*/
public class SHDnsServer1 extends DnsServerObserver {
@Override
protected void sign(Recorder recorder) {
recorder.setOwner("上海服务器");
}
@Override
protected boolean isLocal(Recorder domain) {
return domain.getDomain().endsWith(".sh.cn");
}
}
package com.cn.test;
/**
* Created by user on 2015/9/17.
*/
public class ChinaTopDnsServer1 extends DnsServerObserver {
@Override
protected void sign(Recorder recorder) {
recorder.setOwner("中国服务器");
}
@Override
protected boolean isLocal(Recorder domain) {
return domain.getDomain().endsWith(".cn");
}
}
package com.cn.test;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* Created by user on 2015/9/17.
*/
public class TopDnsServer1 extends DnsServerObserver {
@Override
protected void sign(Recorder recorder) {
recorder.setOwner("定级服务器");
}
@Override
protected boolean isLocal(Recorder domain) {
return true;
}
public static void main(String[] args) throws Exception{
DnsServerObserver shdnsServer = new SHDnsServer1();
DnsServerObserver chinaServer =new ChinaTopDnsServer1();
DnsServerObserver topDnsServer =new TopDnsServer1();
chinaServer.setUpperServer(topDnsServer);
shdnsServer.setUpperServer(chinaServer);
System.out.println("解析过程开始---------------");
while(true){
System.out.println("\n输入域名,n退出");
String domain =(new BufferedReader(new InputStreamReader(System.in))).readLine();
if(domain.equalsIgnoreCase("n")){
return;
}else{
/* Recorder recorder=shdnsServer.resolver(domain);*/
Recorder recorder =new Recorder();
recorder.setDomain(domain);
shdnsServer.update(null,recorder);
System.out.println("解析结果------------");
System.out.println(recorder);
}
}
}
}
该模式的缺陷就是不会知道具体的哪个服务器解析了域名,只返回时上海服务器解析了域名(因为上海服务器作为了观察者去处理请求)。