單例
定義:一個類在運行期間只能夠擁有一個實例。
類圖:
具體實現的兩種方式如下:
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");
}
}
好處:使用代理可以封裝一些客戶不需要知道的信息。讓客戶使用代理類就可以了。
不足:靜態代理會產生很多的代理類,因此就有了動態代理。但是動態代理有時不能夠全滿足客戶的要求。