随笔-19  评论-2  文章-1  trackbacks-0
  2005年7月30日
模板模式:
       
         模板方法中分两种方法:一种是模板方法,另一种是基本方法。
         模板方法:就是把基本方法组合在一起形成一个总算法或则总行为,这个模板方法一般会在抽象定义并且在子类种不加以修改的继承下来。一个抽象类可以有任意多个模板方法。
         基本方法:它又分为抽象方法,具体方法,钩子方法。
      抽象方法由抽象类申明,由子类具体实现;具体方法由抽象类申明并实现,而子类并不实现或则置换,这里面也可以有工厂方法;钩子方法,由抽象类申明并实现,但是它是一个空的实现,一般都是由子类进行扩张实现。
posted @ 2005-08-19 21:15 sky 阅读(368) | 评论 (0)编辑 收藏


import java.io.*;

public class FileRead{
 private static double totalFile = 0;
 private static double totalDirectory = 0;

 public String replace(String value){
     StringBuffer replace = new StringBuffer(value);
     int i = 0;
     int last = replace.lastIndexOf("──");
     i = replace.indexOf("──");
     while((i != last)&&(i != -1)){
         replace.replace(i,i+"──".length(),"   ");
         i = replace.indexOf("──");
         last = replace.lastIndexOf("──");
     }
     return replace.toString();
 }

 public void searchFile(File f,String value,boolean b)throws IOException{
     StringBuffer string = new StringBuffer(value);
     string.append("──");
     boolean bool = b;
  String path = f.getAbsolutePath();
  File currentFile = new File(path); //取得当前路径的文件
  File[] file = currentFile.listFiles();

  for(int i=0;i<file.length;i++){      
      StringBuffer s = null;
      String lastDirectory = null; 
     
      /*
       * 判断文件夹是否为该目录下的最后一个文件夹,如果是的话,则取消打印"│"符号
       */
      for(int k=0;k<file.length;k++){
       if(file[k].isDirectory())
        lastDirectory = new String(file[k].getName()); 
      }
      if(file[i].getName().equals(lastDirectory)){
       if(string.indexOf("│") != -1){
           string.delete(string.lastIndexOf("│"),string.lastIndexOf("│")+1);
       }
      }
       
      /*
       * 格式化打印,将符号最后的"──"变为"├──"(当最后的符号不为"│──"时)
       */     
      if(!((string.lastIndexOf("──")-1) == string.lastIndexOf("│──"))){
          s = new StringBuffer(string.substring(0,string.lastIndexOf("──")));
       s.append("├──");         
      }else{
       if(string.indexOf("│──")!=-1){
        s = new StringBuffer(string.substring(0,string.lastIndexOf("│──")));
        s.append("├──");
       }
      }
     
      if(file[i].getName().equals(file[file.length-1].getName()))
       if(s != null)
        if(s.lastIndexOf("├") != -1)
         s.replace(s.lastIndexOf("├"),s.lastIndexOf("├")+1,"└");
     
      /*
       * 如果s不为空,则将s传入方法replace中进行格式化
       */
      if(s != null)           
       System.out.println(replace(s.toString()) + file[i].getName());
           
   if(file[i].isDirectory()){   
       totalDirectory  += 1;
        
       /*
        * 如果该文件夹的子目录下还有两个以上的文件和文件夹,则打印一个"│"符号,并标记bool为true
        */
           String pathstring = file[i].getAbsolutePath();
     File current = new File(pathstring); //取得当前路径的文件
     File[] fp = current.listFiles();
     if(fp.length >1){
         bool = true;                  
     }
    
       if(bool)
        string.append("│");
      
       searchFile(file[i],string.toString(),bool);
      
       /*
        * 如果bool已经被标记过,则将上一次的"│"符号删除
        */
       if(bool)
        if(string.indexOf("│") != -1)
            string.delete(string.lastIndexOf("│"),string.length());
       bool = false; 
   }
   totalFile += 1; 
  }
 } 
 public static void main(String args[])throws IOException{
  String path = null;
  if(args.length<1)
   path =".";
  else
   path = args[0];
  FileRead read = new FileRead();
  File file = new File(path);
  
  if(!file.exists()){
   System.err.print("the path is error");
   System.exit(1);
  } 
  read.searchFile(file,"│",false);
  System.out.println("the file is :" + (totalFile-totalDirectory));
  System.out.println("thd directory is : " + totalDirectory);
 }
}

