随笔-3  评论-0  文章-0  trackbacks-0
  2012年6月23日
设计模式之代理模式01
问题:如何知道一个方法的运行时间:
引出代理
----------------------
1.直接在原来类上修改
利用System.currentTimeMillis()
public void Move() {
        
long start=System.currentTimeMillis();
        System.out.println(
"Tank Moving");
        
try {
            Thread.sleep(
new Random().nextInt(10000));
        } 
catch (InterruptedException e) {            
            e.printStackTrace();
        }
        
long end=System.currentTimeMillis();
        System.out.println(
"time:"+(end-start));
        
    }


2.利用继承
如果不能在原来类上添加函数。则可以利用新建类继承extends原来类,重写方法,在super.方法前后加入此函数System.currentTimeMillis()
public class Tank2 extends Tank{
    @Override
    
public void Move() {
        
long start=System.currentTimeMillis();
        
super.Move();
        
long end=System.currentTimeMillis();
        System.out.println(
"time2:"+(end-start));
    }
    
}

3.利用聚合。新建一个类B实现接口函数,B类里面有需要测试的类A的对象。相当于B是A的一个代理。实际上,第二种方法也算是一个代理
public class Tank3 implements Moveable{        
    
public Tank3(Tank myt) {
        
super();
        
this.myt=myt;        
    }
    Tank myt;    
    
    @Override
    
public void Move() {
        
long start=System.currentTimeMillis();
        myt.Move();
        
long end=System.currentTimeMillis();
        System.out.println(
"time3:"+(end-start));
    }    
}

4、利用聚合实现多个代理。下面写时间代理(运行的时间)和日志代理(打印),可以通过改变client类上代理调用顺序来改变出现的顺序
------------- Moveable .java-------------
package mypro.cn;
public interface Moveable {
    
public void Move();
}

---------------tank.java-----------
package mypro.cn;
import java.util.Random;
public class Tank implements Moveable{

    
public void Move() {
        System.out.println(
"Tank Moving");
        
try {
            Thread.sleep(
new Random().nextInt(10000));
        } 
catch (InterruptedException e) {            
            e.printStackTrace();
        }
        
    }
}
----------- TankTimeProxy.java-------------------------
package mypro.cn;
import java.text.DateFormat;

public class TankTimeProxy implements Moveable{        
    
public TankTimeProxy(Moveable myt) {
        
super();
        
this.myt=myt;        
    }
    Moveable myt;    
    
    @Override
    
public void Move() {
        
long start=System.currentTimeMillis();
        java.util.Date date 
= new java.util.Date();
        String currTime 
= DateFormat.getDateTimeInstance().format(date);
        System.out.println(
"starttime:"+currTime);
        myt.Move();
        
long end=System.currentTimeMillis();
        System.out.println(
"time:"+(end-start));
    }    
}

------------------------- TankLogProxy .java-------------------------------
package mypro.cn;

public class TankLogProxy implements Moveable{        
    
public TankLogProxy(Moveable myt) {
        
super();
        
this.myt=myt;        
    }
    Moveable myt;    
    
    @Override
    
public void Move() {//日志代理
        System.out.println("tank start");
        myt.Move();        
        System.out.println(
"tank stop");    }    
}

--------------------- Client .java----------------------------
package mypro.cn;
public class Client {
    
public static void main(String[] args) {
        Tank t
=new Tank();
        TankTimeProxy ttp
=new TankTimeProxy(t);//先时间代理,即先包装一层时间
        TankLogProxy tlp=new TankLogProxy(ttp);//再日志代理,最外层包装日志
        Moveable m=tlp;
        m.Move();
    }
}
 
改变包装顺序,先包装日志,再包装时间:
 
    


posted @ 2012-06-28 22:16 兔小翊 阅读(116) | 评论 (0)编辑 收藏

 

设计模式之工厂模式:
1、    掌握什么叫反射
2、    掌握class类的作用
3、    通过反射实例化对象
4、    通过反射调用类中方法的操作原理
5、    工厂设计的改进,重点掌握其思想,程序和配置相分离
package fac.cn;
interface Fruit{
    
public void eat();
}
class Apple implements Fruit{
    
public void eat(){
        System.out.println(
"吃苹果");
    }
}
class Orange implements Fruit{
    
public void eat(){
        System.out.println(
"吃橘子");
    }
}

