3.对象去耦-代理模式(Proxy)+状态模式(State)+迭代器(Iterator )

3.对象去耦-代理模式(Proxy)+状态模式(State)+迭代器(Iterator )

 

 

对象去耦这个东西是一个很有趣的东西,耦合度是指什么,可能是学习得还不够深入吧,因此当我提及这一概念的时候我心虚了一下,不过我的理解是每个对象与每个对象直接是有关系的,而这种关系如何才能让它去到最弱,很多时候我们会使用接口和基类,对于接口和基类的一个很大的作用就是向上转型,这时候关系就会被减弱,所以很多时候我希望做到的是依赖接口编程,而不是依赖类型编程,做一个比喻,依赖类型,就好比你依赖的那个人是你的父母,而依赖接口(或者更加弱化这个关系)就是你爸爸的爸爸的表叔公的弟弟的儿子的老婆的大姨妈的妹妹的女儿(这个应该是远戚了吧),当这个远戚去变了性,但是对你有影响吗。一点影响也没有,但是如果你爸爸妈妈去变了性,那就大影响了.

 

代理模式:

这个我记得之前我写过的一篇文章,组合,继承,代理,这是3种方式去复用你的代码,其中个人使用最多的是组合,而代理的好处是什么,比如说一个太空船需要一个控制模块,当你使用组合,那么这个控制类的所有方法变得难以配置,并且经常是暴露出来的,如果使用继承呢,但是概念上会混淆,(接口实现是可以的)。太空船是控制模块的子类,很奇怪,所以我们这里可以使用一种中庸的办法,代理,代理从字面上可以和明星的代理人比较一下,外面很多工作,代理人帮你选择并接,然后他暴露给你的工作就是只有几个,而你需要做的就是从代理人的手中拿工作做,其他并不需要理解与关心,这种思想我觉得和代理模式是很相似的,从这一点,你就可以感受到有一个代理人的好处了吧。

示例

public class spaceship{

 

private String name;

private SpaceShipControls controls=new SpaceShipControls();

 

public spaceship(String name){

this.name=name;

 

}

 

 

//后退

public void back(int velocity){

controls.back();

}

 

 

 

//前进

public void forward(int velocity){

controls.forward();

}

 

 

....

}

 

 

 

以上就是一个代理类,它可以选择性暴露接口,这是一个很棒的事情,真正需要体验的还是必须要通过实践,我曾经的一个做法就是将代理类改了一下,比如在方法中实现了部分业务逻辑,比如说back(),我会调用controls.back(),但同时我还会加入一下逻辑判断,比如说back的方式,怎么back,还有什么时候back,给不给back现在,这样形成一个back的事务,事务这个词不知道在这里用对不对,不过我觉得这个词真的很精妙,封装性很强,很贴近现实世界的思想.

 

 

 

 

动态代理(Dynamic Proxies):

这是一个很酷的东西,不过在介绍动态代理之前,我们先对代理模式进行改进,代理模式可以看出缺点不少,当添加新的功能,难免必须增加一个代理类,而代理类依赖于controls,对于系统的扩展性是不好的,这时候我们在想,假如类型是我调用这个代理类的时候我才指定的,然后代理类又根据我给的这个类型去调用相应的方法,那不就解决而来上诉的问题的吗,这个思想很好yeah,一开始是依赖代理类的接口类型的,现在变成了代理类依赖我给的类型了,呵呵,不小心就实现了依赖注入(ioc 依赖倒转)的概念。但是假如代理人变成了代理公司会不会更好呢,这样就不需要每个明星都对应一个代理人,我们可以将入职,审批,等一些相同的工作这些围绕着为明星接工作而核心的周围工作统一起来,而变的只是为明星接工作,这样横向一切面。我们就发现我们成了面向方面编程了(aop),这样管理起来更加方便,而且扩展性增强了,明星只需报上自己是演员还是唱歌的还是主持的,代理公司就会动态生成一个代理(代理公司此时对于该明星来说就是对口的代理人了),然后统一一系列的工作为一方面。这样以后添加明星,就不需要增加代理人,也不需要额外的工作,这就是动态代理的好处了(下次要放在实践中感受一下)

示例

//定义一个接口

 

public interface people{

public void fuck();

}

 

 

 

//定义一个man

//被代理的对象

public class man implements people{

@Override

public void fuck(){

System.out.println("yeah!,fuck the ***!");

}

public void eat(){

System.out.println("the more you eat,the more you shit!");

}

}

 

 

 

//定义动态代理

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

/** * the fucking 动态代理类 *

@author shadow * */

