当前位置:  编程技术>软件工程/软件设计
本页文章导读:
    ▪设计模式原则之三:接口隔离原则      接口隔离原则要求的是在一个模块应该只依赖它需要的接口,以保证接口的小纯洁。而且需要保证接口应该尽量小,即设计接口的时候应该让接口尽量细化,不要定义太臃肿的接口(比如接口.........
    ▪设计模式推演——装饰已有对象(Proxy/Decorator)      上一篇文章中,我们提到OO中复用的方式有两种,组合和继承。一般情况下,应该尽可能使用组合的方式。现在以复用为基本需求,推演若干常见组合型模式 1. Decorator模式  需求:我们.........
    ▪spring AOP        Spring的AOP是上面代理模式的深入。使用Spring AOP,开发者无需实现业务逻辑对象工厂,无需实现代理工厂,这两个工厂都由Spring容器充当。Spring AOP不仅允许使用XML文件配置目标方法,ProxyH.........

[1]设计模式原则之三:接口隔离原则
    来源: 互联网  发布时间: 2013-11-19

接口隔离原则要求的是在一个模块应该只依赖它需要的接口,以保证接口的小纯洁。而且需要保证接口应该尽量小,即设计接口的时候应该让接口尽量细化,不要定义太臃肿的接口(比如接口中有很多不相干的逻辑的方法声明)。

首先看看接口隔离原则的定义,有两种定义

第一种:Clients should not be forced to depend upon interfaces that they don't use.(客户端不应该强行以来它不需要的接口)

第二种:The dependency of one class to another one should depend on the smallest possible interface.(类间的依赖关系应该建立在最小的接口上)

而这里的接口,却不仅仅指的是通过interface关键字定义的接口,接口分为2种:

1、对象接口(Object Interface)

JAVA中声明的一个类,通过new关键字产生的一个实例,它是对一个类型的事物的描述,这也是一种接口。例如:

Phone phone = new Phone();这里的类Person就是实例phone的一个接口

2、类接口(Class Interface)

这种接口就是通过interface关键字定义的接口了

也就是说,接口隔离原则要求的是在一个模块应该只依赖它需要的接口,以保证接口的小纯洁。而且需要保证接口应该尽量小,即设计接口的时候应该让接口尽量细化,不要定义太臃肿的接口(比如接口中有很多不相干的逻辑的方法声明)。

接口隔离原则与单一职责原则有些相似,不过不同在于:单一职责原则要求的是类和接口职责单一,注重的是职责,是业务逻辑上的划分。而接口隔离原则要求的是接口的方法尽量少,尽量有用(针对一个模块)

在使用接口隔离原则的时候需要有一些规范:

1.接口尽量小

接口尽量小主要是为了保证一个接口只服务一个子模块或者业务逻辑

2.接口高内聚

接口高内聚是对内高度依赖,对外尽可能隔离。即一个接口内部的声明的方法相互之间都与某一个子模块相关,且是这个子模块必须的。

3.接口设计是有限度的

但是如果完全遵循接口隔离原则的话,会出现一个问题。即接口的设计力度会越来越小,这样就造成了接口数量剧增,系统复杂度一下子增加了,而这不是真实项目所需要的,所以在使用这个原则的时候还要在特定的项目,根据经验或者尝试判断,不过没有一个固定的标准。
作者:chuangzaozhe1 发表于2013-5-9 0:06:43 原文链接
阅读:63 评论:0 查看评论

    
[2]设计模式推演——装饰已有对象(Proxy/Decorator)
    来源: 互联网  发布时间: 2013-11-19

上一篇文章中,我们提到OO中复用的方式有两种,组合和继承。一般情况下,应该尽可能使用组合的方式。现在以复用为基本需求,推演若干常见组合型模式



1. Decorator模式

 需求:我们已经有一群对象,现在想统一为这些对象添加若干新特性。更重要的是,这些新特性可以反复叠加于某个对象,或者只选择部分特性作用于某个对象。

条件:如果这个特性的实现不依赖于具体的对象,就如同添加一个装饰,那么可以应用Decorator模式。

如果基于开闭原则出发,实际上就是要求不修改已有的对象,通过为每一个新特性实现一个Decorator类来实现扩展(使用的方式是组合)。

应该说:Decorator的使用条件是异常苛刻的,因为每一个Decorator类要求可装饰于任意的对象,这些对象可以是现在已经存在的,同时包括那些未来时的。




2. Proxy模式

Proxy模式有点类似于Decorator模式,也是为已有类的行为做些新的装饰。所不同的是,Proxy模式一般只是为一个对象作装饰,且这些装饰不会相互组合叠加。

从开闭原则出发,Proxy与Decorator模式相同,都是要求不修改已有的对象,通过组合的方式,新建一个Proxy类来扩展原有对象的功能。


Proxy模式是典型的中间层技术,以Proxy对象作为中间层,代替原始对象,从而提供一种更灵活的设计方式。

对代理模式,常见的应用情景是权限和访问控制:

1) 远程代理(Remote  Proxy)为一个位于不同的地址空间的对象提供一个本地的代理对象。这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又叫做大使(Ambassador)。
2) 虚拟代理(Virtual Proxy)根据需要创建开销很大的对象。如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。 
3) 保护代理(Protection Proxy)控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
4) 智能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。
5) Copy-on-Write代理:它是虚拟代理的一种,把复制(克隆)操作延迟到只有在客户端真正需要时才执行。