class Factory{
    
public static Fruit getInstance(String className){
        Fruit f
=null;
        
if(className.equals("Apple"))
            f
=new Apple();
        
else if(className.equals("Orange"))
            f
=new Orange();
        
return f;
    }
}
public class FactoryDemo {
    
public static void main(String args[]){
        Fruit fruit
=Factory.getInstance("Apple");
        fruit.eat();
    }

}
注:本程序的确实现了工厂操作。所有的问题集中在工厂操作中,因为每次只要一增加子类,则必须修改工厂。此时可以根据反射机制来完成,通过Class类来修改工厂
如下表即为修改的工厂类和主类
class Factory{
    
public static Fruit getInstance(String className){
        Fruit f
=null;
            
try {
                f
=(Fruit)Class.forName(className).newInstance();
            } 
            
catch (Exception e) {                
                e.printStackTrace();
            }
        
return f;
    }
}
public class FactoryDemo2 {
    
public static void main(String args[]){
        Fruit fruit
=Factory.getInstance("fac2.cn.Apple");
        fruit.eat();
    }

}
注:在以上操作中,工厂类完全不用修改,但是每次操作应用时,都必须输入很长的包.类.名称,使用时很不方便。最好的方法是通过一个别名来表示这个完成的包.类名称,而且在类增加的时候,别名也可以自动增加。所以如果想要完成这样的操作,可以使用属性类配置

class MyPropertiesOperate{//属性操作类
    private Properties pro=null;
    
private File file=new File("D:\\Workplace"+File.separator+"Fruit.properties");
    
public MyPropertiesOperate(){
        
this.pro=new Properties();
        
if(file.exists()){//文件存在
            try {
                pro.loadFromXML(
new FileInputStream(file)); //读取
            } 
            
catch (Exception e) {                
            }
        }
        
else this.save();
    }
    
    
private void save(){
        
this.pro.setProperty("Apple""cn3.Apple");
        
this.pro.setProperty("Orange""cn3.Orange");
        
try {
            
this.pro.storeToXML(new FileOutputStream(this.file),"Fruit"); //读取
        } 
        
catch (Exception e) {                
        }
    }
    
public Properties getProperties(){
        
return this.pro;
    }
    
}
public class FactoryDemo3 {
    
public static void main(String args[]){
        Properties myPro
=new MyPropertiesOperate().getProperties();    
        Fruit fruit
=Factory.getInstance(myPro.getProperty("Orange"));
        fruit.eat();
    }

}
注:从以上的操作代码中发现,程序通过一个配置文件,可以控制程序的执行,也就是达到了配置文件和程序相分离的目的。这个设计思想现在还在使用中,包括三大框架等。最新的设计理论,是将注释写入代码之中,让注释起到程序控制的作用。要实现此操作,则使用Annotation完成

 

posted @ 2012-06-28 16:47 兔小翊 阅读(98) | 评论 (0)编辑 收藏















































































































































































方法摘要




<U> Class<? extends
U>
asSubclass(Class<U> clazz)
          强制转换该
Class
对象,以表示指定的 class
对象所表示的类的一个子类。
Tcast(Object obj)

          将一个对象强制转换成此 Class 对象所表示的类或接口。
booleandesiredAssertionStatus()

          如果要在调用此方法时将要初始化该类,则返回将分配给该类的断言状态。
static Class<?>forName(String className)

          返回与带有给定字符串名的类或接口相关联的 Class 对象。
static Class<?>forName(String name,
boolean initialize, ClassLoader loader)


          使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class
对象。




<A extends Annotation>

A
getAnnotation(Class<A> annotationClass)

如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
Annotation[]getAnnotations()

          返回此元素上存在的所有注释。
StringgetCanonicalName()

          返回 Java Language Specification 中所定义的底层类的规范化名称。
Class<?>[]getClasses()

          返回一个包含某些 Class 对象的数组,这些对象表示属于此 Class
对象所表示的类的成员的所有公共类和接口。
ClassLoadergetClassLoader()

          返回该类的类加载器。
Class<?>getComponentType()

          返回表示数组组件类型的 Class
Constructor<T>getConstructor(Class<?>... parameterTypes)

          返回一个 Constructor 对象,它反映此 Class
对象所表示的类的指定公共构造方法。
Constructor<?>[]getConstructors()

          返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class
对象所表示的类的所有公共构造方法。
Annotation[]getDeclaredAnnotations()

          返回直接存在于此元素上的所有注释。
Class<?>[]getDeclaredClasses()

          返回 Class 对象的一个数组,这些对象反映声明为此 Class
对象所表示的类的成员的所有类和接口。
Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes)

          返回一个 Constructor 对象,该对象反映此 Class
