首页 > 其他分享 >设计模式问题汇总

设计模式问题汇总

时间:2024-11-23 20:01:34浏览次数:8  
标签:System String 汇总 代理 Movable 问题 new 设计模式 public

因为很多时候完成技术选型后,走逻辑的时候总发现软件设计中普遍存在(反复出现)的各种因为设计而产生的冗余性问题,就所提出的解决方案而言,总是没有一个很好的汇总,因此今天搬运一些常见的设计模式(虽然有好几种都没用过hhhhh)。

设计模式典型应用框架中的应用
工厂方法适合在单个产品上做纬度扩展
抽象工厂适合在产品族的纬度上扩展bean工厂
Mediator 调节模式消息中间件(内部之间调和)(居委会大妈)mq
Facade 门面模式将复杂的服务整合,当用户访问后,可以通过简单的方式访问到复杂的服务(包工头)
责任链模式需要用状态来确定责任是否完成,通常需要用boolean来确定Filter Interceptor,Filter中FilterChain负责调用的顺序,里面是一个递归的方法
Observer观察者事件处理模型
Decorator装饰器顾名思义,就是在原来的基础上在加一层装饰,装饰的类和被装饰的类都可以横向扩展(在开发的时候,就是类在继承,而方法在嵌套)在IO流中,比如Reader 包含InputStream
观察者模式Observer观察者很少和事件源打交道,主要是和事件打交道,和Listener,hook function,callback function 都是观察者很多系统中,Observer模式往往和负责责任链共同负责对于事件的处理,其中某一个observer负责是否将事件进一步传递
组合Composite树状结构专用模式可用于导航栏
享元Flyweight重复利用对象,共享元数据,有池化的概念String 就是这个模式,使用的时候 可以和组合模式一起使用
代理模式静态代理,动态代理,springAop,代理也实现被代理类的接口,并在代理类中将接口类作为成员变量有点类似 Decorator jdk实现的动态代理需要 实体类实现了接口 cglib可以对任何类进行动态代理
Iteratror迭代器容器,容器遍历其实就是多态的一个应用
Visitor访问者在结构不变的情况下动态改变对于内部元素的动作
ASMIteratror+Visitor+chainfresposibility
builder构建复杂的对象链式编程(在类的众多参数中,你只需要其中的一些时候,使用该模式,看代码)
Adapter(Wrapper)接口转换器相当于插线板的转接头一样,加一层
Bridge双纬度扩展分离抽象和具体
Command封装命令(doit和undo方法)别名:Action/Transaction
Prototype原型模式/克隆模式Object.clone() Object 自带clone模式有浅克隆和深克隆区分
Memento备忘录记录状态便于回滚记录快照(瞬时状态),存盘,使用File做序列化时,使用transient 表示透明的,不需要存盘,需要存盘的都需要实现序列化接口,或者父类实现序列化接口,在网络传输中序列化通常使用google的ProtoBuf
TemplateMethod模版方法(钩子函数)
State状态模式根据状态决定行为
Intepreter解析器动态脚本解析

记住典型的用法和类图

1

2

3

4

5

静态代理

/**
 * 问题:我想记录坦克的移动时间
 * 最简单的办法:修改代码,记录时间
 * 问题2:如果无法改变方法源码呢?
 * 用继承?
 * v05:使用代理
 * v06:代理有各种类型
 * 问题:如何实现代理的各种组合?继承?Decorator?
 * v07:代理的对象改成Movable类型-越来越像decorator了
 *
 */