该程序存在一个问题,也就是当jdk中的File类无法判断目录下的一些目录是文件夹或则是文件时?

posted @ 2005-08-19 20:20 sky 阅读(574) | 评论 (0)编辑 收藏
策略模式:

        策略模式的对算法的包装,是把使用算法的责任和算法本生分开,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。
使用条件:
        如果在一个系统种有许多类,他们之间的区别仅仅在于他们的行为,并且这个系统需要动态的在几种算法种选择一种。       
posted @ 2005-08-14 23:51 sky 阅读(187) | 评论 (0)编辑 收藏
不变模式:
       
        不变模式可以增强对象的强壮性,不变模式准许多个对象共享一个对象,这降低了对该对象进行并发访问时的同步化开销。如果要修改一个不变对象的状态,则需要创建一个新的对象,并将其存入新的对象里。不变模式只涉及到一个类,一个类的内部状态一旦被创建以后,在整个期间都不会发生变化。他有两种一种是强不变模式和弱不变模式。
        弱不变模式:
首先满足没有方法可以改变对象的状态,则对象一旦被创建之后,对象的状态就不会改变。二该对象的所有的属性都是私有的,并且不准许声明任何公有的方法来改变他们。三这个对象所引用的对象也应该是不变的对象,如果在初始化时应用了一个可变的对象,则应该对该可变对象进行复制一份,而不要使用原来的拷贝。这种模式的缺点是他可以用子类,并且子类可以是可变的对象。可变的子类可能一修改父类对象的状态,从而可能会允许外界修改父对象的状态。

问题:
       为什么说可变的对象可以修该父类对象的状态呢?怎样做?

强不变模式首先要满足弱不变模式,然后将这个类声明成final类,则它变不可能有子类了,并且也将该对象所考虑到的所有方法声明为final。
不变模式与享元模式有很大的相同处,他们的对象状态都有要求不随环境的变化而变化,不过享元模式的内涵状态在不影响享元对象的共享时,可以为可变的。不变模式对对象的要求要比享元模式对对象的要求更严格。


posted @ 2005-08-14 23:39 sky 阅读(634) | 评论 (2)编辑 收藏
桥梁模式:
   
        桥梁模式就是抽象化和实现化脱藕,使得两者可以独立地变法。例子如java中的peer架构。
        桥梁模式与适配器模式的区别是,
posted @ 2005-08-12 23:28 sky 阅读(326) | 评论 (0)编辑 收藏
门面模式:
        在外界访问要访问多个内部系统时,并且他与这些内部系统有着复杂的关系时,我们则可以用门面模式来解决这样的问题。
         门面模式他只是提供一个可以共外界方便访问内部子系统的一个接口,他并不会对子系统进行扩展,他只提供子系统所具有的方法。对外界来说,他是一个子系统,但是内部的子系统并不知道有这么一个类。例如:一个学生要去图书馆借书,这里有3个表,rule是记录不同的读者的借书规则(如研究生可以借7而本科生只能借4本),publish表是记录过期未还书的学生,passwork是记录图书馆所颁发过的借书证。如果一个学生要借书,则他必须要有一个在passwork中存在的借书证,并且没有在publish中的情况,则可以保证向该学生提供借阅,但是借阅的书则要按rule中的规则来进行。所以一个学生client借书必须访问这些类,为了便于管理,我们提供一个  FacadeFactory类来处理,这个类提供了所有client向子系统访问的方法。这样对于client来说就轻松多了,也便于我们维护代码了。但是FacadeFactory不能够向client提供内部子系统不存在的方法。
        由于一个系统中所需要的只需要一个实例,则我们可以把门面类设置为单例类,如上面的FacadeFactory,他应该设置为一个单例类,这样就不会发生多个人同时借一本书了。
       
posted @ 2005-08-12 19:38 sky 阅读(226) | 评论 (0)编辑 收藏

享元模式:flyweight pattern

     享元模式包括两种状态,内蕴状态和外蕴状态。他的种类有单纯享元模式和复合享元模式,结构图如下:

我们从结构种可以看出,复合享元模式是由单纯享元模式和合成模式组合而成的。

享元模式有四种角色:抽象享元角色,具体享元角色,享元工厂角色,和客户角色。享元模式中的享元工厂角色可以通过单例模式来实现。