3.  Decorator模式 /Proxy模式与重构

如果原始代码没有使用Decorator模式 /Proxy模式,那么大多数情况下基本是使用了继承+多态的方式实现,就这种情况而言,可以使用Replace Inheritance with Delegate重构方法。



最后想说明的是,

1. 这两个模式的应用时机

虽然这两个模式是都是装饰已有对象的行为,但是一般设计之初我们可能就已经有意的引入这两个模式。

2. 为什么不是多态,而是组合

首先,使用多态总是可以实现需求的,但正如之前文章中所论述的,应该尽可能使用组合。

第二,这两个模式的主要特点是装饰,通过装饰,将对象的主要行为由原始对象体现,将对象的一些别致行为由装饰对象或者代理对象实现。

这样的设计更满足单一职责原则。

3. 为什么说是装饰已有行为?

没有增加新的接口;改变了原有接口的效果;




作者:crylearner 发表于2013-5-8 23:33:37 原文链接
阅读:57 评论:0 查看评论

    
[3]spring AOP
    来源: 互联网  发布时间: 2013-11-19

 Spring的AOP是上面代理模式的深入。使用Spring AOP,开发者无需实现业务逻辑对象工厂,无需实现代理工厂,这两个工厂都由Spring容器充当。Spring AOP不仅允许使用XML文件配置目标方法,ProxyHandler也允许使用依赖注入管理,Spring AOP提供了更多灵活的选择。
在下面Spring AOP的示例中,InvocationHandler采用动态配置,需要增加的方法也采用动态配置,一个目标对象可以有多个拦截器(类似于代理模式中的代理处理器)。
下面是原始的目标对象:
//目标对象的接口
public interface  Person
{
 //该接口声明了两个方法
 void info();
 void run();
}
下面是原始目标对象的实现类,实现类的代码如下:
//目标对象的实现类,实现类实现Person接口
public class PersonImpl implements Person
{
 //两个成员属性
 private String name;
 private int age;
 //name属性的 setter方法
 public void setName(String name)
 {
  this.name = name;
 }
 //age属性的setter方法
public void setAge(int age)
 {
  this.age = age;
 }
 //info方法,该方法仅仅在控制台打印一行字符串
 public void info()
 {
  System.out.println("我的名字是:  " + name + " , 今年年龄为:  " + age);
 }
 //run方法,该方法也在控制台打印一行字符串。
 public void run()
 {
  if (age < 45)
  {
   System.out.println("我还年轻,奔跑迅速...");
  }
  else
  {
   System.out.println("我年老体弱,只能慢跑...");
  }
 }
}
该Person实例将由Spring容器负责产生和管理,name属性和age属性也采用依赖注入管理。
为了充分展示Spring AOP的功能,此处为Person对象创建三个拦截器。第一个拦截器是调用方法前的拦截器,代码如下:
//调用目标方法前的拦截器,拦截器实现MethodBeforeAdvice接口
public class MyBeforeAdvice implements MethodBeforeAdvice
{
 //实现MethodBeforeAdvice接口,必须实现before方法,该方法将在目标
 //方法调用之前,自动被调用。
     public void before(Method m, Object[] args, Object target) throws Throwable
 {
  System.out.println("方法调用之前...");
  System.out.println("下面是方法调用的信息:");
  System.out.println("所执行的方法是:" + m);
  System.out.println("调用方法的参数是:" + args);
  System.out.println("目标对象是:" + target);
     }
}
第二个拦截器是方法调用后的拦截器,该拦截器将在方法调用结束后自动被调用,拦截器代码如下:
//调用目标方法后的拦截器,该拦截器实现AfterReturningAdvice接口
public class MyAfterAdvice implements AfterReturningAdvice
{
 //实现AfterReturningAdvice接口必须实现afterReturning方法,该方法将在目标方法
 //调用结束后,自动被调用。
     public void afterReturning(Object returnValue, Method m, Object[] args, Object target)throws Throwable
 {
  System.out.println("方法调用结束...");
System.out.println("目标方法的返回值是 : " + returnValue);
  System.out.println("目标方法是 : " + m);
  System.out.println("目标方法的参数是 : " + args);
  System.out.println("目标对象是 : " + target);
    }
}
第三个拦截器是是Around拦截器,该拦截器既可以在目标方法之前调用,也可以在目标方法调用之后被调用。下面是Around拦截器的代码:
//Around拦截器实现MethodInterceptor接口
public class MyAroundInterceptor implements MethodInterceptor
{
 //实现MethodInterceptor接口必须实现invoke方法
     public Object invoke(MethodInvocation invocation) throws Throwable
 {
  //调用目标方法之前执行的动作
         System.out.println("调用方法之前: invocation对象:[" + invocation + "]");
  //调用目标方法
         Object rval = invocation.proceed();
  //调用目标方法之后执行的动作
         System.out.println("调用结束...");
         return rval;
    }
}
利用Spring AOP框架,实现之前的代理模式相当简单。只需要实现对应的拦截器即可,无需创建自己的代理工厂,只需采用Spring容器作为代理工厂。下面在Spring配置文件中配置目标bean,以及拦截器。
下面是Spring配置文件的代码:
<?xml version="1.0" encoding="gb2312"?>
<!--  Spring配置文件的文件头-->
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
 "http://www.springframework.org/dtd/spring-beans.dtd">