对象所表示的类或接口的指定构造方法。
Constructor<?>[]getDeclaredConstructors()

          返回 Constructor 对象的一个数组,这些对象反映此 Class
对象表示的类声明的所有构造方法。
FieldgetDeclaredField(String name)

          返回一个 Field 对象,该对象反映此 Class
对象所表示的类或接口的指定已声明字段。
Field[]getDeclaredFields()

          返回 Field 对象的一个数组,这些对象反映此 Class
对象所表示的类或接口所声明的所有字段。
MethodgetDeclaredMethod(String name, Class<?>... parameterTypes)

          返回一个 Method 对象,该对象反映此 Class
对象所表示的类或接口的指定已声明方法。
Method[]getDeclaredMethods()

          返回 Method 对象的一个数组,这些对象反映此 Class
对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
Class<?>getDeclaringClass()

          如果此 Class 对象所表示的类或接口是另一个类的成员,则返回的 Class
对象表示该对象的声明类。
Class<?>getEnclosingClass()

          返回底层类的立即封闭类。
Constructor<?>getEnclosingConstructor()

          如果该 Class 对象表示构造方法中的一个本地或匿名类,则返回 Constructor
对象,它表示底层类的立即封闭构造方法。
MethodgetEnclosingMethod()

          如果此 Class 对象表示某一方法中的一个本地或匿名类,则返回 Method
对象,它表示底层类的立即封闭方法。
T[]getEnumConstants()

          如果此 Class 对象不表示枚举类型,则返回枚举类的元素或 null。
FieldgetField(String name)

          返回一个 Field 对象,它反映此 Class
对象所表示的类或接口的指定公共成员字段。
Field[]getFields()

          返回一个包含某些 Field 对象的数组,这些对象反映此 Class
对象所表示的类或接口的所有可访问公共字段。
Type[]getGenericInterfaces()

          返回表示某些接口的 Type,这些接口由此对象所表示的类或接口直接实现。
TypegetGenericSuperclass()

          返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的
Type
Class<?>[]getInterfaces()

          确定此对象所表示的类或接口实现的接口。
MethodgetMethod(String name, Class<?>... parameterTypes)

          返回一个 Method 对象,它反映此 Class
对象所表示的类或接口的指定公共成员方法。
Method[]getMethods()

          返回一个包含某些 Method 对象的数组,这些对象反映此 Class
对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
intgetModifiers()

          返回此类或接口以整数编码的 Java 语言修饰符。
StringgetName()

          以 String 的形式返回此 Class
对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
PackagegetPackage()

          获取此类的包。
ProtectionDomaingetProtectionDomain()

          返回该类的 ProtectionDomain
URLgetResource(String name)

          查找带有给定名称的资源。
InputStreamgetResourceAsStream(String name)

          查找具有给定名称的资源。
Object[]getSigners()

          获取此类的标记。
StringgetSimpleName()

          返回源代码中给出的底层类的简称。
Class<? super T>getSuperclass()

          返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class
TypeVariable<Class<T>>[]getTypeParameters()

          按声明顺序返回 TypeVariable 对象的一个数组,这些对象表示用此
GenericDeclaration 对象所表示的常规声明来声明的类型变量。
booleanisAnnotation()

          如果此 Class 对象表示一个注释类型则返回 true。
booleanisAnnotationPresent(Class<? extends Annotation> annotationClass)

          如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。
booleanisAnonymousClass()

          当且仅当底层类是匿名类时返回 true
booleanisArray()

          判定此 Class 对象是否表示一个数组类。
booleanisAssignableFrom(Class<?> cls)
          判定此
Class
对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。
booleanisEnum()

          当且仅当该类声明为源代码中的枚举时返回 true。
booleanisInstance(Object obj)

          判定指定的 Object 是否与此 Class
所表示的对象赋值兼容。
booleanisInterface()

          判定指定的 Class 对象是否表示一个接口类型。
booleanisLocalClass()

          当且仅当底层类是本地类时返回 true
booleanisMemberClass()

          当且仅当底层类是成员类时返回 true
booleanisPrimitive()

          判定指定的 Class 对象是否表示一个基本类型。
booleanisSynthetic()

          如果此类是复合类,则返回 true,否则 false
TnewInstance()

          创建此 Class 对象所表示的类的一个新实例。
StringtoString()

          将对象转换为字符串。
posted @ 2012-06-23 17:07 兔小翊 阅读(153) | 评论 (0)编辑 收藏