Java设计模式

单例模式

单例模式是指一个类保证只有一个实例,下面简单介绍一下单例模式的实现方式:

实现单例模式注意两点:

  • 构造函数必须声明为private

  • 变量必须声明为private static


懒汉 线程不安全

public class Singleton {

    private static Singleton singleton;

    private Singleton() {

    }

    public static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}


接下来为了保证能够在多线程下正常工作:

线程安全的实现方式:

public class Singleton {

    private static Singleton singleton;

    private Singleton() {

    }

    public static synchronized Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

这种情况具备很好的lazy loading,但是效率低


代理模式

代理模式, 顾明思议就是让别人给你做事, 比如说我们要租房子,平时又没有时间, 所以只好找房产中介来为我们找房子,我们只需要告诉中介要找什么的房子 大概什么价位就可以了, 那么房产中介就是所谓的代理:

说说代理之前我们来看一个例子吧:

   定义一个接口

public interface IHello {
    void  sayHello(String name);
}

   定义实现类:

public class IHelloImpl implements IHello {

    @Override
    public void sayHello(String name) {
        System.out.println("Hello " + name);
    }
}

   那么如果我想在System.out.println("Hello: " + name)之前加before() 和之后加 after() 用于测试方法的性能监控, 很多人可能会说直接这样好了:

public class IHelloImpl implements IHello {

    @Override
    public void sayHello(String name) {
        before();
        System.out.println("Hello " + name);
        after();
    }
    
    public void before(){
        System.out.println("Before");
    }
    
    public void after(){
        System.out.println("After");
    }
}

  这种做法在大型项目中会有一个问题, 会造成项目中代码冗余, 扩展性不高, 那么能不能让一个专门的类去执行Before() 和After() 方法呢 当然是可以的 这就是代理模式的由来:


   接下来我们定义一个代理类:

public class IHelloProxy implements IHello {

    private IHello hello;

    public IHelloProxy() {
        this.hello = new IHelloImpl();
    }

    @Override
    public void sayHello(String name) {
        before();
        hello.sayHello(name);
        after();
    }

    public void before() {
        System.out.println("Before");
    }

    public void after() {
        System.out.println("After");
    }

    public static void main(String[] args) {
        IHello hello = new IHelloProxy();
        hello.sayHello("test");
    }
}


   运行后的结果为:

Before
Hello test
After

   那么这样是解决之前的问题了, 但是如果IHello 接口变了, 我们还需要在IHelloProxy里面去修改代码,代码的解耦性不好

   所以就出现了动态代理啦


   动态代理

       接下来我们来看下动态代理我们应该如何实现: 动态代理需要实现InvocationHandler接口:

public class DynamicProxy implements InvocationHandler {
    private Object obj;

    private DynamicProxy(Object obj) {
        this.obj = obj;
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object result = method.invoke(obj, args);
        after();
        return result;
    }

    public void before() {
        System.out.println("Before");
    }

    public void after() {
        System.out.println("After");
    }

    public static void main(String[] args) {
        IHello hello = new IHelloImpl();
        DynamicProxy dynamicProxy = new DynamicProxy(hello);
        IHello helloProxy = dynamicProxy.getProxy();
        helloProxy.sayHello("tester");
    }

    @SuppressWarnings("unchecked")
    public <T> T getProxy() {
        return (T)Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }
}

  

   cglib动态代理

public class CglibProxy implements MethodInterceptor {

    private Object obj;

    public Object getInstance(Object obj) {
        this.obj = obj;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.obj.getClass());
        enhancer.setCallback(this);//回调方法
        return  enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        before();
        Object result = method.invoke(obj, objects);
        after();
        return result;
    }

    public void before() {
        System.out.println("Before");
    }

    public void after() {
        System.out.println("After");
    }

    public static void main(String[] args) {
        IHello hello = new IHelloImpl();
        CglibProxy proxy = new CglibProxy();
        IHello hello1 = (IHello)proxy.getInstance(hello);
        hello1.sayHello("tester");
    }
}

   运行结果为:

Before
Hello tester
After

3.工厂模式

   

你可能感兴趣的:(java设计模式)