<!--  Spring配置文件的根元素-->
<beans>
 <!--  配置目标对象-->
 <bean id="personTarget" class="lee.PersonImpl">
  <!--  为目标对象注入name属性值-->
  <property name="name">
   <value>Wawa</value>
  </property>
  <!--  为目标对象注入age属性值-->
  <property name="age">
   <value>51</value>
  </property>
 </bean>
 <!--  第一个拦截器-->
 <bean id="myAdvice" class="lee.MyBeforeAdvice"/>
 <!--  第二个拦截器-->
 <bean id="myAroundInterceptor" class="lee.MyAroundInterceptor"/>
<!--  将拦截器包装成Advisor,该对象还确定代理对怎样的方法增加处理-->
 <bean id="runAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
  <!--  advice属性确定处理bean-->
  <property name="advice">
   <!-- 此处的处理bean定义采用嵌套bean,也可引用容器的另一个bean-->
   <bean class="lee.MyAfterAdvice"/>
  </property>
  <!--  patterns确定正则表达式模式-->
  <property name="patterns">
   <list>
    <!--  确定正则表达式列表-->
    <value>.*run.*</value>
   </list>
  </property>
 </bean>
 <!--  使用ProxyFactoryBean 产生代理对象-->
 <bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
  <!--  代理对象所实现的接口-->
  <property name="proxyInterfaces">
   <value>lee.Person</value>
  </property>
  <!--  设置目标对象-->
  <property name="target">
   <ref local="personTarget"/>  
  </property>
  <!--  代理对象所使用的拦截器-->
  <property name="interceptorNames">
   <list>
    <value>runAdvisor</value>
    <value>myAdvice</value>
    <value>myAroundInterceptor</value>
   </list>
  </property>
 </bean>
</beans>
该配置文件使用ProxyFactoryBean来生成代理对象,配置ProxyFactoryBean工厂bean时,指定了target属性,该属性值就是目标对象,该属性值为personTarget,指定代理的目标对象为personTarget。通过interceptorNames属性确定代理需要的拦截器,拦截器可以是普通的Advice,普通Advice将对目标对象的所有方法起作用,拦截器也可以是Advisor,Advisor是Advice和切面的组合,用于确定目标对象的哪些方法需要增加处理,以及怎样的处理。在上面的配置文件中,使用了三个拦截器,其中myAdvice、myAroundInterceptor都是普通Advice,它们将对目标对象的所有方法起作用。而runAdvisor则使用了正则表达式切面,匹配run方法,即该拦截器只对目标对象的run方法起作用。

