单例
定义:一个类在运行期间只能够拥有一个实例。
类图:
具体实现的两种方式如下:
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");
}
}
好处:使用代理可以封装一些客户不需要知道的信息。让客户使用代理类就可以了。
不足:静态代理会产生很多的代理类,因此就有了动态代理。但是动态代理有时不能够全满足客户的要求。