设计模式学习

设计模式学习

策略模式

工厂模式:

简单工厂:

一个工厂创建所有实例

工厂方法:

父类定义工厂方法 子类实现具体的实现

抽象工厂:

定义一个工厂的接口,所有的具体工厂实现接口

装饰者模式:

  1. 装饰者模式需要定义共同的定义行为的接口;
  2. 指的是在装饰者在被装饰着上面增加行为接口;
  3. 不改变具体代理 动态叠加增强行为功能
  4. 装饰着比继承提供了更为灵活的替代方案
  5. 装饰者持有一个被装饰着的对象。
  6. 继承装饰者类,并实现扩展功能

代理模式:

相对于装饰者模式而言,代理模式意味者在使用者控制使用者对目标对象的访问,以及增强功能。

静态代理:

在运行前已经生成了class类

动态代理:

在代理运行过程中,由于反射机制动态创建而成

JDK的动态代理

image

Java.lang.reflect.Proxy.newProxyInstance()类创建代理对象,

参数说明:类加载器ClassLoader,提供代理实现的接口,增强的Handler对象:需要实现java.lang.reflect.InvocationHandler接口;

Java.lang.reflect.invocationHandler().invoke() 提供增强功能z

被代理的对象

public class TeacherChen implements Boy {
	public boolean dating(char cup) {	}

	public void show() {//dosomething}
}

代理类的实现

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

interface Subject {
    void request();
}

class RealSubject implements Subject {
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

class MyInvocationHandler implements InvocationHandler {
    private Object realSubject;

    public MyInvocationHandler(Object realSubject) {
        this.realSubject = realSubject;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method invocation.");
        Object result = method.invoke(realSubject, args);
        System.out.println("After method invocation.");
        return result;
    }
}

public class Example {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        InvocationHandler handler = new MyInvocationHandler(realSubject);
        Subject proxySubject = (Subject) Proxy.newProxyInstance(
            Subject.class.getClassLoader(),
            new Class<?>[]{Subject.class},
            handler
        );

        proxySubject.request();
    }
}

测试代码

public class PlayGame {
	public static void main(String[] args) {
            System.out.println("JDK动态代理:");
		Boy tcc = new TeacherChen();
		Boy tony2 = (Boy) TonyCompany.proxy(tcc);
		tony2.dating('E');
		tony2.show();
		ProxyUtils.generateClassFile(Boy.class, tony2.getClass().getName());
	}
}
CGLIB的代理模式

image

创建代理对象

Enhancer.create():Obj

Enhancer.createClass():CLass

代码增强

Interface Callback

——>interface MethodInterceptor.intercept()

并持有被增强对象target:Obj

回调增强,对不同的方法实现不同的增强

Interface CallbackFilter.accept(method):int

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

class RealSubject {
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

class MyMethodInterceptor implements MethodInterceptor {
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before method invocation.");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("After method invocation.");
        return result;
    }
}

public class Example {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(RealSubject.class);
        enhancer.setCallback(new MyMethodInterceptor());

        RealSubject proxySubject = (RealSubject) enhancer.create();
        proxySubject.request();
    }
}

责任链模式

抽象一个责任接口

Responsibility.process(request,chian)

public class ResponsibilityChain {
	private List<Responsibility> responsibilitys;
	private int index = 0;
	public ResponsibilityChain() {		this.responsibilitys = new ArrayList<>();	}
	public void process(Request request) {
		if (this.index < this.responsibilitys.size()) {
			this.responsibilitys.get(index++).process(request, this);
		}
	}
	public void register(Responsibility res) {		
            this.responsibilitys.add(res);
	}
}

和装饰模式区别

装饰模式需要持有一个被装饰的对象,责任链将所有的责任链交给责任接口

适配器模式

使用者和提供者的接口不一致,增加一层适配者

外观模式

提供一个新的接口影藏复杂的调用过程影藏

观察者模式

一个被观察的主题接口 一个观察者接口

<interface> Observer.update(obj)
<interface>Subject.addObserver(observer)
                   .removeObserver(observer)
                   .notifyObservers();

Java.util.Observable 可被观察的主题,具体的主题扩展他

Java.util.Observer 观察者接口,具体观察者 实现这个接口

public static void main(String[] args) {
	Observable subject1 = new Observable() {
		public synchronized void notifyObservers(Object data) {
			this.setChanged();
			super.notifyObservers(data);
		}
	};
	subject1.addObserver(new Observer() {
		@Override
		public void update(Observable o, Object arg) {
			System.out.println("观察者1收到通知被更新了..." + arg);
		}
	});
	new Thread(()->{
		subject1.addObserver((o,arg)->{
			System.out.println(o.toString());
			System.out.println(arg.toString());
			System.out.println("观察者2收到通知被更新了..." + arg);
		});
		try {
			Thread.sleep(Integer.MAX_VALUE);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}).start();
	subject1.notifyObservers("change1");
	subject1.notifyObservers("change2");
}

命令模式

场景:命令行界面,用户可以输入命令执行某项功能;系统的功能在逐步增加,命令也在增加,

命令行程序

Receiver.commends:Map  
                   .register(String,Commend)
                   .receive(String)
 <interface>Commend.execute()

命令模式和策略模式的区别

策略模式侧重的是一个行为的多个算法实现,可以互换算法

命令模式侧重的是位多个行为提供灵活的执行方式

状态模式:

场景:一个类对外提供了多个状态,同时具有多个行为,不同的状态下的对外的行为不同。

<interface> State:pay() 
                  refund() 
                  buy() 
                  getCoffee()

对应每一个状态实现一个状态对象,不同的状态有不同的实例

桥接模式

在两个维度上比如形状和颜色维度进行设计模式

<abstract> Shape.color:Color
                   .draw()

单例模式

饥汉模式:

持有一个静态块对象或者静态属性的对象,使用公开的方法返回这个对象

懒汉模式:

错误示范:

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){
            synchronized (Singleton.class) {
                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;
    }
}
// 没有线程安全
public class Singleton {
//对象的可见性,在一个线程对对象做了更新后,其他对象3很有可能访问不到最新的对象   
//不能保证并发的线程不能看到线程变化的最新值
    private static volatile Singleton singleton;
    private Singleton(){}
    public static synchronized Singleton getInstance(){
        if (singleton == null){
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
//静态内部类:使用类加载机制
//类的静态属性只能在类加载的过程中一次加载,在类在加载的时候别的线程是无法进去的
public class Singleton {
    private Singleton(){}
    private static class SingletonInstance{
        private static final Singleton SINGLETON = new Singleton();
    }
    public static  Singleton getInstance(){
        return SingletonInstance.SINGLETON;
    }
}
使用枚举的方式
public enum Singleton {
    SINGLETON;
    public void whateverMethod(){}
}

模板方法模式

场景:当设计一个类,能明确他对外界提供的某个方法的内部执行步骤,但是有的步骤不同的类有有不同的行为。

public abstract class Game {
    protected abstract void init();
    protected abstract void start();
    protected abstract void end();
    public final void play(){
        init();
        start();
        end();
    }
} 

设计模式总结

image

设计模式原则

image

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值