设计模式总结

单例模式 Singleton

懒汉模式 lazy loading

有多种,用的不多,不推荐使用

饿汉模式

推荐使用,简单粗暴,没那么复杂,项目中用到最多的模式也是这个

public static T INSTANCE = new T();

private T (){};

最完美的模式 enum模式

effective java 作者推荐的模式,保证单例,且不会被反序列化实例出来(即不会被反射创建出来)

public enum T{
	INSTANCE;
}

策略模式 Strategy

最典型的例子是jdk的Comparator比较器。本质就是传个function进去。

public BiFunction<Integer,Integer,Integer> calculator;

public BiFunction<Integer,Integer,Integer> addiotnCalculator = (p0,p1)->p0+p1;
public BiFunction<Integer, Integer, Integer> multiplicationCalculator = (p0, p1) -> p0 * p1;

public int calculator (int param0,int param1){
	calculator = addiotnCalculator;
	//calculator = multiplicationCalculator;
	return calculator.apply(param0,param1);
}

工厂模式 Factory 以及 抽象工厂模式 AbstractFactory

工厂:实例不由自己去创建,而交给工厂创建,项目代码
抽象工厂:## 标题创建工厂的工厂

public class AbstractFactoryPattern {
    private static final Data DB_DMG = DataFactory.newFactory("Db").newDataInstance(new Object());
    private static final Data MC_DMG = DataFactory.newFactory("Redis").newDataInstance(new Object());

}

abstract class DataFactory{
    abstract Data newDataInstance(Object param);
    static DataFactory newFactory(String factoryName){
        if(Objects.equals(factoryName,"Db")){
            return new DbDataFactory();
        }
        if(Objects.equals(factoryName,"Redis")){
            return new RedisDataFactory();
        }
        DataFactory defaultFactory = null;
        return defaultFactory;
    }
}

class DbDataFactory extends DataFactory{
    Data newDataInstance(Object param){
        int tableId = 0;
        int dataId = 1;
        return new DbData(tableId,dataId);
    }
}

class RedisDataFactory extends DataFactory{
    Data newDataInstance(Object param){
        String reidsKey = "";
        return new RedisData(reidsKey);
    }
}

abstract class Data{
    abstract int get(int userId);
    abstract void set(int userId);
}

class DbData extends Data{
    int tableId;
    int dataId;

    public DbData(int tableId, int dataId) {
        this.tableId = tableId;
        this.dataId = dataId;
    }

    @Override
    int get(int userId) {
        /*mysql操作*/
        return 0;
    }

    @Override
    void set(int userId) {
        /*mysql操作*/
    }
}

class RedisData extends Data{
    String reidsKey;

    public RedisData(String reidsKey) {
        this.reidsKey = reidsKey;
    }

    @Override
    int get(int userId) {
        /*redis操作*/
        return 0;
    }

    @Override
    void set(int userId) {
        /*redis操作*/
    }
}

门面模式 Facade和Meidator

简单的说就是把所有的相关的操作全部聚合到一个类中

class Person(){
	int id;
	Clothes clothes;
	Pet pet;
	...
}

class PersonUtil{
	ClothesManager clothesManager;
	PetManager petManager;
	...

	/*通过id拿到clothes*/
	Clothes getClothes(int id){
		/*clothesManager里面有自己的业务逻辑*/
		clothesManager.get(id);
	}

	/*通过id拿到pet*/
	Pet getPet(int id){
		/*petManager里面有自己的业务逻辑*/
		petManager.get(id);
	}

	...
}

装饰器模式 Decorator

这个平时没怎么用到,理解的还不是很深,简单的用代码实现一下,方便后面自己理解

interface Decorator{
	void decorate();
}

class ADecorator implements  Decorator{
	void decorate(){
		
	}
}

class BDecorator implements  Decorator{
	Decorator decorator;

	public BDecorator(Decorator decorator){
		this.decorator = decorator;
	}
	
	void decorate(){
		/*自己需要的业务逻辑*/
		decorator.decorate();
	}
}

责任链 Chain Of Responsibility

