JAVA设计模式示例代码

本文罗列了部分设计模式的简单示例代码,其中有很多框架的底层都是通过动态代理和责任链模式实现的,比如spring和mybatis

文章目录

  • 一:java反射技术
    • 1.1通过反射构造对象
    • 1.2反射方法
    • 1.3实例,生成反射对象和反射调度方法
  • 二:动态代理模式和责任链模式
    • 2.1JDK动态代理
    • 2.2 CGLIB动态代理
    • 2.3 拦截器
    • 2.4责任链模式(多拦截器)
  • 三:观察者(Observer)模式(发布订阅模式)
  • 四:工厂模式和抽象工厂模式
    • 4.1普通工厂模式
    • 4.2抽象工厂模式
  • 五:建造者(Builder) 模式

一:java反射技术

1.1通过反射构造对象

  • 创建 ReflectServiceImpl类
package reflect;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/12 15:48
 * @Description:
 */
public class ReflectServiceImpl {

        public void sayHello(String name){
            System.out.println("hello,"+name);
        }

}

通过反射生成对象

    public ReflectServiceImpl getInstance() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        ReflectServiceImpl object = null;
        /*给类加载器注册了一个ReflectServiceImpl的全限定名,然后通过newInstance()构造了一个新的对象*/
        object = (ReflectServiceImpl) Class.forName("reflect.ReflectServiceImpl").newInstance();
        return object;
    }

  • 创建 ReflectServiceImpl2类(含有参数)
package reflect;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/12 16:21
 * @Description: 构造方法含有参数的类
 */
public class ReflectServiceImpl2 {
    private  String name;

    public ReflectServiceImpl2(String name) {
        this.name = name;
    }

    public void sayHello(){
        System.out.println("hello"+name);
    }
}

生成对象


    /*通过反射生成带有参数的构造方法*/
    public ReflectServiceImpl2 getInstance2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        ReflectServiceImpl2 object = null;
        object = (ReflectServiceImpl2) Class.forName("reflect.ReflectServiceImpl2").getConstructor(String.class).newInstance("jack");
        return object;
    }

反射仅需配置就可以生成对象,解除程序的耦合度,缺点就是运行比较慢,但依然比较常用,如Spring Ioc容器

1.2反射方法

/*反射方法*/
    public Object reflectMethod() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Object returnObject = null;

        ReflectServiceImpl target = new ReflectServiceImpl();

        Method method = ReflectServiceImpl.class.getMethod("sayHello", String.class);//第一个参数是方法名称,第二个参数是方法的参数类型
        returnObject = method.invoke(target,"张三");//第一个参数使用哪个对象调用方法

        return  returnObject;
    }

1.3实例,生成反射对象和反射调度方法

/*实例*/
    public  Object reflect() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        ReflectServiceImpl object;
        object = (ReflectServiceImpl) Class.forName("reflect.ReflectServiceImpl").newInstance();

        Method method = object.getClass().getMethod("sayHello", String.class);
        method.invoke(object,"张三");
        return object;
    }

二:动态代理模式和责任链模式

代理分两个步骤:

  • 代理对象和真是对象建立代理关系
  • 实现代理对象的代理逻辑方法
    Spring最常使用的动态代理技术是JDK和CGLIB,其中JDK动态代理中必须使用接口

2.1JDK动态代理

  • 建立接口和实现类
package agent;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/12 17:06
 * @Description:
 */
public interface HelloWorld {
    public void sayHelloWorld();
}

package agent;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/12 17:08
 * @Description:
 */
public class HelloWorldImpl implements HelloWorld{

    @Override
    public void sayHelloWorld() {
        System.out.println("hello,world");
    }

}

  • 动态代理绑定和代理逻辑实现
package agent;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/12 17:10
 * @Description:
 */
public class JdkProxyExample implements InvocationHandler {

    //真实对象
    private Object target = null;

