设计模式之单例、策略模式、代理模式

 

单例

定义:一个类在运行期间只能够拥有一个实例。

类图:

具体实现的两种方式如下:

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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章