当前位置:网站首页 > 技术博客 > 正文

html用什么软件写代码



要分析常用框架spring、mybatis、springboot、springcloud等的源码,首先要了解各种设计模式,因为框架里面应用了各种设计模式

学习设计模式最重要的是掌握设计思想和设计原则,理解了设计思想和设计原则并运用到平时的编码中是最重要的!!!

天天加班编程,编程到底都做的是什么?

  撸代码,加班撸代码,写接口、写类、写方法

为什么要做设计、用设计模式?

  代码会变,为应对变化,为了以后方便扩展。做到以不变应万变,做一个会偷懒的程序员!

首先是从现实出发理清现实,在写代码之前先从实际分析,然后就开始写代码,写代码时要区分出不变的代码和会变化的代码,会变得代码会怎么变,使用者如何隔绝这种变化,所谓的隔绝这种变化就是不让调用者感知到内部的变化,只需要很简单的方式就能使用不必关心内部的逻辑,这样的话就要用到各种设计模式。不同的变化方式对应不同的设计模式。

设计的最终体现:如何来定义类、接口、方法

  定义功能使用者和功能提供者间的接口
3)为什么要有接口?
  隔离变化

1. 找出变化,分开变化和不变的

  隔离,封装变化的部分,让其他部分不受它的影响。

2. 面向接口编程 ——隔离变化的方式

  使用者使用接口,提供者实现接口。“接口”可以是超类!

3. 依赖倒置原则(里氏替换原则)——隔离变化的方式

  依赖抽象,不要依赖具体类!

4. 对修改闭合,对扩展开放——隔离变化的方式

  可以继承一个类或者接口扩展功能,但是不能修改类或者接口的原有功能

5. 多用组合,少用继承——灵活变化的方式

  “有一个”可能比“是一个”更好。

6. 单一职责原则——方法设计的原则

  每个方法只负责一个功能,不要把很多功能写在一个方法里面

应用设计模式的目的:

易扩展,易维护

少改代码,不改代码

示例:

京东、天猫双十一促销,各种商品有多种不同的促销活动:
满减:满400减50
每满减:每满100减20
数量折扣:买两件8折、三件7折
数量减:满三件减最低价的一件
……
顾客下单时可选择多种促销活动的其中一种来下单
后端代码中如何来灵活应对订单金额的计算?以后还会有很多的促销活动出现!

控制器OrderController.java

OrderService.java改怎么来写呢

营销活动有很多,这个switch会变得很庞大,不利于维护,并且很容易引入新的问题

把每个促销算法单独抽出一个方法,新加入一个促销活动只需要新增一个方法和case就可以了

这里利用了设计原则的方法设计原则:单一职责原则

但是这样写还会存在如下问题:

营销活动经常变,这个switch就得经常改,还得不断加促销的算法方法…….

改代码是bug的源泉,我们希望少改动OrderService!!!

分析:这里变的是什么?

  促销的金额的算法!同一行为的不同算法!

我们不希望OrderService被算法代码爆炸!

同一行为的不同算法实现,我们可以用接口来定义行为,不同的算法分别去实现接口。

这里利用了设计原则:对修改关闭,对扩展开放!

这就是策略模式的应用!

策略模式的的定义:

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们可以相互替换,让算法独立于使用它的用户而独立变化。

但是switch中的代码还是会不断变!!!switch中需要知道所有的实现!

如何让OrderService的代码不要改变?

  把变的部分移出去!改怎么移呢?

这是简单工厂模式:所有产品由一个工厂创建

想要工厂中的代码也不要随促销的变化而变化,你觉得该怎么办?

方式一:promotion = beanName

  把各种促销算法的实现交给spring容器来管理,用户选择的促销活动promotion 作为bean的名字,在PromotionCalculationFactory 工厂里面通过getBean("promotion")就能拿到各种促销算法的实现了

方式一的伪代码实现:

spring里面的bean配置:

PromotionCalculationFactory 工厂改写:

方式二: 配置promotion与实现类的对应关系

  把用户选择的促销活动promotion和对应的促销算法的实现类放到map里面,或者存到数据库里面,在PromotionCalculationFactory 工厂里面通过map.get("promotion"),或者从数据库里面获取对应促销算法的实现类路径通过Class.forName("促销算法的实现类路径")就能拿到各种促销算法的实现了

方式二的伪代码实现:

PromotionCalculationFactory 工厂改写:

一个工厂负责创建所有实例。比如上面的策略模式中使用的就是简单工厂模式

根据传入的工厂类型参数String创建对应的实例(产品)

父类中定义工厂方法,各子类在+factoryMethod():Product方法里面实现具体的实例创建