public class Tank implements Movable {
​
    /**
     * 模拟坦克移动了一段儿时间
     */
    @Override
    public void move() {
        System.out.println("Tank moving claclacla...");
        try {
            Thread.sleep(new Random().nextInt(10000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
​
    public static void main(String[] args) {
​
        Tank t = new Tank();
        TankTimeProxy ttp = new TankTimeProxy(t);
        TankLogProxy tlp = new TankLogProxy(ttp);
        tlp.move();
​
//        new TankLogProxy(
//                new TankTimeProxy(
//                        new Tank()
//                )
//        ).move();
    }
}
​
class TankTimeProxy implements Movable {
    Movable m;
​
    public TankTimeProxy(Movable m) {
        this.m = m;
    }
​
    @Override
    public void move() {
        long start = System.currentTimeMillis();
        m.move();
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}
​
class TankLogProxy implements Movable {
    Movable m;
​
    public TankLogProxy(Movable m) {
        this.m = m;
    }
​
    @Override
    public void move() {
        System.out.println("start moving...");
        m.move();
        long end = System.currentTimeMillis();
        System.out.println("stopped!");
    }
}
​
interface Movable {
    void move();
}

动态代理

/**
 * 问题:我想记录坦克的移动时间
 * 最简单的办法:修改代码,记录时间
 * 问题2:如果无法改变方法源码呢?
 * 用继承?
 * v05:使用代理
 * v06:代理有各种类型
 * 问题:如何实现代理的各种组合?继承?Decorator?
 * v07:代理的对象改成Movable类型-越来越像decorator了
 * v08:如果有stop方法需要代理...
 * 如果想让LogProxy可以重用,不仅可以代理Tank,还可以代理任何其他可以代理的类型
 * (毕竟日志记录,时间计算是很多方法都需要的东西),这时该怎么做呢?
 * 分离代理行为与被代理对象
 * 使用jdk的动态代理
 *
 * v09: 横切代码与业务逻辑代码分离 AOP
 * v10: 通过反射观察生成的代理对象
 * jdk反射生成代理必须面向接口,这是由Proxy的内部实现决定的
 */
public class Tank implements Movable {
​
    /**
     * 模拟坦克移动了一段儿时间
     */
    @Override
    public void move() {
        System.out.println("Tank moving claclacla...");
        try {
            Thread.sleep(new Random().nextInt(10000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
​
    public static void main(String[] args) {
        Tank tank = new Tank();
​
        System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles","true");
​
        Movable m = (Movable)Proxy.newProxyInstance(Tank.class.getClassLoader(),
                new Class[]{Movable.class}, //tank.class.getInterfaces()
                new TimeProxy(tank)
        );
​
        m.move();
​
    }
}
​
class TimeProxy implements InvocationHandler {
    Movable m;
​
    public TimeProxy(Movable m) {
        this.m = m;
    }
​
    public void before() {
        System.out.println("method start..");
    }
​
    public void after() {
        System.out.println("method stop..");
    }
​
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //Arrays.stream(proxy.getClass().getMethods()).map(Method::getName).forEach(System.out::println);
​
        before();
        Object o = method.invoke(m, args);
        after();
        return o;
    }
​
}
​
interface Movable {
    void move();
}

链式编程 builder模式

public class Person {
    int id;
    String name;
    int age;
    double weight;
    int score;
    Location loc;
​
    private Person() {}
​
    public static class PersonBuilder {
        Person p = new Person();
​
        public PersonBuilder basicInfo(int id, String name, int age) {
            p.id = id;
            p.name = name;
            p.age = age;
            return this;
        }
​
        public PersonBuilder weight(double weight) {
            p.weight = weight;
            return this;
        }
​
        public PersonBuilder score(int score) {
            p.score = score;
            return this;
        }
​
        public PersonBuilder loc(String street, String roomNo) {
            p.loc = new Location(street, roomNo);
            return this;
        }
​
        public Person build() {
            return p;
        }
    }
  public static void main(String[] args) {
        Person p = new Person.PersonBuilder()
                .basicInfo(1, "zhangsan", 18)
                //.score(20)
                .weight(200)
                //.loc("bj", "23")
                .build();
    }
}
​
class Location {
    String street;
    String roomNo;
​
    public Location(String street, String roomNo) {
        this.street = street;
        this.roomNo = roomNo;
    }
}

标签:System,String,汇总,代理,Movable,问题,new,设计模式,public
From: https://blog.csdn.net/qq_56394739/article/details/143990611

相关文章

  • 构造交互题汇总
    构造给定直径个数构造树一听到构造题,被吓怕了。就写了个单个菊花的。k这么大一眼多个菊花。还有剩余打个表发现2或3个菊花满了,这就是正解。KTSC2024R2岛屿简述题意:给定一个\(n\)多边形以及其三角划分,对于以这张图为基础进行如下构造:取出一个三角形\((a,b,c)\),在其......
  • 设计模式之PIMPL模式
    设计模式之PIMPL模式PIMPL是指pointertoimplementation,又称作“编译防火墙”,是实现“将文件间的编译依存关系降至最低”的方法之一。PIMPL模式是一种减少代码依赖和编译时间的C++编程技巧,其基本思想是将一个外部可见类的实现细节(一般是通过私有的非虚成员)放在一个单独的实现类......
  • 【K8S问题系列 | 15】资源配额不足导致Pod无法调度的场景如何处理
    在Kubernetes中,资源配额不足可能导致Pod无法调度,这种情况通常发生在命名空间的资源使用达到了设定的上限。以下是一些处理这类情况的策略和方法:1.监控资源使用情况实施监控使用监控工具(如Prometheus和Grafana)实时监控命名空间和集群的资源使用情况。设置告警规......
  • Mathtype 常用功能技巧汇总
    注:本文为“Mathtype常用功能/公式使用技巧”系列文章合辑。未整理去重。Mathtype使用技巧汇总发布时间:2021-03-1019:15:12在使用Word,PPT等制作文档时,很多时候会需要用特殊符号,特别是理工科的学生在写论文时会用到大量的公式。市面上有很多这样的软件都需要......
  • 设计模式之 模板方法模式
    模板方法模式是行为型设计模式的一种。它定义了一个算法的骨架,并将某些步骤的实现延迟到子类中。模板方法模式允许子类在不改变算法结构的情况下重新定义算法的某些特定步骤。模板方法模式的核心在于:封装算法的骨架:通过父类中的模板方法定义算法的执行顺序和框架,保证算法结构......
  • Kafka创建不了topic问题,定位1个月的现场血案,居然如此简单
    背景        2022年某天,我还在happy的看着电影。突然,手上握着的红米手机响起了周杰伦《回到过去》的铃声。哟,现场童鞋又来电话了,一接听电话,就响起了比较焦急的声音,“哥,现场有个Kafka集群创建不了topic了,赶紧帮忙看下!”,不爽,今天是周六,本来休息的时间,但是谁叫咱们有现场......
  • 进程与线程的区别(详解)(包括线程与进程的调度问题)
    前言:    计算机的发展是飞速的,从底层的算术逻辑单元ALU(Arithmetic&LogicUnit)、控制单元CU(ControlUnit),到中央处理器CPU(CenterProcessUnit)。    发展是非常迅速的,如今我们需要要深刻认识计算机,学会计算机是如何"管理"所有的"程序"正常运行,如何合理"......
  • 深圳大学-算法设计与分析-实验2-分治法求最近点对问题
    前言说明一门没什么意义的课程,学算法不如直接刷题,这门课纯答辩,本人写的报告也很答辩,可能还有错误,仅供参考,慎抄!实验目的(1)掌握分治法思想。(2)学会最近点对问题求解方法。实验内容对于平面上给定的N个点,给出所有点对的最短距离,即,输入是平面上的N个点,输出是N点中具有最短......
  • 深圳大学-算法设计与分析-实验4-动态规划(鸡蛋掉落问题)
    前言说明一门没什么意义的课程,学算法不如直接刷题,这门课纯答辩,本人写的报告也很答辩,可能还有错误,仅供参考,慎抄!实验目的(1)掌握动态规划算法设计思想。(2)掌握鸡蛋坠落问题的动态规划解法。实验内容动态规划将问题划分为更小的子问题,通过子问题的最优解来重构原问题的最......
  • vue.js学习知识点(汇总)
     Vue是什么?Vue是一个用于构建用户界面的渐进式框架1.构建用户界面:基于数据动态渲染页面2.渐进式:循序渐进的学习3.框架:一套完整的项目解决方案,提升开发效率↑(理解记忆规则)   规则→官网创建Vue实例,初始化渲染的核心步骤1.准备容器2.引包(......