Java代理模式(静态代理)

代理模式是通过创建一个代理对象,使用这个代理对象代替实际对象。对于客户端而言,得到代理对象于操作而言没有任何影响。

当客户端操作代理对象时,实际上操作会由实际对象完成。即客户端操作代理对象,代理对象操作实际对象,而代理对象在操作实际对象时,可以添加额外的操作实现懒加载,权限限定等一系列额外操作。

代理分类:

1、  虚代理:根据需要创建开销很大的对象,而该对象只有在真正需要的时候才会被真正创建。实际应用------懒加载。

2、  远程代理:用来在不同的地址空间表示同一个对象。实际应用------RMI技术

3、  Copy-on-wirte:只有当对象确实改变了,才会拷贝一个目标对象。

4、  保护代理:控制对原始对象的访问。


下文则从最简单的静态代理开始讲解java中的代理模式:

以生活中销售手机为例,厂家生产手机,经销商从厂家拿货销售给客户。而在这个过程中,经销商就是厂家的代理。可以在厂家销售过程中增加一系列加价,满减等活动。而针对客户,买手机这一操作并没有因为是从经销商处购买收到影响。而经销商也是在厂家销售的基础上增加其他活动,完成整个代理。


代码实例:

1、公用接口

public interface SellProduct {

	public int SellPhone(String phoneName);
}

2、实际对象厂家():

public class Producer implements SellProduct{


	/**
	 * 模拟厂家定价
	 */
	@Override
	public int SellPhone(String phoneName) {
		// TODO Auto-generated method stub
		int price = 0;
		switch (phoneName) {
		case "iphone":
			price = 6000;
			break;
		case "mi":
			price = 2499;
		default:
			break;	
		}
		System.out.println("销售手机:"+phoneName+",价格:"+price);
		return price;
	}

}

3、代理对象(经销商):

public class Dealer implements SellProduct{

	private Producer producer;
	
	public Dealer(Producer producer) {
		this.producer = producer;
	}
	/**
	 * 经销商不需要知道厂家如何定价,只要在出厂价基础上加价即可
	 */
	@Override
	public int SellPhone(String phoneName) {
		int price = producer.SellPhone(phoneName)+200;	
		System.out.println("销售手机:"+phoneName+",价格:"+price);
		return price;
	}

}

4、客户:

public class Client {

	public static void main(String []args){

		SellProduct sell = new Dealer(new Producer());
		sell.SellPhone("iphone");
	}
}

运行结果:

销售手机:iphone,价格:6200

以下介绍两种其他常用的代理模式:

一:虚代理(实际运用与懒加载):

在数据库中,往往需要一个对象有很多个属性,而一次性加载所有属性是对内存的极大浪费。如果我们第一次只查询必要的数据,而其他数据等到需要时再查询,无疑会大大减小内存的消耗。

1、接口:

public interface UserModel {

	public int getId();
	
	public void setId(int id);
	
	public String getName();
	
	public void setName(String name);
}

2、实际对象:

public class UserModelImpl implements UserModel {

	private int id;
	private String name;

	@Override
	public int getId() {
		// TODO Auto-generated method stub
		return id;
	}

	@Override
	public void setId(int id) {
		// TODO Auto-generated method stub
		this.id = id;
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return name;
	}

	@Override
	public void setName(String name) {
		this.name = name;

	}

}


3、代理对象:

public class ProxyModel implements UserModel{

	private UserModelImpl userModel;
	
	private boolean isLoad = false;
	
	public ProxyModel(UserModelImpl userModel){
		this.userModel = userModel;
	}

	@Override
	public int getId() {
		// TODO Auto-generated method stub
		return userModel.getId();
	}

	@Override
	public void setId(int id) {
		// TODO Auto-generated method stub
		userModel.setId(id);
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		if(!this.isLoad){
			reload();
			this.isLoad = true;
		}
		return userModel.getName();
	}

	@Override
	public void setName(String name) {
		// TODO Auto-generated method stub
		userModel.setName(name);
	}
	/**
	 * 重新从数据库中获取name注入实际对象
	 */
	private void reload(){
		String name = getNameFromSQL();
		System.out.println("重新从数据库加载数据");
		userModel.setName(name);
	}
	/**
	 * 模拟从数据库获取name操作
	 * @return
	 */
	private String getNameFromSQL(){
		return "simulation";
	}
}

4、客户使用:

public class Client {

	/**
	 * 模拟从数据库中查询,因为不需要知道其他属性,只注入id即可
	 * @param usermodel
	 */
	private static void SQLQuery(UserModel usermodel){
		
		usermodel.setId(1);
	}
	
	public static void main(String []args){
		ProxyModel proxy = new ProxyModel(new UserModelImpl());
		SQLQuery(proxy);
		System.out.println("id:"+proxy.getId());
		System.out.println("name:"+proxy.getName());
	}
}

运行结果:
id:1
重新从数据库加载数据
simulation


二 保护代理:

控制原始对象访问的代理。

1、接口:

public interface OAOperate {

	
	public void add();
	
	public void select();
	
	public void delete();
}

2、原始对象:

public class OAOperater implements OAOperate{

	private String name;
	
	private int flag;
	
	public OAOperater(String name,int flag) {
		this.name = name;
		this.flag = flag;
	}
	
	public int getFlag(){
		return this.flag;
	}
	
	@Override
	public void add() {
		//省略相应操作
	}

	@Override
	public void select() {
		//省略相应操作
	}

	/**
	 * delete需要权限设置
	 */
	@Override
	public void delete() {
		//省略相应操作
		System.out.println("删除操作");
	}

}

3、代理对象:

public class OAProxy implements OAOperate {

	private OAOperater operate;

	public OAProxy(OAOperater operate) {
		this.operate = operate;
	}

	@Override
	public void add() {
		// TODO Auto-generated method stub

	}

	@Override
	public void select() {
		// TODO Auto-generated method stub

	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		if (operate.getFlag() != 4) {
			System.out.println("权限不足,不能修改");
		} else {
			operate.delete();
		}

	}

}

4、客户:

public class Client {

	public static void main(String []args){
		OAOperate operate = new OAProxy(new OAOperater("xiaoming", 3));
		operate.delete();
		
		OAOperate operater = new OAProxy(new OAOperater("paditang", 4));
		operater.delete();
	}
}

运行结果:

权限不足,不能修改
删除操作




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值