`
abcxo
  • 浏览: 33424 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

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
4
分享到:
评论

相关推荐

    24种设计模式介绍与6大设计原则

    **迭代器模式(Iterator Pattern)** 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。 **应用场景**:当遍历集合对象时。 ##### 15. **组合模式(Composite Pattern)** 将对象组合...

    Apress.Pro.Objective-C.Design.Patterns.for.iOS

    - **第14章**:迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。 #### 第六部分:行为扩展模式(Behavioral Extension) - **第15章**:访问者模式(Visitor)...

    源码:阎宏设计模式光盘

    com.javapatterns.iterator 迭代子模式 com.javapatterns.javaio 专题:设计模式在Java I/O中的应用 com.javapatterns.keygen 专题:序列键生成器与单例及多例模式 com.javapatterns.liskov 里氏代换原则 ...

    JAVA设计模式(十三种)

    - 迭代器模式(Iterator):迭代器模式提供了一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):中介者模式用一个中介对象来封装一系列的对象交互,降低系统的耦合度。 - 观察...

    设计模式可复用面向对象软件的基础 源码

    - 迭代器模式(Iterator):提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):定义一个中介对象来简化原本复杂的对象间交互。 - 备忘录模式(Memento):在不破坏封装性的...

    23种 设计模式---面向对象的基本原则

    - 迭代器模式(Iterator):提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):用一个中介对象来封装一系列的对象交互,降低系统的耦合度。 - 备忘录模式(Memento):在不...

    3.Java之23种设计模式解析-尚硅谷1

    - **迭代器模式(Iterator)**:允许顺序访问聚合对象的元素,而无需暴露其内部结构。 - **观察者模式(Observer)**:定义对象之间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知并自动...

    java23种设计模式详解+源码(绝对详解)

    - 迭代器模式(Iterator):提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):用一个中介对象来封装一系列的对象交互,降低系统的耦合度。 - 备忘录模式(Memento):在不...

    设计模式精解-GoF-23种设计模式解析--附C++源代码

    - 迭代器模式(Iterator):提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):用一个中介对象来封装一系列的对象交互。 - 备忘录模式(Memento):在不破坏封装性的前提下...

    设计模式可复用面向对象软件的基础(PDF,学习设计模式必备)

    - 迭代器模式(Iterator):顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):定义一个中介对象协调多个对象之间的交互。 - 备忘录模式(Memento):在不破坏封装的前提下,捕获和恢复...

    原创-设计模式实现代码

    - 迭代器模式(Iterator):提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于...

    C#经典设计模式及代码示例

    3. 行为型模式:这类模式关注对象之间的交互和责任分配,包括策略模式(Strategy)、观察者模式(Observer)、命令模式(Command)和迭代器模式(Iterator)。例如,策略模式允许在运行时选择算法,提供更大的灵活性...

    c#设计模式教程+源码

    - 迭代器模式(Iterator):提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):定义一个中介对象来简化原本复杂的对象交互。 - 观察者模式(Observer):定义对象之间的一...

    JAVA DesignPattern面向对象23种设计模式的实现源代码.zip

    3. 行为型模式:策略模式(Strategy)、模板方法模式(Template Method)、观察者模式(Observer)、责任链模式(Chain of Responsibility)、命令模式(Command)、迭代器模式(Iterator)、访问者模式(Visitor)...

    《设计模式可复用面向对象软件的基础》

    行为模式 1475.1 CHAIN OF RESPONSIBIL ITY(职责链)—对象行为型模式 1475.2 COMMAND(命令)—对象行为型模式 1545.3 INTERPRETER(解释器)—类行为型模式 1625.4 ITERATOR(迭代器)—对象行为型模式 1715.5 ...

    23种经典设计模式UML类图汇总.chm_23种经典设计模式UML类图汇总.chm_uml_

    - 迭代器模式(Iterator):提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):用一个中介对象来封装一系列的对象交互,降低系统的耦合度。 - 备忘录模式(Memento):在不...

    C#设计模式_设计模式_C#_

    迭代器模式(Iterator Pattern) 16. 观察者模式(Observer Pattern) 17. 解释器模式(Interpreter Pattern) 18. 中介者模式(Mediator Pattern) 19. 职责链模式(Chain of Responsibility Pattern) 20. 备忘录模式...

    设计模式,设计模式详解

    - 迭代器模式(Iterator):提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):定义一个中介对象来简化原本复杂的对象交互。 - 观察者模式(Observer):定义对象间的一对...

    设计模式整理代码-pattern.zip

    - 迭代器模式(Iterator):提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):定义一个中介对象来简化原本复杂的对象交互。 - 观察者模式(Observer):定义对象之间的一...

Global site tag (gtag.js) - Google Analytics