設計模式之單例、策略模式、代理模式

 

單例

定義:一個類在運行期間只能夠擁有一個實例。

類圖:

具體實現的兩種方式如下:

a方式

package com.sigleton;

 

public class House1 {

    public static final House1 HOUSE = new House1();

 

    private House1() {

    }

}

b.方式

package com.sigleton;

 

public class House2 {

    private static House2 house;

 

    private House2() {

    }

 

    public static House2 getHouseInstance() {

       synchronized (house) {//加synchronized是爲了防止線程調用時產生新的單例

           if (house == null) {

              house = new House2();

           }

           return house;

       }

    }

}

好處:運用單例可以來控制一些全局變量的設置。

不足:只有一個對象實例,對於對象裏面的值大家都能夠進行修改。

策略模式

定義:包裝了具體的實現。

類圖:

具體實現的方式如下:

package com.strategy;
/**
 * 策略
 */
public interface Operate {
 public int operation(int a, int b);
}
 

package com.strategy;
/**
 *
 *加法策略
 */
public class AddOperate implements Operate {

 @Override
 public int operation(int a, int b) {
  return a + b;
 }

}

package com.strategy;
/**
 *
 *減法策略
 */
public class SubOperate implements Operate {

 @Override
 public int operation(int a, int b) {
  return a - b;
 }

}

 

package com.strategy;

public enum OperateEnum {
 ADD, SUB, Muli
}

 

package com.strategy;
/**
 *
 * 環境類,本類是通過switch和枚舉類型控制着該使用哪種策略。當然也可以通過其他方式來控制策略
 *
 */
public class Environment {
 private OperateEnum operate;

 public void setOperate(OperateEnum operate) {
  this.operate = operate;
 }

 public int calculateResult(int a, int b) throws Exception {
  Operate o = getOpreate();
  if (o == null) {
   throw new Exception("No found the strategy.");
  }
  return o.operation(a, b);
 }

 private Operate getOpreate() {
  Operate operate = null;
  switch (this.operate) {
  case ADD:
   operate = new AddOperate();
   break;
  case SUB:
   operate = new SubOperate();
   break;
  default:
   operate = null;
   break;
  }
  return operate;
 }

}

 

package com.strategy;
/**
 *
 *使用策略
 */
public class Client {
 public static void main(String[] args) throws Exception {
  System.out.println("-----------Strategy Design---------------");
  Environment environment = new Environment();
  environment.setOperate(OperateEnum.ADD);
  System.out.println("Add Strategy: " + environment.calculateResult(4, 2));
  environment.setOperate(OperateEnum.SUB);
  System.out.println("Sub Strategy: " + environment.calculateResult(4, 2));
 }
}

 

 

好處:具體的策略可以在具體中實現。

不足:用戶必須知道全部的策略,才能夠做出正確的用法。

代理模式

定義:在用戶和真是角色之間建立一箇中介,相當於房屋中介一樣。

類圖:

代理模式之靜態代理代碼實現

 package com.staticproxy;

 

public interface Hose {

    public void rentOrSellHouse(String name);

}

 

 

package com.staticproxy;

 

public class RentHouseImpl implements Hose {

    @Override

    public void rentOrSellHouse(String name) {

       System.out.println(name + " have an house for renting.");

    }

}

package com.staticproxy;

 

public class HouseProxy implements Hose {

    private Hose subject;

 

    public void setSubject(Hose subject) {

       this.subject = subject;

    }

 

    @Override

    public void rentOrSellHouse(String name) {

       if (subject == null) {

           subject = new RentHouseImpl();

       }

       subject.rentOrSellHouse(name);

    }

 

}

 

package com.staticproxy;

 

public class Client {

    public static void main(String[] args) {

       System.out.println("------------Static Proxy.-------------");

       RentHouseImpl subI = new RentHouseImpl();

       HouseProxy hp = new HouseProxy();

       hp.setSubject(subI);

       hp.rentOrSellHouse("Sum");

    }

}

 

代理模式之動態代理代碼實現

package com.dynamicproxy;

/**

 *

 * 房屋信息

 *

 */

public interface House {

    public void rentOrSellHouse(String name);

}

 

package com.dynamicproxy;

/**

 *

 * 發佈租房信息

 *

 */

public class RentHouseImpl implements House {

    @Override

    public void rentOrSellHouse(String name) {

       System.out.println(name + " have an house for renting.");

    }

}

 

 

package com.dynamicproxy;

 

/**

 *

 * 發佈賣房信息

 *

 */

public class SellHouseImpl implements House {

    @Override

    public void rentOrSellHouse(String name) {

       System.out.println(name + " have an house for selling.");

    }

 

}

 

package com.dynamicproxy;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

/**

 *

 *代理

 *

 */

public class HouseProxy implements InvocationHandler {

    private Object subject;

 

    public void setSubject(Object subject) {

       this.subject = subject;

    }

 

    /**

     * 通過反射來實現動態代理的

     */

    @Override

    public Object invoke(Object arg0, Method arg1, Object[] arg2)//arg1表示subject的方法。

           throws Throwable {

       arg1.invoke(subject, arg2);//參數:subject表示傳入的真實角色,arg2表示方法參數。

       return null;

    }

 

}

 

package com.dynamicproxy;

 

import java.lang.reflect.Proxy;

/**

 *

 *獲取房屋信息

 *

 */

public class Client {

    public static void main(String[] args) {

       System.out.println("------------Dynamic Proxy.-------------");

       House subject = null;

       System.out.println("-------------Get Release Rent House Information--------------------");

       RentHouseImpl subI = new RentHouseImpl();

       HouseProxy hp = new HouseProxy();

       hp.setSubject(subI);

       subject = (House) Proxy.newProxyInstance(

              House.class.getClassLoader(),

               RentHouseImpl.class.getInterfaces(), hp);//產生動態代理類。newProxyInstance的參數分別表示:類加載器,表示該代理類實現了哪些接口,InvocationHandler的實現類

       subject.rentOrSellHouse("Sum");//該處的subject是代理類。當調用方法的時候,就直接將信息轉入到InvocationHandler的invoke方法中了。

      

       System.out.println();

       System.out.println("-------------Get Release Sell House Information--------------------");

       SellHouseImpl subSellI = new SellHouseImpl();

       hp.setSubject(subSellI);

       subject = (House) Proxy.newProxyInstance(

              House.class.getClassLoader(),

              new Class[]{House.class}, hp);

       subject.rentOrSellHouse("Jhon");

    }

}

 

好處:使用代理可以封裝一些客戶不需要知道的信息。讓客戶使用代理類就可以了。

不足:靜態代理會產生很多的代理類,因此就有了動態代理。但是動態代理有時不能夠全滿足客戶的要求。

發佈了42 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章