使用条件:

    一个系统中有大量的对象,这些对象消耗大量的内存,这些对象大部份是可以外部化的,这些对象可以按照内蕴状态分成很多的组,当把外蕴对象从对象中踢除时,每一个组都可以仅用一个对象代替,软件系统不依赖这些对象的身份,换言之,这些对象可以是不可分辨的。不过他要使用一个维护记录了系统已有的所以享元的表,而这需要消耗资源。因此应当在有足够多的享元的实例可提供共享实才值得使用享元模式。
posted @ 2005-08-11 22:37 sky 阅读(261) | 评论 (0)编辑 收藏

   装饰模式

        他的各个角色的作用为:抽象角色:给出一个抽象的接口,以规范准备接收附加责任的对象。

        具体角色:定义一个将要接收附加责任的类。

        装饰角色:持有一个构件对象的实例,并定义一个雨抽象接口一致的接口。

        具体装饰角色:负责给构件对象“贴上”附加责任。

装饰类一般在以下情况使用:

1、  需要扩展一个类的功能,或给一个类增加附加责任。

2、  需要动态的给一个对象增加功能,这些功能可以再动态的测销。

3、  需要增加由一些基本的排列组合产生非常大量的功能,从而使继承关系变得不现实。          

    

他有很多特点:

1、  装饰模式雨继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式准系统动态的决定“贴上”一个需要的“装饰”,或者除掉一个不需要的装饰。而继承则不同,继承关系是静态的,他在系统运行前就决定了。

2、  他可以通过使用不同的具体修饰类以及这些装饰类的排例组合,设计可以创造更多不同行为的组合。     

3、  他虽然比继承性要灵活,这意味着他比继承更容易出错。

缺点:由于使用装饰模式可以比使用继承关系需要较少数目的类,但是在另一方面,使用装饰模式会产生比使用继承方式更多的对象。这在使用时进行错误查询变得更困难了,特别是这些对象看上去都很像。

 

posted @ 2005-08-11 22:36 sky 阅读(228) | 评论 (0)编辑 收藏

import java.util.*;

class BookName{
 String name;
 int number;
}
abstract class Note{
 BookName name = new BookName();
 abstract public void setName(String value);
 abstract public int getNumber();
 abstract public void setNumber(int value);
 abstract public String getName();

class StudentNote extends Note implements Cloneable{
 BookName name = new BookName();
 int isbn;
 public void setName(String value){
  name.name = value;
 }
 public void setNumber(int i){
  name.number = i;
 }
 public int getNumber(){
  return name.number;
 }
 public String getName(){
  return name.name;
 }
 public Object clone() throws CloneNotSupportedException{
  StudentNote st = new StudentNote();
  st = (StudentNote)super.clone();
  st.name = new BookName();
  st.name.name = name.name;
  st.name.number = name.number;
  return st;
 }
 public void setIsbn(int i){
  isbn = i;
 }
 public int getIsbn(){return isbn;}
}
class Manager{
 private Vector v = new Vector();
 
 public void add(Note note){
  v.addElement(note);
 }
 public Note get(int i){
  return (Note)v.get(i);
 }
 public int size(){
  return v.size();
 }
}

class Client{
 private StudentNote student;
 private static Manager client = new Manager();
 public void register()throws CloneNotSupportedException{
  student = new StudentNote();
  StudentNote st = (StudentNote)student.clone();
  client.add(st);
 }
 public static Manager getInstance(){
  return client;
 }

}

class test{ 
 public static void main(String[] args)throws CloneNotSupportedException {
  Client c = new Client();
  c.register(); 
  c.register();
  Manager manager = c.getInstance();
  StudentNote student = (StudentNote)manager.get(0);
  StudentNote st = (StudentNote)manager.get(1);
  student.setName("sky");
  student.setNumber(101);
  student.setIsbn(10001);
  st.setName("fly");
  st.setNumber(102);
  st.setIsbn(10002);
  System.out.println(student.getName() + "\t" + student.getNumber() + "\t" + student.getIsbn());
  System.out.println(st.getName() + "\t" + st.getNumber() + "\t" + st.getIsbn());
 }
}

posted @ 2005-08-09 13:03 sky 阅读(206) | 评论 (0)编辑 收藏