非常重要,也非常实用。简单的来说就是用一个for循环
最典型的例子,filter的实现。
项目中的代码,判断技能是否命中:

private void executeSingle() {
		beforeCast(param);
		// 计算命中伤害前如果死亡则技能无效
		if (hasEffect(param)) {
			//技能命中业务代码
		} else {
			//技能没命中业务代码
		}
		endCast(param);
	}

boolean hasEffect(Param param){
	/*这里采用的就是责任链模式,若有个buff是必定闪避,则只要在改buff生成的
	status里面将hasEffect重新为return false,就可以实现该逻辑*/
	List<Status> statusList = param.getAllStatus();
	for(Status s:statusList){
		if(!s.hasEffect()){
			return false;
		}
	}
	//其他的判断
	return true;
}

观察者模式 Observer

同样非常重要,也非常实用。简单的来说就是将function存在一个list里面,然后触发某个时间可以依次执行list里面的函数。
resoucre,信息源,抛出event的地方,就是在哪里触发的
event,事件本身,可以理解为function的参数
listener,监听者,事件触发后的执行,可以理解为function本身
典型例子为键盘和鼠标的响应事件
在项目之中的应用

class EventDispatcher{
	private static HashMap<Class, List<ListenerWrap>> map;

	static{
		//这里将监听者注册到map里面,这里只是方便演示,项目中用的是反射将所有监听事件注册进来
		AListen aListen = new AListen();
		Method[] methods = aListen.getClass().getMethods();
        for (Method method:methods){
            EventInject ei = m.getAnnotation(EventInject.class);
			if(ei != null){
				map.get(ei.value).add(new ListenerWrap(method,aListen));
			}
        }
		
	}

	public static boolean dispatch(Event event) {
		List<ListenerWrap> listenerList = map.get(event.class);
		for(ListenerWrap l:listenerList){
			l.invoke(event);
		}
	}
}

class ListenerWrap(){
	public Method method;
	public Object inv;

	public 	ListenerWrap(Method method,Object inv){
		this.method = method;
		this.inv = inv;
	}

	invoke(Event event){
		method.invoke(inv,event);
	};
}

class Resoucre{
	void A(){
		//其他代码
		EventDispatcher.dispatch(new XEvent(Object param))
	}
}

class Event{}

class XEvent extends Event{
	Object param;

	public XEvent(Object param){
		this.param = param;
	}
}

class AListen{
	@EventInject(XEvent.class)
	public void listen(XEvent event){
		//业务逻辑
	}
}

组合模式 Composite

一个树状结构,分为叶子节点和非叶子节点
典型例子为文件系统

public class Composite {
    public static void main(String[] args) {
        Directory root = new Directory("root");
        File f1 = new File("file1");
        File f2 = new File("file1");
        Directory d1 = new Directory("directory1");
        Directory d2 = new Directory("directory2");
        root.addNode(f1);
        root.addNode(f2);
        root.addNode(d1);
        root.addNode(d2);
        File f11 = new File("file11");
        File f12 = new File("file12");
        d1.addNode(f11);
        d1.addNode(f12);
        File f21 = new File("file21");
        File f22 = new File("file22");
        d2.addNode(f21);
        d2.addNode(f22);
        print(root, 0);
    }

    private static void print(Node root, int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("--");
        }
        System.out.println(root.name);
        if (root instanceof Directory) {
            Directory d = (Directory) root;
            for (Node n : d.nodes) {
                print(n, depth + 1);
            }
        }
    }
}

abstract class Node {
    String name;

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

class File extends Node {
    public File(String name) {
        super(name);
    }
}

class Directory extends Node {
    List<Node> nodes = new ArrayList<>();

    public Directory(String name) {
        super(name);
    }

    void addNode(Node node) {
        nodes.add(node);
    }
}

享元模式 flyweight

池化技术,创建一个池回收对象,减少对象的创建和销毁
String,Integer,线程池,连接池都属于该模式

备忘录模式 Memento

数据持久化
java中采用serializable将对象序列化储存,利用transient关键字可以将字段不序列化

public class Memento {
    MementoSerializable m = new MementoSerializable();

