直挂云帆济沧海,展翅遨翔登九天!

我要飞得更高...

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  19 随笔 :: 0 文章 :: 5 评论 :: 0 Trackbacks

2008年8月14日 #

        从这一阶段开始讲述软件设计模式,我也不再讲GoF的神奇历史,直接进入正题。在进行模式讲解的同时,对于本人来说,一方面也是进行了复习,另一方面也是通过讲解使自己对这些模式的使用上达到一个更加理解的层次。搞软件的朋友都知道,在进行开发过一段时间后,会发现自己大学里学习的基础课很重要。而目前很多朋友对软件的理解都非常肤浅,只知道增删改查,试用这样的程序员能存活多久,思考很重要,学习很重要,理解很重要,领悟更重要。让浮燥的程序员回归理性吧,模式可能让浮燥的心情得到净化,在模式中进行思考,在模式中进行领悟吧。
        第一讲是装饰器。当初我在学装饰器模式的时候总是感觉似懂非懂,一直没有真正理解。其实装饰器也叫油漆工模式,再加上在我们的java类库中有很多是实现了装饰器模式的类。比方说:在读取文件时
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
这其实就是一个decorator模式。因为针对File的读取方式有很多,如果每种都要采用继承的方法,那么会产生很多的子类,那样显然是很烦的。
          装饰器也称为油漆工模式。它的目的就是给一个对象动态地添加一些功能。就像是给对象刷了一层漆,使这个对象更加丰富,而不是通过继承来增加功能。而这些功能的添加是动态的运行期的,当然这里的动态并不是像aop中的引介introductor,大家不要混淆。
          在我们的项目中,经常会遇到日志的情况。大凡我们会定义一个log接口就像下面。
public interface Logger {
    public void log(String msg);
}
一般我们会把日志保存中文件中,所以有了一个FileLogger

public class FileLogger implements Logger {

 public void log(String msg) {
        //开始记录日志到文件中
 }
}
此时如果在项目有些地方需要对日志进行加密,有些地方又不需要加密,或者有些地方生成的文件是以xml的方式。此时如果采用继承的方法,也能实现,但是从面向对象的角度来说,并不建议对象的层次太深,增加系统的复杂性,这样对于系统的扩展和维护都不是很方便。此时Decorator模式就可以帮我们解决这些问题,我们可以为这个一般的FileLogger对象上刷一层不同的漆,那么这些漆,从上面增加的功能角度来说,就是加了一个“加密”的漆,或加了一层“生成xml”的漆。
先定义一个Decorator接口,此接口也实现了Logger接口
public class LoggerDecorator implements Logger{
   Logger logger;
   public LoggerDecorator(Logger logger){
        this.logger=logger;
   }
   //开始记录日志
   public void log(String msg){
       //此处便是给实现了Logger接口的,被刷了油漆的(增加了功能的例如加密等)对象记录日志
       logger.log(msg);
   }
}
public class EncryptDecorator extends LoggerDecorator{
    public EncryptDecorator(Logger logger){
        super(logger);
    }
    public void log(String msg){
        //刷加密字符串的油漆
        msg=this.encryptMsg(msg);
        //记录加密后的日志
        logger.log(msg);
    }
}
//客户端的调用
public DecoratorClient{
    public static void main(String args[]){
         Logger logger=new FileLogger();
         Logger decorator=new EncryptDecorator(logger);
         decorator.log("加密的字符串");
   }
}
这样就基本把Decorator模式的应用起来,当然在项目中我们可能还需要更丰富一下我们的类,此处仅用这样的简单示例来讲述。

posted @ 2008-08-18 23:11 周大侠 阅读(435) | 评论 (1)编辑 收藏

         网上google一下,想找一些有用的资料,结果是搜了不少,谁知道都是转载,而且相同的文章太多太多,达到了泛滥的地步,然后冒充自己的文章,也不提是转载,貌似增加了网络搜索资料的途径,实是浪费真正想找资料的朋友的时间,殊不知别人的时间都是有限的,每次打开一个页面结果却都是相同的内容,你叫人气不气,扰乱了整个网络的制序,损人利己,滥宇充数。
    网上的资料不是不可转载,但请转载者在盲目转载的同时,请提出自己的看法意见,留下有用的信息,否则乱贴在自己的blog只会让真正的有志之士所看不起,如果您无法原创,就请您把您的blog关闭。
    清除网络垃圾,还我们一片干净的网络空间!!!
