注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
热点文章 35岁技术人遭遇年龄坎儿,..
 帮助

比较继承子类实现与Decorator模式实现


2008-04-16 11:19:34
 标签:模式 Decorator 继承   [推送到博客圈]

版权声明:原创作品,如需转载,请与作者联系。否则将追究法律责任。
1. Decorator模式
Decorator模式利用对象的组合动态的提供类的扩展,它是继承方式的一种替代方案。

ConcreteComponent是目标类,通过ConcreteDecorator类对其进行扩展。
下面分别利用继承子类实现和Decorator模式对一个实例进行分析与比较。
2.使用继承子类
Dir提供对指定路径的查询功能,它接受一个路径字符串和一个正则表达式字符串作为参数。路径字符串用于指定查询路径,正则表达式字符串用于提供过滤特定文件名和目录名的功能。
下面是整个实例的类结构图。

Dir.java
package com.zj.file;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.regex.Pattern;
 
public class Dir {
    private String[] list;
    private File path;
    private String regex;
 
    public Dir(File path, String regex) {
       this.path = path;
       this.regex = regex;
    }
 
    public Dir(File path) {
       this.path = path;
    }
 
    private boolean filterFiles() {
       if (regex == null)
           list = path.list();
       else
           list = path.list(new FilenameFilter() {
              private Pattern pattern = Pattern.compile(regex);
 
              public boolean accept(File dir, String name) {
                  return pattern.matcher(name).matches();
              }
           });
       if (list.length > 0)
           return true;
       return false;
    }
 
    public void getFiles() {
       if (getList().length > 0)
           for (String dirItem : getList())
              System.out.println(dirItem);
       else
           System.out.println("No files or directories at" + getPath());
    }
 
    public String[] getList() {
       if (filterFiles())
           return Arrays.copyOf(list, list.length);
       return new String[] {};
    }
 
    public File getPath() {
       return path;
    }
 
    public String getRegex() {
       return regex;
    }
 
    public static void main(final String[] args) {
       System.out.println("===list all files and directories===");
       Dir dir = new Dir(new File("."));
       if (dir.filterFiles())
           dir.getFiles();
       System.out.println("===list all *.zj files===");
       dir = new Dir(new File("."), ".*\\.zj");
       if (dir.filterFiles())
           dir.getFiles();
    }
}
结果:
===list all files and directories===
.classpath
.project
a.zj
b.zj
bin
c.zj
d.zj
src
===list all *.zj files===
a.zj
b.zj
c.zj
d.zj
 
2.1扩展:增加统计文件和目录数目功能
DetailDir使用两个int成员保存当前查询空间下的文件总数和目录总数。它使用继承的方式重写了getFiles方法。
DetailDir.java
package com.zj.file;
import java.io.File;
 
public class DetailDir extends Dir {
    private int dirs = 0;
    private int files = 0;
 
    public DetailDir(File path, String regex) {
       super(path, regex);
    }
 
    public DetailDir(File path) {
       super(path);
    }
 
    public void getFiles() {
       String[] list = getList();
       if (list.length > 0) {
           for (int i = 0; i < list.length; i++) {
              File temp = new File(list[i]);
              if (temp.isDirectory())
                  dirs++;
              if (temp.isFile())
                  files++;
           }
           super.getFiles();
           System.out.println(dirs + " dirs," + files + " files in all");
       } else
           System.out.println("No files or directories at" + getPath());
    }
 
    public static void main(final String[] args) {
       Dir detailDir = new DetailDir(new File("."));
       detailDir.getFiles();
    }
}
结果:
.classpath
.project
a.zj
b.zj
bin
c.zj
d.zj
src
2 dirs,6 files in all
 
2.2扩展:增加统计文件总空间和可使用空间功能
DetailFile使用两个int成员保存当前查询空间下的文件总空间和可使用空间。它使用继承的方式重写了getFiles方法。
DetailFile.java
package com.zj.file;
import java.io.File;
 
public class DetailFile extends Dir {
    private long totalSpace = 0;
    private long freeSpace = 0;
 
    public DetailFile(File path, String regex) {
       super(path, regex);
    }
 
    public DetailFile(File path) {
       super(path);
    }
 
    public void getFiles() {
       String[] list = getList();
       if (list.length > 0) {
           for (int i = 0; i < list.length; i++) {
              File temp = new File(list[i]);
              if (temp.isFile()) {
                  freeSpace += temp.getFreeSpace();
                  totalSpace += temp.getTotalSpace();
              }
           }
           super.getFiles();
           System.out.println("total space " + totalSpace
                  + " bytes,free space " + freeSpace + " bytes");
       }else
           System.out.println("No files or directories at" + getPath());
    }
 
    public static void main(final String[] args) {
       Dir detailFile = new DetailFile(new File("."));
       detailFile.getFiles();
    }
}
结果:
.classpath
.project
a.zj
b.zj
bin
c.zj
d.zj
src
total space 70369492992 bytes,free space 34571993088 bytes
3.使用Decorator模式
使用Decorator模式可以达到同样的效果,其中类Dir可以被视为ConcreteComponent,两个子类可以被视为ConcreteDecorate
下面是整个实例的类结构图。

<<interface>> DirIface.java
package com.zj.file.decorate;
import java.io.File;
 
public interface DirIface {
    void getFiles();
 
    String[] getList() ;
 
    File getPath();
 
    String getRegex();
}
 
具体构件Dir.java
它提供原始功能。
package com.zj.file.decorate;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.regex.Pattern;
 
public class Dir implements DirIface {
    private String[] list;
    private File path;
    private String regex;
 
    public Dir(File path, String regex) {
       this.path = path;
       this.regex = regex;
    }
 
    public Dir(File path) {
       this.path = path;
    }
 
    private boolean filterFiles() {
       if (regex == null)
           list = path.list();
       else
           list = path.list(new