使用者持有具体的工厂ChildAClass、ChildBClass、ChildCClass,传入对应的工厂ChildAClass、ChildBClass、ChildCClass创建对应的工厂实例

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

使用者调用FactoryProducer的getFactory(type)方法传入type,type为AFactory、BFactory、CFactory对应的类型,就会返回对应的工厂AFactory、BFactory、CFactory,不需要传入AFactory、BFactory、CFactory,因为type已经跟AFactory、BFactory、CFactory绑定了。

示例:促销活动可多重叠加,该如何灵活实现订单金额计算?

OrderController

OrderService

装饰者模式的定义:以装饰的方式,动态地将责任附加到对象上。

说明:

不改变具体类代码(被装饰者ConcreteComponent),动态叠加增强行为功能。

若要扩展功能,装饰者提供了比继承更有弹性的替代方案

相较于前面的for循环,有何区别?

  当需要对一个类的多个方法进行增强,使用者会随意使用被增强方法时,for循环就不够灵活了。

责任链和装饰者模式完成的是相同的事情。

装饰者模式-代码示例:

共同的需装饰的行为定义成接口

被装饰者实现接口Component

装饰者实现接口Component

装饰者派生出的装饰者

调用示例:

输出结果:

concrete-object + A

110

代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。

在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

作用:不改变原类的代码,而增强原类对象的功能,可选择前置、后置、环绕、异常处理增强

代理模式的类图:

类图与装饰者模式一样,那么代理模式和装饰者模式有什么区别呢?

代理模式意在在代理中控制使用者对目标对象的访问,以及进行功能增强。装饰者模式意在对功能的叠加,比如对多种促销活动的叠加

代理模式有两种实现方式:

静态代理:由程序员创建或由特定工具自动生成代理类源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

动态代理:代理类在程序运行时,运用反射机制动态创建而成。

静态代理事先知道要代理的是什么,而动态代理不知道要代理什么东西,只有在运行时才知道。

4.3.1 静态代理:

有一个土豪要找苍老师约会,他不能直接和苍老师约,需要经过一个中间代理Tony

需要被代理控制增强的行为定义成接口或者超类

代理和被代理的目标对象都要实现接口Girl

代理:

被代理的目标对象

土豪使用者

调用示例:

输出结果:

老板,这个我试过了,很不错,推荐给你!
身高可以,可以约!
老板,你觉得怎样,欢迎下次再约!

静态代理缺点:

  扩展能力差

    横向扩展:代理更多的类

    纵向扩展:增强更多的方法

  可维护性差

由于静态代理的扩展能力差、可维护性差,这就需要使用动态代理了!!!

4.3.2 动态代理

在运行时,动态为不同类的对象创建代理,增强功能。灵活扩展,易维护!

动态代理的实现方式:

JDK动态代理:只可对接口创建代理

CGLIB动态代理:可对接口、类创建代理

(1) JDK动态代理

在运行时,对接口创建代理对象

生成代理类$Proxy0的方法:

参数说明:

ClassLoader loader:类加载器

Class<?>[] interfaces:需要被代理的目标对象实现的接口,可以传入多个

InvocationHandler h:功能增强的接口

功能增强的接口:

参数说明:

Object proxy:被代理的目标对象(接口)

Method method:要调用的目标对象的方法

Object[] args:要调用的目标对象的方法的参数

被代理控制增强的行为生成接口:

Girl

Boy

被代理的目标对象

TeacherCang

TeacherChen

JDK动态代理

调用示例:

输出结果:

(2) cglib动态代理

cglib是什么?

cglib( Byte Code Generation Library),一个高层次的java字节码生成和转换的api库.

ASM:一个低层次的字节码操作库

它的主要用途

在运行期为类、接口生成动态代理对象。 以达到不改动原类代码而实现功能增强的目的

常在哪里用它?

  常在 AOP、test、orm框架中用来生成动态代理对象、拦截属性访问

如何使用它?

1)引入它的jar

2)学习它的API

https://github.com/cglib/cglib/wiki

cglib动态代理-类图和API

说明:

实现思想和前面的JDK动态代理一样,只是使用了不同的API。

代理类由Enhancer生成,代理类实现被代理的类或者接口,特定的功能增强的实现MyMethodInterceptor实现MethodInterceptor接口,特定的功能增强实现MyMethodInterceptor里面持有被代理的类或者接口target

eg2:cglib动态代理-代码示例

被代理对象的接口:

被代理对象:

cglib动态代理主类:

输出结果:

http web请求处理,请求过来后将经过转码、解析、参数封装、鉴权......一系列的处理(责任),而且要经过多少处理是可以灵活调整的。

将所有的处理都写在一个类中可否?

  不行

分成多个类如何灵活组合在一起?