posted @ 2008-08-15 23:35 周大侠 阅读(186) | 评论 (1)编辑 收藏

        Java中有关数据结构的类都在java.util包中,集合框架是每一个程序员都应该熟练掌握的一个类库。Java的集合框架可以提供处理对象的标准方式。在很早的jdk版本中,只提供了Dictionary、Vector、Stack、Properties来存储和操作对象。这些类之间没有统一的api,使用这些类达不到易扩展的作用。
        当然我们使用这些数据结构目的也是为了使用方便,能够提供高效的存取。学过数据结构的朋友们都知道,链表和哈希表的结构的效率都是较高的。为了使用不同的集合之间能够相互操作,相互扩展,那么使用通用的接口将是一个较好的选择。所以整个集合框架被设计成了一系列的标准的接口。在Collections类中有许多静态的算法方法。Iterator迭代器接口提供了通用的访问集合元素的方式,因为每一个集合都实现了Iterator接口。除了集合,还提供了映射的接口和类。比方说Map就提供了存储键值对。虽然它不是集合,但也被整合到了集合中。目前所有的集合都是基于泛型的。
        下面介绍集合框架中的几个常用的接口:
1.Collection 允许处理一组对象,位于集合层次结构的顶部
2.List  扩展Collection接口以处理序列
3.Queue  扩展Collection接口以处理列表中的特殊类型,其元素只能从前面删除
4.Set  扩展Collection接口以处理集合,集合中的元素必须是唯一的
5.SortedSet  扩展Set接口以处理排序的集合
当然除了上述的接口外,集合中还使用Copmarator、Iterator、ListIterator等接口 。
        Collection接口是构造集合框架的基础,必须被定义集合的任意类实现,同样它也是一个泛型接口。
方法摘要
 boolean add(E o)
          确保此 collection 包含指定的元素(可选操作)。
 boolean addAll(Collection<? extends E> c)
          将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。
 void clear()
          移除此 collection 中的所有元素(可选操作)。
 boolean contains(Object o)
          如果此 collection 包含指定的元素,则返回 true
 boolean containsAll(Collection<?> c)
          如果此 collection 包含指定 collection 中的所有元素,则返回 true
 boolean equals(Object o)
          比较此 collection 与指定对象是否相等。
 int hashCode()
          返回此 collection 的哈希码值。
 boolean isEmpty()
          如果此 collection 不包含元素,则返回 true
 Iterator<E> iterator()
          返回在此 collection 的元素上进行迭代的迭代器。
 boolean remove(Object o)
          从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。
 boolean removeAll(Collection<?> c)
          移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。
 boolean retainAll(Collection<?> c)
          仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。
 int size()
          返回此 collection 中的元素数。
 Object[] toArray()
          返回包含此 collection 中所有元素的数组。
<T> T[]
toArray(T[] a)
          返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。
List接口:
该接口扩展了Collection接口,它声明集合是存储一个序列的元素。我们可以把它看成是动态数组。学过数据结构的朋友都知道,数组可以使用基于0的索引,对于泛型的List接口而言,他可以指定保存不同的对象类型。
方法摘要
 boolean add(E o)
          向列表的尾部追加指定的元素(可选操作)。
 void add(int index, E element)
          在列表的指定位置插入指定元素(可选操作)。
 boolean addAll(Collection<? extends E> c)
          追加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序(可选操作)。
 boolean addAll(int index, Collection<? extends E> c)
          将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。
 void clear()
          从列表中移除所有元素(可选操作)。
 boolean contains(Object o)
          如果列表包含指定的元素,则返回 true
 boolean containsAll(Collection<?> c)
          如果列表包含指定 collection 的所有元素,则返回 true
 boolean equals(Object o)
          比较指定的对象与列表是否相等。
 E get(int index)
          返回列表中指定位置的元素。
 int hashCode()
          返回列表的哈希码值。
 int indexOf(Object o)
          返回列表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1。
 boolean isEmpty()
          如果列表不包含元素,则返回 true
 Iterator<E> iterator()
          返回以正确顺序在列表的元素上进行迭代的迭代器。
 int lastIndexOf(Object o)
          返回列表中最后出现指定元素的索引,如果列表不包含此元素,则返回 -1。
 ListIterator<E> listIterator()
          返回列表中元素的列表迭代器(以正确的顺序)。
 ListIterator<E> listIterator(int index)
          返回列表中元素的列表迭代器(以正确的顺序),从列表的指定位置开始。
 E remove(int index)
          移除列表中指定位置的元素(可选操作)。
 boolean remove(Object o)
          移除列表中出现的首个指定元素(可选操作)。
 boolean removeAll(Collection<?> c)
          从列表中移除指定 collection 中包含的所有元素(可选操作)。
 boolean retainAll(Collection<?> c)
          仅在列表中保留指定 collection 中所包含的元素(可选操作)。
 E set(int index, E element)
          用指定元素替换列表中指定位置的元素(可选操作)。
 int size()
          返回列表中的元素数。
 List<E> subList(int fromIndex, int toIndex)
          返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
 Object[] toArray()
          返回以正确顺序包含列表中的所有元素的数组。