    public static void main(String[] args) throws Exception{
        Memento memento = new Memento();
        memento.save();
        MementoSerializable nm = memento.load();
        /*MementoSerializable{id=0, name='dream', age=0}*/
        System.out.println(nm.toString());
    }

    private void save() throws Exception {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\MementoSerializable.data"));
        oos.writeObject(m);
        oos.flush();
        oos.close();
    }

    private MementoSerializable load() throws Exception{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\MementoSerializable.data"));
        MementoSerializable nm = (MementoSerializable)ois.readObject();
        ois.close();
        return nm;
    }
}

class MementoSerializable implements Serializable {
    int id = 0;
    String name = "dream";
    transient int age = 22;

    @Override
    public String toString() {
        return "MementoSerializable{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

原型模式 Prototype

对象的拷贝
java中实现Cloneable将对象浅拷贝,深拷贝则需要将对象的属性也加上Cloneable。另外String类型是属于深拷贝的,具体实现是String的池化技术和final关键字。

模板模式 Template

项目常用,比如说一个命令的接收,我们只需要关注doSome的具体业务实现,而不用关注全部的流程实现

public abstract class Father{
	public void receive(User u,Param param){
		Response re = new Response();
		doSome(u,param,re);
		sendResponse(u,re);
	}

	protected abstract void doSome(User u,Param param,Response re);
}

public class Child{
	@Override
	protected void doSome(User u,Param param,Response re){
		//dosomething
	}
}

代理模式 proxy

静态代理

与 decorate几乎一样

动态代理

使用Proxy.Proxy.newProxyInstance()方法

public class Main3 {
    public static void main(String[] args) {
        Movable c = (Movable)Proxy.newProxyInstance(Car.class.getClassLoader(), new Class[]{Movable.class},new CarInvocationHandler(new Car()));
        c.move();
    }
}

class CarInvocationHandler implements InvocationHandler{
    Movable m;

    public CarInvocationHandler(Movable m) {
        this.m = m;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before");
        Object result = method.invoke(m,args);
        System.out.println("end");
        return result;
    }
}

class Car implements Movable{

    @Override
    public void move() {
        System.out.println("car move");
    }
}

interface Movable{
    void move();
}

迭代器模式 Iterator

典型例子:List 的next()和hasNext()方法

访问者模式 visitor

适合结构固定的

建造者模式 Builder

实例时可以选择需要的参数进行实例,且不用写过多的构造方法

public class Main4 {
    int a;
    int b;
    int c;
    int d;
    int g;

    public static void main(String[] args) {
        Main4 m = new Buider().
                setA(1).
//                setB(2).
                setC(3).
//                setD(4).
                build();
    }
}

class Buider{
    Main4 m;

    Buider(){
        m = new Main4();
    }

    public Buider setA(int a){
        m.a = a;
        return this;
    }

    public Buider setB(int b){
        m.b = b;
        return this;
    }

    public Buider setC(int c){
        m.c = c;
        return this;
    }

    public Buider setD(int d){
        m.d = d;
        return this;
    }

    public Main4 build() {
        return m;
    }
}

适配器模式 Adapter

将接口类型不一致的两个类通过第三个类关联起来
典型例子 callable和Thread

public static void main(String[] args) throws Exception{
        Callable<Integer> c = ()->1;
        /*FutureTask充当适配器角色*/
        FutureTask<Integer> f = new FutureTask(c);
        Thread t = new Thread(f);
        t.start();
        System.out.println(f.get());
    }

命令行模式 Command

撤销(undo),回滚(rollback)等操作

总结

设计模式的本质就是多态,所以不用太过于纠结。做好四大性能和遵循六大原则就行
四大性能

  1. 可维护性 maintainability
  2. 可复用性 reusability
  3. 可扩展性 scalability/extensibility
  4. 灵活性 flexibility/mobility/adaptability

六大原则

  1. 单一职责原则 single responsibility principle
  2. 开闭原则 open-closed principle
  3. 依赖倒置原则 dependency inversion principle
  4. 接口隔离原则 interface segregation principle
  5. 里氏替换原则 Liskov Substitution principle
  6. 高内聚 低耦合原则 minimize coupling
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值