    /**
     * 建立代理对象和真实的代理关系,并返回代理对象
     * @param target 真是对象
     * @return 代理对象
     */
    public Object bind(Object target){
        this.target = target;
        //第一个参数是类加载器,第二个参数是生成的动态代理对象下挂在那些接口下,第三个是定义实现方法逻辑的代理类
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    /**
     * 代理方法逻辑
     * @param proxy  代理对象
     * @param method 当前调度方法
     * @param args 当前方法参数
     * @return 代理结果返回
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //真实对象
        System.out.println("进入代理逻辑方法");
        System.out.println("在进入真实对象之前的服务");
        Object obj = method.invoke(target,args); //相当于调用sayhelloworld方法

        System.out.println("在调用真实对象之后的服务");
        return obj;
    }



}
  • 测试jdk动态代理
package agent;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/12 17:59
 * @Description:
 */
public class Test {
    public static void main(String[] args) {
        JdkProxyExample jdkProxyExample = new JdkProxyExample();
        //绑定关系,因为挂在接口helloworld下所以声明代理接口对象HelloWorld Proxy
        HelloWorld proxy = (HelloWorld)jdkProxyExample.bind(new HelloWorldImpl());
        //注意此时的HelloWorld对象已经是一个代理对象,它会进入代理的逻辑方法invoke里的proxy里的proxy。sayHelloWorld
        proxy.sayHelloWorld();
    }
}

2.2 CGLIB动态代理

代码如下:

package agent.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.Proxy;

import java.lang.reflect.Method;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/12 18:59
 * @Description:
 */
public class CjlibProxyExample  implements MethodInterceptor {

    /**
     * CGLIB生成代理对像
     * @param cls 类
     * @return 类的CGLIB代理对象
     */
    public Object getProxy(Class cls){
        //CGLIB enhancer 增强类对象
        Enhancer enhancer = new Enhancer();
        //设置增强类型
        enhancer.setSuperclass(cls);
        //定义代理对象为当前对象,要求当前对象实现methodInterceptor方法
        enhancer.setCallback(this);
        //生成并返回代理对象
        return enhancer.create();
    }

    /**
     * 代理逻辑方法
     * @param o 代理对象
     * @param method 方法
     * @param objects 参数
     * @param methodProxy 方法代理
     * @return 代理逻辑返回
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("调用真实对象前");
        //CGLIB 反射调用真实对象方法
        Object result = methodProxy.invokeSuper(o,objects);
        System.out.println("调用真实对象后");
        return result;
    }

}

测试

package agent.cglib;

import reflect.ReflectServiceImpl;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/12 19:23
 * @Description:
 */
public class Test {
    public static void main(String[] args) {
        CjlibProxyExample cjlibProxyExample = new CjlibProxyExample();
        ReflectServiceImpl obj = (ReflectServiceImpl) cjlibProxyExample.getProxy(ReflectServiceImpl.class);
        obj.sayHello("MR.Zhang");
    }
}

2.3 拦截器

  • 接口与实现
package interceptor;

import java.lang.reflect.Method;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/12 20:19
 * @Description:
 */
public interface Interceptor {
    /**
     *
     * @param proxy 代理对象
     * @param torget 真实对象
     * @param method 方法
     * @param args 方法参数
     * @return
     */
    public boolean before(Object proxy, Object torget, Method method,Object[] args);

    public void around(Object proxy, Object torget, Method method,Object[] args);

    public void after(Object proxy, Object torget, Method method,Object[] args);

}

package interceptor;

import java.lang.reflect.Method;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/12 20:24
 * @Description:
 */
public class MyInterceptor implements Interceptor {

    @Override
    public boolean before(Object proxy, Object torget, Method method, Object[] args) {
        System.out.println("反射方法前逻辑");
        return false;//不反射被代理对象原有方法
    }

    @Override
    public void around(Object proxy, Object torget, Method method, Object[] args) {
        System.out.println("取代了被代理对象的方法");
    }

    @Override
    public void after(Object proxy, Object torget, Method method, Object[] args) {
        System.out.println("反射方法后逻辑");
    }
}

  • JDK动态代理与拦截器
package interceptor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/12 20:30
 * @Description:
 */
public class InterceptorJdkProxy implements InvocationHandler {

    private Object target;//真实对象
    private String interceptorClass =null;//拦截器全限定名

    public InterceptorJdkProxy(Object target, String interceptorClass) {
        this.target = target;
        this.interceptorClass = interceptorClass;
    }

    /**
     * 绑定一个委托对象并返回一个【代理占位】
     * @param target 真实对象
     * @param interceptorClass 代理对象【占位】
     * @return
     */
    public  static Object bind(Object target, String interceptorClass){
        //取得代理对象
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),
                new InterceptorJdkProxy(target,interceptorClass));
    }

    /**
     * 通过代理对象调用方法,首先调用这个方法
     * @param proxy 代理对象
     * @param method 方法,被调用方法
     * @param args 方法的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (interceptorClass ==null){
            //如果没有拦截器,直接反射原有方法
            return method.invoke(target,args);
        }

        Object result = null;
        //通过反射生成拦截器
        Interceptor interceptor = (Interceptor)Class.forName(interceptorClass).newInstance();
        //调用前置方法
        if (interceptor.before(proxy,target,method,args)){
             result = method.invoke(target,args); //反射原有方法
        }else{//返回false则执行around方法
            interceptor.around(proxy,target,method,args);
        }
        //后置方法
        interceptor.after(proxy,target,method,args);
        return result;
    }


}

  • 测试类
package interceptor;

import agent.jdk.HelloWorld;
import agent.jdk.HelloWorldImpl;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/12 21:04
 * @Description:
 */
public class Test {
    public static void main(String[] args) {
        HelloWorld proxy = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImpl(),"interceptor.MyInterceptor");
        proxy.sayHelloWorld();
    }
}

2.4责任链模式(多拦截器)