<T> T[]
toArray(T[] a)
          返回以正确顺序包含列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。
相对于Collection接口而言,List接口增加了add(int index, E element),add(int index,Collection c)方法,这些方法用于将元素插入到特定的位置,这也是动态数组的特性。
Set接口:
该接口扩展了Collection接口,但不允许有相同的存在的元素,而上述的List接口却没有此约束,其实很好理解,我们可以把它想象成数学中的集合,在那种集合中,是不允许有相同的元素的。
SortedSet接口扩展了Set接口,此接口是升序的集合,由于是有序的,所有自然其中的数据元素是有意义的,否则升序的算法无从使用起。自然就不能存在为null的对象。下表是该接口特有的方法:
方法摘要
 Comparator<? super E comparator()
          返回与此有序集合关联的比较器,如果使用元素的自然顺序,则返回 null
 E first()
          返回此有序集合中当前第一个(最小的)元素。
 SortedSet<E> headSet(E toElement)
          返回此有序集合的部分视图,其元素严格小于 toElement
 E last()
          返回此有序集合中最后一个(最大的)元素。
 SortedSet<E> subSet(E fromElement, E toElement)
          返回此有序集合的部分视图,元素范围从 fromElement(包括)到 toElement(不包括)。
 SortedSet<E> tailSet(E fromElement)
          返回此有序集合的部分视图,其元素大于或等于 fromElement
Queue接口:
这个接口在1.4的版本中是没有,新增的。看名字就知道是队列,先进先出。
方法摘要
 E element()
          检索,但是不移除此队列的头。
 boolean offer(E o)
          如果可能,将指定的元素插入此队列。
 E peek()
          检索,但是不移除此队列的头,如果此队列为空,则返回 null
 E poll()
          检索并移除此队列的头,如果此队列为空,则返回 null
 E remove()
          检索并移除此队列的头。
从队列顶部删除元素 。
posted @ 2008-08-15 19:03 周大侠 阅读(244) | 评论 (0)编辑 收藏

        AOP全称叫做Aspect-Oriented Programming,即面向方面编程或叫做面向切面编程。目前基于java的开源框架有很多已经应用了AOP思想进行设计开发。在轻量级的J2EE应用开发中,AOP经常可以解决一些系统级的服务,比方说事务处理、安全检查、系统日志等。
        目前在AOP编程开发中,有许多新的名词,这些名词的出现会让一些刚开始涉足AOP的朋友们是一头雾水。下面我会把每个名词的意思用自己的语言再描述一遍。
        关注点:关注点即是需要我们去解决的去关心的问题。关注点又可分为核心关注点和横切关注点。核心关注点指的是一个系统中的核心业务功能,也可以认为是是业务逻辑。横切关注点指的是充斥在各个核心关注点间的可以解决同一类问题的的关注点。那么我们的系统也可以认为是由若干个关注点组成的。
       连接点:连接点就是在程序运行时需要在某一点中插入切面,那一点就是连接点。这一点可以是一个方法、一个属性、构造函数、类静态初始化模块。在Spring框架中,只关注方法的切面,即只关心的是方法连接点。
        切入点:切入点其实就是连接点的集合。在Spring框架中我们经常可以看到利用正则表达式对切入点进行定义。
        通知:通知其实就是一个切面的具体实现。比方说在一个业务订单的处理中,切入了订单处理的日志,那么这个日志的具体实现就是一个advice。比方说这个日志实现了某人某时间进行订单的处理审批。那么通知有几种。有前通知、后通知、环绕通知、当然Spring框架中还有Exception通知。
        切面:上面讲到的切入点与通知就是切面的组成部分。
        引介:引介很强大,但是目前用的比较少。它可以强大到给一个定义好的类在运行时动态地添加方法、属性。
        织入:光有切面与核心关注点是不够的,因为这样两者还没有建立关系起来。那么织入的目的就是让两者建立起关系。织入也有三种方式:
1.通过Java代理实现织入。那么又有两种方式。一种是基于代理接口的Java动态代理。另一种是动态字节码生成器代理,也就是在spring中的经常发现的cglib.jar包。
2.有些Aop的实现织入采用了自定义的类加载器,在虚拟机加载字节码的时候进行织入。
3.最后一种就是使用专门的编译器来编译整个应用程序,在编译的过程中就进行织入。
        拦截器:拦截器故名思意就是进行拦截。它可以对连接点进行拦截。那么拦截器也可以组成链通常也称为栈。拦截器的说明可见我上一篇文章。
       
       
未完待续!
posted @ 2008-08-14 22:53 周大侠 阅读(250) | 评论 (0)编辑 收藏