责任链:所有的处理者都加入到这个链式,一个处理完后,转给下一个。

责任链模式具体实现步骤:

1)抽象出责任接口,具体责任逻辑实现责任接口。

2)根据处理过程需要,将具体责任实现逻辑组合成链

3)使用者使用链

典型代表:Filter(过滤器)、Intercept(拦截器)

责任链模式类图:

和装饰者模式的区别在哪里?

  装饰者模式意在功能的叠加,责任链模式意在链式的处理

eg:责任链模式代码示例

抽象出责任接口:

具体的责任逻辑实现责任接口:

ResponsibilityA

ResponsibilityB

责任链:

ResponsibilityChain

请求接口:

调用者调用示例

输出结果:

使用者依赖的接口与提供者的接口不匹配时,就加一层适配,而不改两端的代码。

适配器模式类图:

说明:

使用者使用Target接口,但是提供者Provider又没有实现Target接口,这个时候就需要加一层适配Adaper,Adaper里面持有Provider,在Adapter的methodA()方法里面调用Provider的methodB方法

和代理、装饰的区别在哪里?

  适配器模式不进行功能增强

使用方要完成一个功能,需要调用提供方的多个接口、方法,调用过程复杂时,我们可以再提供一个高层接口(新的外观),将复杂的调用过程向使用方隐藏。

外观(门面)模式类图:

这里使用了设计原则:最少知识原则(迪米特原则)

观察者模式类图:

说明:

主题Subject面向观察者接口Observer编程,主题里面可以添加、删除和通知观察者Observer;
注意每个观察者都有一个回调方法update,如果有变化就会在主题的notifyObservers()方法里面调用update方法,把最新的变化给到观察者

变化之处:观察者会变,观察者的数量会变。

不变:主题的代码要不受观察者变化的影响。

观察者模式定义:

定义了对象之间一对多的依赖关系,当一端对象改变状态时,它的所有依赖者都会收到通知并自动更新(被调用更新方法)。也称为:监听模式、发布订阅模式。提供一种对象之间松耦合的设计方式。

设计原则:为了交互对象之间的松耦合设计而努力!

Java.util. Observable 可被观察的(主题),具体主题扩展它。

java.util.Observer 观察者接口,具体观察者实现该接口。

主题Observable:

观察者接口Observer

使用代码示例:

输出结果:

示例:

请为你的系统设计一个命令行界面,用户可输入命令来执行某项功能。

系统的功能会不断增加,命令也会不断的增加。

如何将一项一项的加入到这个命令行界面?

如何让我们的命令程序写好以后,不因为功能的添加而修改,又可灵活的加入命令、功能。

命令模式类图:

命令模式的定义:

以命令的方式,解耦调用者与功能的具体实现者,降低系统耦合度,提供了灵活性。

适用场景:Servlet、Controller、线程池

命令模式伪代码示例:

命令模式与策略模式的区别:

命令模式类图:

策略模式类图:

区别:

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

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

示例:一个类对外提供了多个行为,同时该类对象有多种状态,不同的状态下对外的行为表现不同,我们该如何来设计该类,让它对状态可以灵活扩展?

如请为无人自动咖啡售卖机开发一个控制程序。

说明:用户可以在咖啡机上进行支付、退款、购买、取咖啡等操作

咖啡机状态转换图:

说明:

不同的状态下这四种操作将有不同的表现。如在没有支付的状态下,用户在咖啡机上点退款、购买、取咖啡,和在已支付的状态下做这三个操作。

普通实现:

如何让状态可以灵活扩展?

  从分析可以看出,变化的是状态,同时不同的状态同一个行为的表现不同,这样的话就可以把变化的状态抽象生成接口,然后不同的状态行为实现状态接口做该状态下的具体行为。这里可以采用状态模式

状态模式类图:

状态模式代码示例:

把变化的状态抽象生成接口State,里面含有不同状态下的行为方法

不同的状态实现状态接口State

没有支付状态

已支付状态

售出状态

售罄状态

使用了状态模式的咖啡机

状态模式、命令模式、策略模式的区别

状态模式类图:

命令模式类图:

策略模式类图:

区别:

状态模式应用于状态机的情况

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

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

请开发一个画图程序,可以画各种颜色不同形状的图像,请用面向对象的思想设计图像

分析:

1)比如有红、黄、蓝三种颜色

2)形状有方形、圆、三角形

3)圆可以是红圆、黄圆、蓝圆

变化:

会从两个维度发生变化:形状、颜色

任其在这两个维度各自变化,为这两个维度搭个桥,让他们可以融合在一起:桥接模式

桥接模式的实现步骤:

1)抽象:分别对各自的维度进行抽象,将共同部分抽取出来

2)组合:将抽象组合在一起(桥接)