  • 创建三个拦截器,继承之前定义好的Interceptor
package interceptor.responsibilitychain;

import interceptor.Interceptor;

import java.lang.reflect.Method;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/13 10:15
 * @Description:
 */
public class Interceptor1 implements Interceptor {
    @Override
    public boolean before(Object proxy, Object torget, Method method, Object[] args) {
        System.out.println("拦截器一的before方法");
        return true;
    }

    @Override
    public void around(Object proxy, Object torget, Method method, Object[] args) {

    }

    @Override
    public void after(Object proxy, Object torget, Method method, Object[] args) {
        System.out.println("拦截器一的after方法");
    }
}

package interceptor.responsibilitychain;

import interceptor.Interceptor;

import java.lang.reflect.Method;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/13 10:15
 * @Description:
 */
public class Interceptor2 implements Interceptor {
    @Override
    public boolean before(Object proxy, Object torget, Method method, Object[] args) {
        System.out.println("拦截器二的before方法");
        return true;
    }

    @Override
    public void around(Object proxy, Object torget, Method method, Object[] args) {

    }

    @Override
    public void after(Object proxy, Object torget, Method method, Object[] args) {
        System.out.println("拦截器二的after方法");
    }
}

package interceptor.responsibilitychain;

import interceptor.Interceptor;

import java.lang.reflect.Method;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/13 10:15
 * @Description:
 */
public class Interceptor3 implements Interceptor {
    @Override
    public boolean before(Object proxy, Object torget, Method method, Object[] args) {
        System.out.println("拦截器三的before方法");
        return true;
    }

    @Override
    public void around(Object proxy, Object torget, Method method, Object[] args) {

    }

    @Override
    public void after(Object proxy, Object torget, Method method, Object[] args) {
        System.out.println("拦截器三的after方法");
    }
}

  • 下面测试责任链模式上的多拦截器
package interceptor.responsibilitychain;

import agent.jdk.HelloWorld;
import agent.jdk.HelloWorldImpl;
import interceptor.InterceptorJdkProxy;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/13 10:24
 * @Description:
 */
public class Test {
    public static void main(String[] args) {
        HelloWorld proxy1 = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImpl(),"interceptor.responsibilitychain.Interceptor1");
        HelloWorld proxy2 = (HelloWorld) InterceptorJdkProxy.bind(proxy1,"interceptor.responsibilitychain.Interceptor2");
        HelloWorld proxy3 = (HelloWorld) InterceptorJdkProxy.bind(proxy2,"interceptor.responsibilitychain.Interceptor3");
        proxy3.sayHelloWorld();
        /*
            拦截器三的before方法
            拦截器二的before方法
            拦截器一的before方法
            hello,world
            拦截器一的after方法
            拦截器二的after方法
            拦截器三的after方法
        */
    }
}

三:观察者(Observer)模式(发布订阅模式)

观察者模式需要同时存在观察者和被观察者双方,其中观察者可以是多个,需要继承的类为java.util.Observable。下面代码定义了被观察 ,一个产品列表

package observer;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/13 10:59
 * @Description:
 */
public class ProductList extends Observable {
    private List productList = null;//产品类表
    private static ProductList instance;//类唯一实例

    private ProductList() {
    }//构造方法私有化,避免通过new构造对象,而是通过getInstace方法获得产品列表,这里使用的是单例模式

    /**
     * 取得唯一实例
     * @return 产品列表唯一实例
     */
    public static ProductList getInstance(){
        if (instance == null){
            instance = new ProductList();
            instance.productList = new ArrayList<>();
        }
        return instance;
    }

