2012年6月28日
设计模式之代理模式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 兔小翊 阅读(124) |
评论 (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 兔小翊 阅读(103) |
评论 (0) |
编辑 收藏