  <java与模式> ---电子书 page 425

 

装饰模式—Decorator

装饰模式有名包装模式,装饰模式以对客户端透明的方式来扩展对象的功能,是继承关系的一个替代的方案。

客户端并不会觉得装饰模式在装饰前和装饰后有什么不同,他可以在不使用更多的子类的情况下来进行对对象的功能加以扩展。结构图如下:

装饰模式原来被装饰类的一个子类的实例,把客户端的调用委派到被装饰类。他有以下组成:抽象构件,具体构件,装饰角色,具体装饰;他一般在下面这些情况使用他最好:

1、  需要扩展一个类的功能,或给一个类增加附加责任。

2、  需要动态的给一个对象增加功能,这些功能可能被动态的撤消。

3、  需要增加一些基本功能的排例组合而产生的非常大量的功能,从而使继承关系变得不现实。

优点:他可以灵活的增加一个类或对象的功能,也可以通过不同的具体装饰类的排例组合设计出更加复杂的,功能更强的类。

缺点:他虽然增加了一个类的灵活性,但同时他也给一个类的管理带来了复杂性。
posted @ 2005-08-03 00:00 sky 阅读(203) | 评论 (0)编辑 收藏

import java.io.*;

public class FileRead{
 private static int space=0;
 private static double totalFile = 0;
 private static double totalDirectory = 0;
 
 public String printSpace(int space){
  String str = "";
  for(int i=0;i<space;i++)
   str += "    ";
  return str; 
 }

 public void searchFile(File f)throws IOException{
  String path = f.getAbsolutePath();
  File currentFile = new File(path); //取得当前路径的文件
  File[] file = currentFile.listFiles();
  
  space++;

  for(int i=0;i<file.length;i++){
   System.out.println(printSpace(space) + file[i].getName());
   if(file[i].isDirectory()){
    totalDirectory  += 1;
    searchFile(file[i]);
    if(space>0)
     space--;   
   }
   totalFile += 1; 
  }
 } 
 public static void main(String args[])throws IOException{
  String path = null;
  if(args.length<1)
   path =".";
  else
   path = args[0];
  FileRead read = new FileRead();
  File file = new File(path);
  
  if(!file.exists()){
   System.err.print("the path is error");
   System.exit(1);
  } 
  read.searchFile(file);
  System.out.println("the file is :" + (totalFile-totalDirectory));
  System.out.println("thd directory is : " + totalDirectory);
 }
}
这个程序在便历多文件时会出现问题?不知道问题在哪里?

合成模式
        合成模式他是一种树型结构,他可以通过对合成的图的单独部分方法达到对整个合成图方法问。他由三部分组成,抽象构件—Component和树枝构件—Composite以及树叶构件Leaf。合成模式分为两种,一种是透明式的。另一个是安全式的合成模式。
         透明式的合成模式和安全式的合成模式,他们的组成成分都一样,他们的区别是:透明式的合成模式,他在抽象构件种增加了操作子类对象的一些接口,这样在实现的过程中,无论是树枝构件还是树叶构件都必须实现这些接口,这对树叶构件来说,这种接口实现是多余的,所以树叶构件是通过平庸式的方式来实现,这种实现,将造成编译时可以通过,但是当用户在应用的过程过如果调用这些方法,将造成运行时的错误,这就造成了程序的不安全;而安全式的合成模式,他并没有在抽象构件实现对子结点接口的申明,他是通过树枝直接对管理子类所需要的方法进行申明,这就给程序带来灵活性,但是也给程序带来不便的管理性,这种实现使得程序不会出现运行时的错误。
         一般我们在这样的情况下应用合成模式:
                  1、当我们要体现构件的部分和整体的结构时。
                  2、当我们要要忽略个体构件与整体构件的区别时,并且要平等的对待个体构件和整体构件时。
         使用合成构件有以下好处:
                  1、使用合成模式可以很容易的增加新构件的种类。
                  2、使用合成模式方便了用户对构件的使用,因为他们不用担心使用的是树页构件还是树枝构件。
         他的缺点:使用合成模式之后在控制树枝构件的类型就不是那么容易了。

posted @ 2005-08-02 01:56 sky 阅读(175) | 评论 (0)编辑 收藏

                                                                                                      

