服务提供者框架

//服务接口
public interface Service {
	public void move();
}
public class Train implements Service{
	public void move(){
		System.out.println(this.getClass().getName().substring(this.getClass().getName().lastIndexOf(".")+1)+" can run.");
	}

}
public class Plane implements Service {
	public void move(){
		System.out.println(this.getClass().getName().substring(this.getClass().getName().lastIndexOf(".")+1)+" can fly.");
	}

}
//服务提供者接口
public interface Provider {
	Service newService();
}
public class TrainProvider implements Provider{
	@Override
	public Service newService() {
		return new Train();
	}
}
public class PlaneProvider implements Provider {
	@Override
	public Service newService() {
		return new Plane();
	}
}

public class Services {

	private Services(){}		//私有化构造函数,禁止创建Services的实例
	
	//用Map存储service及其对应的名称
	private static final Map<String,Provider> providers=
			new ConcurrentHashMap<String,Provider>();
	public static final String DEFALUT_PROVIDER ="<def>";
	
	//注册provider的API
	public static void registerDefaultProvider(Provider p){
		registerProvider(DEFALUT_PROVIDER,p);
	}
	public static void registerProvider(String name,Provider p){
		providers.put(name, p);
	}
	
	//获取service的API
	public static Service newInstance(){
		return newInstance(DEFALUT_PROVIDER);
	}
	public static Service newInstance(String name){
		Provider p=providers.get(name);
		if(p==null)
			throw new IllegalArgumentException("No provider registered with name: "+name);
		return p.newService();
	}
}

//客户程序
public class Client {

	public static void main(String[] args){
		//创建服务提供者
		Provider p1=new TrainProvider();
		Provider p2=new PlaneProvider();
		//注册服务
		Services.registerProvider("train", p1);
		Services.registerProvider("plane", p2);
		//获取服务
		Service s1=Services.newInstance("train");
		Service s2=Services.newInstance("plane");
		//使用服务
		s1.move();
		s2.move();
	}
}


服务提供者接口(Service Provider Interface)可以不要,这个时候可以按照类名来注册服务,并且通过反射的方法对服务进行实例化。

public class Services {
	private Services(){}
	
	private static final Set<String> services=
			new LinkedHashSet<String>();
	public static final String DEFAULT_SERVICE_NAME="<def>";
	
	//注册服务的API
	public static void registerDefaultService(){
		registerService(DEFAULT_SERVICE_NAME);
	}
	public static void registerService(String name){
		services.add(name);
	}
	
	//获取服务的API
	public static Service newInstance(){
		return newInstance(DEFAULT_SERVICE_NAME);
	}
	public static Service newInstance(String name){
		if(!services.contains(name))
			throw new IllegalArgumentException("No provider registered with name: "+name);
		Service s=null;
		try{
			String package_path=Services.class.getName().substring(0,Services.class.getName().lastIndexOf(".")+1);
			s=(Service)Class.forName(package_path+name).newInstance();
		}catch(ClassNotFoundException e1){
			System.err.println("class not found.");
			System.exit(1);
		}catch(IllegalAccessException e2){
			System.err.println("class not accessible.");
			System.exit(1);
		}catch(InstantiationException e3){
			System.err.println("class not instantiable.");
			System.exit(1);
		}
		return s;
	}
}

public class Client {
	public static void main(String[] args){
		//注册服务
		Services.registerService("Train");
		Services.registerService("Plane");
		//获取服务
		Service s1=Services.newInstance("Train");
		Service s2=Services.newInstance("Plane");
		//使用服务
		s1.move();
		s2.move();
	}
}

使用反射有3个缺点:

  1. 丧失了编译时类型检查的好处。上例中会产生3个运行时错误,如果不使用反射,这3个错误都会成不编译时错误。
  2. 代码冗长。由于要catch运行时错误,代码变得冗长。
  3. 性能损失。反射方法比普通方法的调用慢许多。
System.exit很少使用,它会终止整个VM,但是它对于命令行有效性的非法终止是很合适的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值