java设计模式

119 阅读3分钟

设计模式6大原则

  • 单一职责原则
  • 开放封闭原则
  • 里氏替换原则
  • 依赖倒置原则
  • 迪米特原则
  • 接口隔离原则

设计模式分类

根据目的准则分类,分为三大类:

  • 创建型设计模式,共5种:单列模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式
  • 结构型设计模式,共7种:
  • 行为型设计模式,共11种:

创建型设计模式,与对象的创建有关。

单列模式

推荐使用双重检查模式,静态内部类模式来创建单例模式

工厂方法模式

有抽象产品类,具体产品类,抽象工厂类,具体工厂类

具体工厂通过反射来生产不同的产品,增加产品时不需要修改工厂类,只需要增加具体的产品就可以了。

//核心代码如下

//抽象工厂类
public abstract class AbstractFactory {
    public abstract <T extends Computer> T createComputer(Class<T> cls);
}

//具体工厂类
public class ComputerFactory extends AbstractFactory {
    @Override
    public <T extends Computer> T createComputer(Class<T> cls) {
        Computer computer = null;
        String clsName = cls.getName();
        try {
            //通过反射生产不同的计算机
            computer = (Computer) Class.forName(clsName).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return (T) computer;
    }
}

结构型设计模式是从程序的结构上解决模块之间的耦合问题。

代理模式

代理模式也成为委托模式,现实生活中类似的场景有代购,打官司,中介等。

代理模式分为静态代理和动态代理。动态代理是在代码运行时通过反射来动态地生产代理类的对象,并确定到底来代理谁。

//抽象被代理类
public interface IShop {
    void buy();
}
//具体的被代理类
public class Shoper implements IShop {
    @Override
    public void buy() {
        System.out.println("买买买");
    }
}
//创建动态代理
public class DyHandler implements InvocationHandler {
    private Object obj;

    public DyHandler(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("在方法前动态插入一句话");
        Object result = method.invoke(obj, args);
        if (method.getName().equals("buy")) {
            System.out.println("动态代理了");
        }
        return result;
    }
}

    public static void main(String[] args) {
        IShop shoper = new Shoper();
        DyHandler handler = new DyHandler(shoper);
        ClassLoader classLoader = shoper.getClass().getClassLoader();
        //动态创建代理类
        IShop proxy = (IShop) Proxy.newProxyInstance(classLoader, shoper.getClass().getInterfaces(), handler);
        proxy.buy();
    }
}

可以看到关键的是InvocationHandler接口和Proxy.newProxyInstance方法,前者是java提供的动态代理的接口,后者是生产动态代理类的方法。创建被代理类,并作为参数传入实现了InvocationHandler接口的类里面,然后调用Proxy.newProxyInstance返回动态代理类,就可以调用被代理类的buy方法了,调用buy方法会调用invoke方法,所以可以在这里面插入代码。

享元模式

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

观察者模式

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

Java中内置了观察者模式的相关类与接口,分别是Observable类以及Observer接口,其中Observable实现了对Observer的增删以及通知等功能,而Observer提供了更新的接口

//观察者要实现Observer接口
public class WechatObserver implements Observer {
    private String name;

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

    @Override
    public void update(Observable o, Object arg) {
        System.out.println(name + "==" + arg);
    }
}
//被观察者要继承Observable类
public class MyObservable extends Observable {
    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        //设置状态改变了
        setChanged();
        //通知观者者
        notifyObservers("状态改变了" + state);
    }

}

   public static void main(String[] args) {
        WechatObserver observer = new WechatObserver("001");
        WechatObserver observer2 = new WechatObserver("002");
        WechatObserver observer3 = new WechatObserver("003");
        WechatObserver observer4 = new WechatObserver("004");

        MyObservable observable = new MyObservable();
        observable.addObserver(observer);
        observable.addObserver(observer2);
        observable.addObserver(observer3);
        observable.addObserver(observer4);

        observable.setState(2);
    }

关键的是在被观察者类里面要设置change是值为true,然后调用notifyObservers才有效,具体的可以看notifyObservers的源码