    /**
     * 增加观察者(电商接口)
     * @param observer 观察着
     */
    public void addProductListObserver(Observer observer){
        this.addObserver(observer);
    }

    public void addProduct(String newProduct){
        productList.add(newProduct);
        System.out.println("产品列表更新了产品"+newProduct);
        this.setChanged();//设置被观察对象发生变化
        this.notifyObservers(newProduct);//通知观察者,并传递新产品
    }


}

下面定义观察者(需要实现java.util.Observer接口的update方法):

  • 观察者一
package observer;

import java.util.Observable;
import java.util.Observer;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/13 15:46
 * @Description: 京东电商接口
 */
public class JingDongObserver implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        String newProduct = (String) arg;
        System.out.println("发布新产品【"+newProduct+"】同步到京东商城");
    }
}

  • 观察者二
package observer;

import java.util.Observable;
import java.util.Observer;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/13 15:49
 * @Description:
 */
public class TaoBaoObserver implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        String newProduct = (String) arg;
        System.out.println("发布新产品【"+newProduct+"】同步到淘宝商城");
    }
}

测试

package observer;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/13 15:50
 * @Description:
 */
public class Test {
    public static void main(String[] args) {
        ProductList observable = ProductList.getInstance();
        TaoBaoObserver taoBaoObserver = new TaoBaoObserver();
        JingDongObserver jingDongObserver = new JingDongObserver();
        observable.addObserver(taoBaoObserver);
        observable.addObserver(jingDongObserver);
        observable.addProduct("新增产品一");
        /*输出
        * 产品列表更新了产品新增产品一
          发布新产品【新增产品一】同步到京东商城
          发布新产品【新增产品一】同步到淘宝商城
        * */
    }
}

其中主方法中第四行和第五行是对被观察者注册观察者,这样才能让观察者监控到被观察者的变化

四:工厂模式和抽象工厂模式

4.1普通工厂模式

图示如下

其中IProduct下有五个实现类,其中用户可以通过编号来从工厂管理处获取需要的产品

4.2抽象工厂模式

抽象工厂可以先客户端提供一个接口,使得客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象,其中建立一个工厂,该工厂能够封装和简化使用者的调用,而调用者无需知道具体工厂的规则,示意图如下:

五:建造者(Builder) 模式

Buidler模式是一种分步构造对象模式,已旅游套票为例,一次性构建套票对象较为困难,所以采用分步构造
JAVA设计模式示例代码_第1张图片
用一个配置类对所有步骤进行统筹,然后将所有的信息交由构造器来完成构建对象
JAVA设计模式示例代码_第2张图片
创建一个实例TicketHelper,作为配置类,它能一步步完成构建对象

package Builder;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/13 16:55
 * @Description:
 */
public class TicketHelper {
    public void  buildAdult(String info){
        System.err.println("构建成人票逻辑"+info);
    }

    public void buildChildrenForSeat(String info){
        System.err.println("构建有座儿童票逻辑"+info);
    }

    public void buildChildrenNoSeat(String info){
        System.err.println("构建无座儿童票逻辑"+info);
    }

    public void buildElderly(String info){
        System.err.println("构建老年人票逻辑"+info);
    }
    public void buildSoldier(String info){
        System.err.println("构建军人及其家属票逻辑"+info);
    }


}

构建类

package Builder;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/13 22:10
 * @Description:
 */
public class TicketBuilder {
    public static Object builder(TicketHelper helper){
        System.out.println("通过ticketHelper 构建套票信息");
        return null;
    }
}

测试

package Builder;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/13 22:13
 * @Description:
 */
public class Test {
    public static void main(String[] args) {
        TicketHelper helper = new TicketHelper();
        helper.buildAdult("成人票");
        helper.buildChildrenForSeat("有座儿童");
        helper.buildChildrenNoSeat("无座儿童");
        helper.buildAdult("成人票");
        helper.buildSoldier("军人及其家属票");
        Object ticket = TicketBuilder.builder(helper);

        /*
        * 构建成人票逻辑成人票
构建有座儿童票逻辑有座儿童
构建无座儿童票逻辑无座儿童
构建成人票逻辑成人票
构建军人及其家属票逻辑军人及其家属票
通过ticketHelper 构建套票信息
*/
    }
}

你可能感兴趣的:(JAVA设计模式示例代码)