
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 兔小翊 閱讀(128) |
評論 (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 兔小翊 閱讀(108) |
評論 (0) |
編輯 收藏