      <java与模式> ---电子书

 

结构模式(Structural Pattern)描述的是类和对象结合在一起行成的更大的结构。分为类的结构模式和对象的结构的结构模式。类的结构模式如:适配器模式,对象的结构模式:代理人模式。

结构模式:合成模式、享元模式、装饰模式、适配器模式、缺省适配器模式、代理模式、门面模式、桥梁模式

 

适配器模式与缺省适配器模式——Adapter Default Adapter  page349 22

 

适配器模式就是把一个类的接口变换成客户端所期待的接口,从而使原来因接口不匹配而无法在一起工作的两个类可以在一起工作。它有两种模式,一种是类的适配器模式,一种叫对象的适配器模式。

 

模式中三种角色:

1、  目标角色:这就是客户端所期待的接口。

2、  源角色:现有的适配接口。

3、  适配器角色:它负责叫源接口转换成目标接口。

类适配器一般用的是继承的方式来实现的,但对象适配器是用的委派。其中对象适配器比起类配器有一些优势,它可以将不同源适配到同一个目标,它甚至可以适配同一个源和它的子类,这对类适配器来说很难的。(类适配器就要先做一个源类的子类,然后将源类的子类进行适配)

 

系统在什么时候使用适配器:

1、  系统需要使用现有的类,而此类的接口有不符合系统的要求。

2、  想成立一个可以重复使用的类,用于将那些之间没有太大的关系的类一起工作。

 

 

缺省适配器模式:它和适配器模式几乎相同,它的作用也和适配器的作用一样,它是适配器模式中的一种特殊的模式。其中的适配器类是一个平庸化的类,它是一个抽象类,但是它实现了从源接口中继承的所有方法,如果不存在适配类的子类,那么适配类就没有意义。如:WindowListener 的适配类WindowsAdapter

J2SE中的缺省适配器模式

 

posted @ 2005-07-31 21:47 sky 阅读(119) | 评论 (0)编辑 收藏

 

   <java与模式> ---电子书

 

原型模式:

 

       深度拷贝:一个是将一个对象中的一个所有域和方法都复制一遍,其中的对象域也一并复制;另一个种是通过流来进行深克窿,因为在java虚拟机中,当把一个对象写到流的对象只是一个拷贝,JVM中还存在原对象。(把对象写到流的过程叫串行化——Serializable)要能够实现第二种深复制必须满足,类中所引用的对象全部都是串行话的,否则,就需要仔细考察那些不可串行化的对象是否可设成transient,从而将之排除在复制之外。

代码测试:

public Object objcetClone() throws IOException, ClassNotFoundException{

              ByteArrayOutputStream o = new ByteArrayOutputStream();

              ObjectOutputStream out = new ObjectOutputStream(o);

              out.writeObject(this);

              ByteArrayInputStream i = new ByteArrayInputStream(o.toByteArray());

              ObjectInputStream in = new ObjectInputStream(i);

              return in.readObject();

       }

posted @ 2005-07-30 21:05 sky 阅读(108) | 评论 (0)编辑 收藏

 复习

 

其中登记式注册单例模式:

import java.util.*;

class Single{

       private static HashMap hashmap = new HashMap();

       private int number = 0;

       static{

              Single single = new Single();

              hashmap.put(single.getClass().getName(),single);

       }

       private Single(){}

       public static Single getInstance(String name){

              if(name == null){

                     name = "Single";

              }

              if(hashmap.get(name) == null){

                     try{

                            hashmap.put(name,Class.forName(name).newInstance());

                     }catch(Exception e){

                            System.out.println(e.getMessage());

                     }

              }

              return (Single)hashmap.get(name);

       }

       public void fun(){

              number++;

              System.out.println("the is the single fun :" + number);

       }

}

 

他的另外一个做法是同过继承,通过父类来注册子类的对象:

代码如:

class SingleChild extends Single{

       public SingleChild(){}

       public static SingleChild getInstance(){

              return (SingleChild)Single.getInstance("SingleChild");

       }

       public void fun(){

              System.out.println("singlechild");

       }

}

当它要这样做之后就破坏了父类,因为子类要调用父类的构造子函数,所以父类的构造子函数就不能够为私有的,这就破坏单例模式的优点。

posted @ 2005-07-30 21:04 sky 阅读(82) | 评论 (0)编辑 收藏

 <java编程语言 >

 

多太中的一种情况

在类的多太中,域是由他引用的类型决定那个版本,而方法则是由对象的真实类决定的。这和接口中使用的一样。

测试代码如下:

class Father{

       public String str="father";

       public void fun(){

              System.out.println("Father : " + str);

       }

}

class ChildOne extends Father{

       public String str="childone";

       public void fun(){

              System.out.println("ChildOne : " + str);

       }

}

public class TestClassProMeth {