public class proxy implements InvocationHandler{

Object target;

public proxy(Object object){ this.target=object;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

// TODO Auto-generated method stub

System.out.println("yeah!,还没fuck");

return method.invoke(target, args);

}

public static Object getInstance(Object obj){

return Proxy.newProxyInstance(

obj.getClass().getClassLoader(),

obj.getClass().getInterfaces(),

new proxy(obj)); } }

 

 

 

//测试

 

 public class test {

public static void main(String[] args){

people people=(people)proxy.getInstance(new man());

people.fuck();

}

}



以上例子很容易理解。就是先看测试类,通过调用动态代理获得了一个被代理对象的实例,然后调用该实例的方法(此时,动态代理会去调用invoke这个方法,根据你刚才获得实例的传入的参数就可以进行发射),然后就会自动选择到被代理对象的方法(可以在invoke上下左右添加事务,这样就可以形成面向方面编程),这样类型依赖就由代理类中转到了客户端去,很多框架是用到动态代理(反射)和依赖注入的概念的,对于我来说,我并不懂j2ee,但是我觉得当你了解了深入这些模式,并在你的项目中使用之后,你写的项目就和他们的框架类似的,这样你学起这些框架来,我相信是游刃有余。毕竟天天百度google不是王道啊。





状态模式(State):
例如,一个人有几种状态,开心,悲伤,感动等,而这些情绪对应这面部表情表现出来,很理所当然我的做法就是定义一个枚举类型(里面有开心,悲伤等.)这样,然后传入state()这个方法,通过swith判断他现在状态,然后调用face()这个方法表现他的表情,这一切好像都理所当然,没有什么问题,但其实这个代码质量并不高,假如判断状态的条件是繁琐的,而且以后要添加新的状态呢,一大堆的东西全部写在一个方法里面,导致这个方法难以维护。这个程度就像硬字印刷和活字印刷的区别如此的明显,使用这里我们引入状态模式这个概念,其实他的好处就为了解决以上的问题
示例

class allstates{

private state s;
public allstates(state s){
this.s=s;
}


public void changestate(state s){
this.s=s;
}

public void say(){
state.face();
}
interface state{
face();
}

private class happy implements state{

face(){
System.out,println(i am happy);
};
}

private class sad implements state{

face(){
System.out,println(i am  sad  );
};
}

private class move implements state{

face(){
System.out,println(i am  move  );
};
}
}


以上就是状态模式的示例,只需调用changestate就可以改变状态,这样通过状态引导行为就可以实现了。
Proxy 模式和State 模式的区别在于它们所解决的问题不同。《设计模式》里是这
么描述Proxy 模式的一般应用的:
1. 远程代理(Remote Proxy)为一个对象在不同的地址空间提供局部代理。
RMI 编译器(rmic)在创建stubs 和skeletons 的时候会自动为你创建一
个远端代理。
2. 虚代理(Virtual proxy),根据需要,在创建复杂对象时使用 “延迟初
始化(lazy initialization)” .
3. 保护代理(protection proxy) 用于你不希望客户端程序员完全控制被代
理对象(proxied object)的情况下。
4. 智能引用(smart reference). 当访问被代理对象时提供额外的动作。
例如,它可以用来对特定对象的引用进行计数,从而实现写时复制
(copy-on-write),进而避免对象别名(object aliasing). 更简单的
一个例子是用来记录一个特定方法被调用的次数。
你可以把java 里的引用(reference)看作是一种保护代理,它控制对分配在堆
(heap)上的实际对象的访问(而且可以保证你不会用到一个空引用(null
reference))。





迭代器模式(Iterator ):
这个比较面向容器类的,因为容器必须要有迭代吧,next吧,是否到达底部了呢,着一些方法,然后就统一接口,就是迭代器,然后通过内部类实现这个接口,那么各个容器类就具有了迭代的功能了,具体迭代器如何在项目中使用到,这个没弄过,java提供的已经足够强大了。那么到底迭代器为什么放在这一章呢,这一章是对象解耦,哦哦,学过数据结构的同学都知道每一种容器实现迭代的算法都是非常不一样的,使用这时候就需要用到迭代器模式了,把算法和容器分离开,that is good。




这一章我看得还是比较吃力的,特别是对动态代理的深入理解,比较没有实践作为背景,很难真正深入了解其好处的,不过在这里我明白了一样东西,其实这些设计模式是可以动态变得,什么意思,每一种模式其实代码差别是很小的,那么我们在写代码的时候,指导我们的是这种思想,所以说代码中不一定要按照这些模式的规范什么的去编写,你考虑到了真正的内涵然后去编写适合的代码才是最重要的..


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值