下面是测试代理的主程序:
public class BeanTest
{
    public static void main(String[] args)throws Exception
{

    
最新技术文章:
▪主-主数据库系统架构    ▪java.lang.UnsupportedClassVersionError: Bad version number i...    ▪eclipse项目出现红色叉叉解决方案
▪Play!framework 项目部署到Tomcat    ▪dedecms如何做中英文网站?    ▪Spring Batch Framework– introduction chapter(上)
▪第三章 AOP 基于@AspectJ的AOP    ▪基于插件的服务集成方式    ▪Online Coding开发模式 (通过在线配置实现一个表...
▪观察者模式(Observer)    ▪工厂模式 - 程序实现(java)    ▪几种web并行化编程实现
▪机器学习理论与实战(二)决策树    ▪Hibernate(四)——全面解析一对多关联映射    ▪我所理解的设计模式(C++实现)——解释器模...
▪利用规则引擎打造轻量级的面向服务编程模式...    ▪google blink的设计计划: Out-of-Progress iframes    ▪FS SIP呼叫的消息线程和状态机线程
▪XML FREESWITCH APPLICATION 实现    ▪Drupal 实战    ▪Blink: Chromium的新渲染引擎
▪(十四)桥接模式详解(都市异能版)    ▪你不知道的Eclipse用法:使用Allocation tracker跟...    ▪Linux内核-进程
▪你不知道的Eclipse用法:使用Metrics 测量复杂度    ▪IT行业为什么没有进度    ▪Exchange Server 2010/2013三种不同的故障转移
▪第二章 IoC Spring自动扫描和管理Bean    ▪CMMI简介    ▪目标检测(Object Detection)原理与实现(六)
▪值班总结(1)——探讨sql语句的执行机制    ▪第二章 IoC Annotation注入    ▪CentOS 6.4下安装Vagrant
▪Java NIO框架Netty1简单发送接受    ▪漫画研发之八:会吃的孩子有奶吃    ▪比较ASP和ASP.NET
▪SPRING中的CONTEXTLOADERLISTENER    ▪在Nginx下对网站进行密码保护    ▪Hibernate从入门到精通(五)一对一单向关联映...
▪.NET领域驱动设计—初尝(三:穿过迷雾走向光...    ▪linux下的块设备驱动(一)    ▪Modem项目工作总结
▪工作流--JBPM简介及开发环境搭建    ▪工作流--JBPM核心服务及表结构    ▪Eclipse:使用JDepend 进行依赖项检查
▪windows下用putty上传文件到远程Linux方法    ▪iBatis和Hibernate的5点区别    ▪基于学习的Indexing算法
▪设计模式11---设计模式之中介者模式(Mediator...    ▪带你走进EJB--JMS编程模型    ▪从抽象谈起(二):观察者模式与回调
▪设计模式09---设计模式之生成器模式(Builder)也...    ▪svn_resin_持续优化中    ▪Bitmap recycle方法与制作Bitmap的内存缓存
▪Hibernate从入门到精通(四)基本映射    ▪设计模式10---设计模式之原型模式(Prototype)    ▪Dreamer 3.0 支持json、xml、文件上传
▪Eclipse:使用PMD预先检测错误    ▪Jspx.net Framework 5.1 发布    ▪从抽象谈起(一):工厂模式与策略模式
▪Eclipse:使用CheckStyle实施编码标准    ▪【论文阅读】《Chain Replication for Supporting High T...    ▪Struts2 Path_路径问题
▪spring 配置文件详解    ▪Struts2第一个工程helloStruts极其基本配置    ▪Python学习入门基础教程(learning Python)--2 Python简...
▪maven springmvc环境配置    ▪基于SCRUM的金融软件开发项目    ▪software quality assurance 常见问题收录
▪Redis集群明细文档    ▪Dreamer 框架 比Struts2 更加灵活    ▪Maven POM入门
▪git 分支篇-----不断更新中    ▪Oracle非主键自增长    ▪php设计模式——UML类图
▪Matlab,Visio等生成的图片的字体嵌入问题解决...    ▪用Darwin和live555实现的直播框架    ▪学习ORM框架—hibernate(二):由hibernate接口谈...
▪(十)装饰器模式详解(与IO不解的情缘)    ▪无锁编程:最简单例子    ▪【虚拟化实战】网络设计之四Teaming
▪OSGi:生命周期层    ▪Javascript/Jquery——简单定时器    ▪java代码 发送GET、POST请求
▪Entity Framework底层操作封装(3)    ▪HttpClient 发送GET、POST请求    ▪使用spring框架,应用启动时,加载数据
▪Linux下Apache网站目录读写权限的设置    ▪单键模式的C++描述    ▪学习ORM框架—hibernate(一):初识hibernate
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3