       public static void main(String args[]){

              ChildOne childone = new ChildOne();

              Father father = childone;

              father.fun();

              childone.fun();

              System.out.println(father.str + '\n' + childone.str);

       }

}

结果:

ChildOne : childone

ChildOne : childone

father

childone

 

接口:

在接口中的声明的域是是一个常量(public static final),他的方法不能够有其他的修饰符,隐式为public,也不能够被拥有定义实现符的修饰如:nativesynchronizedstrictfp也不能够是静态的,因为静态方法不能够抽象方法。

继承接口:如果接口声明了一个和继承来的常量名相同,则无论他的类型如何都将被隐藏,并且当他们的类型不一致时,编译出错。

 

测试如下:

interface Super{

       public static final String name = "super";

       void fun();

}

interface Entend extends Super{

       String name = "entend";

       String str = Super.name + '\n' + name;

       void fun();

}

class Realize implements Entend{

       public void fun(){

              System.out.println(Super.name + '\n' + Entend.name + '\n' + str);

       }

}

public class TestInterface {

       static String name ="testinterface";

       public static void main(String args[]){

              Realize real = new Realize();

              real.fun();

              System.out.println(Realize.name + '\n' + ((Super)real).name);

       }

}

结果:

super

entend

super

entend

entend

super

posted @ 2005-07-30 21:03 sky 阅读(147) | 评论 (0)编辑 收藏

<java与模式> ---电子书

17  page245 多例模式

 

 