桥接模式的定义:将多个维度的变化以抽象的方式组合在一起。使用者面向抽象。个维度间解耦,可自由变化。

饥汉式1——可用

饥汉式2——可用

懒汉式1——不可用

当两个线程同时进入if里面时就会创建两个实例,不是单例,线程不安全,所以不可用

懒汉式2——不推荐使用

线程安全,但不推荐使用。缺点是实例化后就不应该再同步了,效率低

懒汉式3——不可用

当两个线程同时进入if里面时就会产生两个实例,做不到单例

懒汉式4——双重检查——推荐使用

注意:volatile关键字修饰很关键,保证可见性,一个线程先创建了,其他线程就就会看到这个改变,不会再创建,如果没有这个关键字还是不能保证单例。

优点:线程安全;延迟加载;效率较高

懒汉式5——静态内部类方式——推荐使用

优点:避免了线程不安全,延迟加载,效率高

原理:类的静态属性只会在第一次加载类的时候初始化。在这里,JVM的加载机制帮助我们保证了线程安全性,在类进行初始化时,别的线程是无法进入的

懒汉式6——用枚举——推荐使用

示例:

当我们设计一个类时,我们能明确它对外提供的某个方法的内部执行步骤,但一些步骤,不同的子类有不同的行为时,我们该如何来设计该类?

可以用模板方法设计模式

优点:

1)封装不变的部分,扩展可变的部分

2)提取公共代码,便于维护。

3)行为由父控制,子类实现。

适用场景:

1)有多个子类共有的方法,且逻辑相同

2)重要的、复杂的方法,可以考虑作为模板方法

模板方法设计模式代码示例:

设计模式总结

这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用新的运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

  • 工厂模式(Factory Pattern)
  • 抽象工厂模式(Abstract Factory Pattern)
  • 单例模式(Singleton Pattern)
  • 建造者模式(Builder Pattern)
  • 原型模式(Prototype Pattern)

这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。

  • 适配器模式(Adapter Pattern)
  • 桥接模式(Bridge Pattern)
  • 过滤器模式(Filter、Criteria Pattern)
  • 组合模式(Composite Pattern)
  • 装饰器模式(Decorator Pattern)
  • 外观模式(Facade Pattern)
  • 享元模式(Flyweight Pattern)
  • 代理模式(Proxy Pattern)

这些设计模式特别关注对象之间的通信。

  • 责任链模式(Chain of Responsibility Pattern)
  • 命令模式(Command Pattern)
  • 解释器模式(Interpreter Pattern)
  • 迭代器模式(Iterator Pattern)
  • 中介者模式(Mediator Pattern)
  • 备忘录模式(Memento Pattern)
  • 观察者模式(Observer Pattern)
  • 状态模式(State Pattern)
  • 空对象模式(Null Object Pattern)
  • 策略模式(Strategy Pattern)
  • 模板模式(Template Pattern)
  • 访问者模式(Visitor Pattern)

设计原则总结

1. 变化隔离原则:找出变化,分开变化和不变的

  隔离,封装变化的部分,让其他部分不受它的影响。

2. 面向接口编程 ——隔离变化的方式

  使用者使用接口,提供者实现接口。“接口”可以是超类!

3. 依赖倒置原则(里氏替换原则)——隔离变化的方式

  依赖抽象,不要依赖具体类!

4. 开闭原则:对修改闭合,对扩展开放——隔离变化的方式

  可以继承一个类或者接口扩展功能,但是不能修改类或者接口的原有功能

5. 最少知道原则,又称迪米特法则

6. 多用组合,少用继承——灵活变化的方式

  “有一个”可能比“是一个”更好。

7. 单一职责原则——方法设计的原则

  每个方法只负责一个功能,不要把很多功能写在一个方法里面

说明:如果前面的设计思想和设计原则都忘记了,就要找出变化,区分出不变的和变化的,把变化的部分独立出接口,或者使用组合

示例代码获取地址:

https://github.com/leeSmall/FrameSourceCodeStudy/tree/master/design-mode-study

参考文章:

版权声明


相关文章:

  • seo有哪些经典的案例2025-02-10 12:30:05
  • 什么是ev3编程2025-02-10 12:30:05
  • 运算符=重载2025-02-10 12:30:05
  • 串口助手modbus rtu2025-02-10 12:30:05
  • sqlmap注入有几种注入方式2025-02-10 12:30:05
  • 微信小程序开发工具appid2025-02-10 12:30:05
  • redis缓存实战2025-02-10 12:30:05
  • c语言malloc.h2025-02-10 12:30:05
  • tftp工具下载2025-02-10 12:30:05
  • mysql8.0和5.7用哪个2025-02-10 12:30:05