       当实例数目不多是时候,可以用一个个的静态变量来存储一个个的实例,在数目多是时候需要使用静态聚集存储方式来存储这些实例。

 

问题:怎样用静态聚集存储方式来存储?具体如何实现?

 

 

建造模式(builder

 

 

建造模式(builderpage277

建造模式可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象

内部表象—一个产品有不同的组成成分作为产品的零件,这些零件有可以是对象,也有可能不是对象,它们通常又叫做产品的内部表象。

抽象建造者角色:给出一个抽象内部接口,以规范产品对象的各个组成成分的建造,一般而言,该接口独立于应用程序的商业逻辑。

具体建造者角色:担任这个角色的是与应用程序紧密相关的一些类,他们在应用程序调用下创建产品的实例。他的任务:1、实现抽象建造者所有申明的接口,给出一步一步的完成创建产品实例的操作。2、在创建过程完成后,提供产品的实例。

导演者:担任这个角色的类调用具体建造者角色以创建产品对象。

产品角色:产品是焦躁中的复杂对象。

 

下面是一个由两个产品类构成的建造模式结构图: 


20 原始原型模式

 

用意:原始模型模式属于对象的创建模式;通过给出一个原形对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出更多类型的对象。

 

问题:什么叫不变对象? page314

 

简单形式的原始模型模式:

客户角色:客户类提出创建对象的请求;

抽象原型角色:这是一个抽象角色,通常由一个java接口或java抽象实现,此角色给出所有的具体原型类所需要的接口;

具体原型角色:被复制的对象,此角色需要实现抽象的原型角色所要求的接口。

结构图如下:

 


 

登记式原型模型模式:

增加了一个原型管理器角色:创建具体原型类的对象,并记录每一个被创建的对象。

结构图如下:

抽象原型

具体原型

客户

原型管理器

 

 

 

 

posted @ 2005-07-30 21:02 sky 阅读(167) | 评论 (0)编辑 收藏

  <java与模式> ---电子书

抽象工厂模式:page171 14

 

抽象工厂的用意是使客户端在不必指定产品的具体的情况下创建多个产品族中的产品对象;

抽象工程模式是对象的创建模式。

在什么情况下用抽象工厂模式:

1 一个系统不应当依赖产品类实例如何创建、组合和表达的细节,这对与所有形态的工厂模式都是重要的。

2、这个系统的产品有多于一个的产品族,而系统只消耗其中某一族的产品

3、同属于一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来

4、系统提供一个产品类的库,所以的产品以同样的接口出现,从而使客户端不依赖于实现。

 

扩展:

1、产品的等级结构扩展,也就是当在增加一个平行等级新的产品时,抽象工程不支持“开—闭”原则

2、在增加新产品族的时,支持开-闭原则。

 

问题:为什么上面的抽象工厂和抽象产品没有依赖关系呢?(在工厂方法模式中)在这里我们同样用了抽象产品的接口作为抽象工厂的返回接口呀!

15 单例模式 page201

单例模式的要点:

1、  某个类只可以有一个实例

2、  该类必须自行创建实例

3、  它必须自行向整个系统提供这个实例

 

一、 汉式单例类

该类自己含有一个实现自己实例的静态方法,同时为了不让外界创建实例,则它的构造方法必须是私有的。

代码测试:

       class EagerSimple{

              private static final EagerSimple eager = new EagerSimple();

              private EagerSimple{}

              public static EagerSimple getInstance(){

                     return eager;

}

}

      

二、懒汉式单例类

它也饿汉式单例类不同的是,只有当自己被引用的时候,自己才被实例化。结构图与饿汉式单例类一样的。

 

代码测试:

 

class LanSimple{

       private static LanSimple simple= null;

       private LanSimple(){}

       synchronized public static LanSimple getInstance(){

              if(simple == null)

                     simple = new LanSimple();

              return simple;

}    

}

饿汉式单例类与懒汉式单例类的区别是:在时间和反映上说,饿汉式要比懒汉式好,但是从资源利用上则饿汉式要好。

 

 

双重检查成例的“懒汉式”单例类:

class LazySimple{

       private LazySimple(){}

       private static LazySimple lazy = null;

      

       public static LazySimple getInstance(){

              if(lazy == null){

                     synchronized(lazy){

                            if(lazy == null){

                                   lazy = new LazySimple();

                            }

                     }

              }

              return lazy;

       }

}

这个代码看上去并没有步合理之出,而且我认为还相当有意义,可是为什么说在java中就不对呢?不能够使用呢?问题在哪里?

posted @ 2005-07-30 20:59 sky 阅读(177) | 评论 (0)编辑 收藏

 

 

 

对简单工厂的特殊情况进行测试——工厂角色与具体产品角色合并

代码如下:

abstract class AbstractClass{

       private static String name;

       public final static AbstractClass format(String value){

              name = value;

              return new Embody();

       }

       public String getMsg(){

              return name;

       }

       public abstract void fun1();

}

 

class Embody extends AbstractClass{

       public void fun1(){

              System.out.println("the enbody extends AbstractClass" + getMsg());

       }

}

public class tt {

       public static void main(String args[]){

              AbstractClass.format("name").fun1();

       }

}

上面的代码中通过工厂方法把子类具体的实例化隐藏了起来。

下面是对一个普通的简单工厂模式的实现:

代码测试:

      

package sky;

//产品抽象类

abstract class People{

       public String name; //名字

       public String occuptationl;  //职业

       abstract public String getMsg();

}

//学生类——具体产品

class Student extends People{

       private String name;

       private String occupation;

       private String grade;

      

       public Student(String name,String occupation){

              this.name = name;

              this.occupation = occupation;

       }

       public void setGrade(String grade){

              this.grade = grade;

       }

       public String getGrade(){

              return grade;

       }

       public String getMsg(){

              return getOccupation()+getName()+getGrade();

       }

       public String getOccupation(){

              return occupation;

       }

       public String getName(){

              return name;

       }

      

}

//教师类——具体产品类

class Teacherextends People{

       private String name;

       private String occupation;

       private int wage;

      

       public Teacher(String name,String occupation){

              this.name = name;

              this.occupation = occupation;

       }

       public void setWage(int wage){

              this.wage = wage;

       }

       public String getMsg(){

              return getOccupation()+getName() + getWage();

       }

       public String getOccupation(){

              return occupation;

       }

       public String getName(){

              return name;

       }

       public int getWage(){

              return wage;

       }

}

//工厂类

class factory{

       public static People build(String name,String occupation) throws BadPeopleException{

              if(occupation.equals("student")){

                     return new Student(name,occupation);

              }

              else if(occupation.equals("teacher")){

                     return new Teacher(name,occupation);

              }else{

                     throw new BadPeopleException("can not found the people");

              }

       }

}

//异常处理

class BadPeopleException extends Exception{

       public BadPeopleException(String msg){

              super(msg);

       }

}

 

public class test{

       public static void main(String args[]){

              try {

                     Student t = (Student) factory.build("sky","student");

 //从这个显示转换申明中我并没有看到简单工厂的好处

                     factory.build("fly","teacher");

/*难道只有这样才可以看到它的优点吗?——能够避免客户决定什么时候创建哪个实例*/

                     t.setGrade("three");

                     System.out.println(t.getMsg());

              } catch (BadPeopleException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              }

       }

}

 

     问题:接口和抽象类的区别在哪里?    

 

 

  13 工厂方法模式 <java与模式> ---电子书 page146

 

       组成为:抽象工厂、具体工厂、抽象产品、具体产品

其中抽象工厂是为外部访问内部的一个接口,它的好处是可以通过扩张具体产品和具体工厂而不用改变客户端的代码.

 

一个简单的测试代码如下:

 

interface Fruit{

       void grow();

       void harvest();

}

class Apple implements Fruit{

       private int treeNumber;

      

       public void grow(){

              System.out.println("Apple.grow()");

       }

       public void harvest(){

              System.out.println("Apple.harvest()");

       }

       public void setTreeNumber(int number){

              treeNumber = number;

       }

       public int getTreeNumber(){

              return treeNumber;

       }

      

}

class StrawBerry implements Fruit{

       public void grow(){

              System.out.println("StrawBerry.grow()");

       }

       public void harvest(){

              System.out.println("StrawBerry.harvest()");

       }

}

 abstract class Gardener{

      abstract public Fruit product();

 }

 

 class AppleGardener extends Gardener{

      public Fruit product(){

             return new Apple();

      }

 }   

 class StrawBerryGardener extends Gardener{

      public Fruit product(){

             return new StrawBerry();

      }

 }

public class Client {

       public static void main(String args[]){

              Fruit apple,strawberry;

              AppleGardener applegarder = new AppleGardener();

              StrawBerryGardener strawberrygarder = new StrawBerryGardener();

              apple = applegarder.product();

              strawberry = strawberrygarder.product();

              apple.grow();

              strawberry.grow();

       }

}

posted @ 2005-07-30 20:54 sky 阅读(132) | 评论 (0)编辑 收藏

 <java与模式> ---电子书

2.4部分 UML  page16

理解: 类图

一、描述类的类图

一般如果类不包含内部类,则可以将类图分为四层。

1、第一层描述的是类的名字,如果为斜体则该类为抽象类。

2、第二层描述的是类的属性,规则是:[+|-|#]classname<变量名>如果有下划线则表示其为静态的。+表示为public、—表示为private#表示为protected

3、第三层描述的是类的方法,规则是:[+|-|#]funcationname<变量名>如果有下划

则表示其为静态的。

4、第四层表示的是类的性质,也就是类的属性,不过一旦有该属性,类就要实现方法,setget方法。

       接口类的类图和类的类图几乎一样。

 

问题:该类中包含有内部类的有是如何分层的呢?

      

二、描述对象的类图

他们的关系会发生在类和类、类和接口、接口和接口之间。

类图的关系可以分为:一般关系、关联关系、聚合关系、合成关系、依赖关系。

1、一般关系表现在类或则接口之间的继承关系。

2、关联关系是指他用另一个类的实例作为其属性,而聚合关系基本上也是这个意思不过聚合主要体现的是总体和四肢的关系,如:类的属性是用一个对象数组实现的,那么该类就和实现这个属性数组的类是一个聚合关系。

3、合成关系要比聚合关系要强,他在每一个时刻只能够和一个对象发生合成关系,他不能够共享。

4、依赖关系是在一个的方法中引用了一个类的对象作为是参数,或是引用了一个类的对象作为局部变量或引用类的静态方法或属性。 

问题:合成关系中的共享,到底什么不能够共享?怎么理解这个不能够共享?合成关系很难理解,“他在每一个时刻只能够和一个对象发生合成关系”这句话与关联关系中不就一样了吗?也就是说,当我们直接用一个类A来声明一个对象作为一个类B的属性,那么我们就可以说这个类A关联类B,那也可以说类A合成类B吗?

 

第十二章 简单工厂模式

 

 

“开—闭”原则要求一个系统的设计准许在系统不需要修改的情况下扩展其功能

 

理解:简单工厂模型简单说就是:抽象产品——>具体产品<-----------工厂类

       在特殊的情况下,也就是当只有一个具体产品的时候,我们可以将其中抽象产品不要,但是这种用法看上去不是很多。一个更为特殊的用法是将抽象产品和工厂类合并.


                                          

 

 

 

 

 

 

                                

posted @ 2005-07-30 20:15 sky 阅读(183) | 评论 (0)编辑 收藏