网站后台的安全,邯郸网站设计怎么做,中国芯片制造最新消息,做弹弓教程网站文章目录 前言设计原则单一职责原则开闭原则里氏替换原则迪米特法则接口隔离原则依赖倒置原则 设计模式构建类型工厂模式抽象工厂建造者模式原型模式单例模式 结构型适配器模式桥接模式组合模式装饰器模式代理模式外观模式享元模式 行为模式责任链模式命令模式迭代器模式中介模… 文章目录 前言设计原则单一职责原则开闭原则里氏替换原则迪米特法则接口隔离原则依赖倒置原则 设计模式构建类型工厂模式抽象工厂建造者模式原型模式单例模式 结构型适配器模式桥接模式组合模式装饰器模式代理模式外观模式享元模式 行为模式责任链模式命令模式迭代器模式中介模式备忘录模式观察者模式状态模式策略模式模板模式访问者模式 总结 前言
okey,最近在写个小框架那么不免会用到设计模式相关的内容当然还有个原因就是要准备软考。所以的话我们今天的话把我们的设计模式重新过一遍当然这里注意的是由于每个人的理解是不同的话因此对于涉及模式来说我们的案例代码可能也是不太相同的。所以如果你觉的我这里的某些描述有点问题请在评论区我们一同探讨。那么在这里的话也是会有一些奇怪的比喻重在理解。
设计原则
设计原则是可以理解是我们的一种代码编写的建议规范。我们接下来的设计模式基本上都是同这几个设计原则相关的换句话说我们的设计模式可以帮助我们的代码在一定程度上符合规范我们的代码满足设计原则。那么为什么我们要学习使用设计模式呢
这个问题其实就好像我们为什么在学习高等数学的时候或者初等高中数学的时候为什么我们要学习二级结论要学习技巧的道理是一样的。如果有学习过考研数学的话我想你对于这些话印象会很深刻。很多固定的题目如果在第一步你没有想清楚思考出大致的解题链路你将很痛苦当然现在不仅仅是思路的问题还有计算能力的问题对于我们的代码同样如此
那么在这里我们一共有六个基本的设计原则 六大基本设计原则
单一职责原则
单一职责原则是一个基础的设计原则。其核心是保证我们写的每一类只做一个件事情。避免上帝类的出现导致代码臃肿不利于对扩展开放。
以我们人类社会为例子单一职责告诉我们每个人有属于每个人的角色
开闭原则
基于接口来进行声明配合单一职责原则实现对代码的扩展开放。在需要新功能的时候只需要实现新的接口然后通过机构模式来将其进行替换。
开闭原则告诉我们从事计算机软件开发时我们可以在同一行业内疯狂跳槽
里氏替换原则
继承必须具备超类的所有特性。对类进行分类实现不同的功能
举个例子龙生龙凤生凤老鼠的儿子会打洞。所有的子类继承父类都需要确保具备父类的所有的功能之后再新增新的功能。
迪米特法则
降低类之间的耦合不同角色做不同的事。只是向上开发的时候提供接口而提供实现。下级只需要为上级提供接口而不能提供具体实现具体实现可以由同级实现让上级调用。
接口隔离原则
单一职责是对类来说避免上帝的出现接口隔离原则则是对接口来说来避免上帝接口的出现。这个和里氏替换原则是息息相关的
依赖倒置原则
高层不能依赖底层。顶级接口实现可以依赖底层接口实现但是底层不能直接依赖高层同级可依赖。
口诀 单一职责尽可能自己做自己的事 开闭原则多加少改后面再配合工厂模式策略模式等等。 里氏替换原则我们需要继承和发扬中国传统文化子类必须具备超类的所有实现 迪米特法则尽可能提供接口服务保持一定的神秘感我只关心你能干什么你要什么你适合什么环境什么时候用你怎么用你 接口隔离原则接口多拆拆避免上帝出现同时提高复用性 依赖倒置原则上级要听上级的话上级派遣下级下级无权调用上级
设计模式
说完了基本的设计原则我们来看到我们的设计模式设计模式我们这里可以分为三大类。
构建类型结构类型行为类型
这个很好理解。因为最早的设计模式是土木老哥那边搞出来的。然后用在我们这边非常的牛逼。所以可以这样想象。盖一栋大楼我们需要哪些部件这些部件要如何组装耦合在一起完成功能。然后呢这些部件要怎么生产具备哪些功能。
当然话说回来由于我们的实际代码其实是很复杂的所以的话我们其实可能会出现你中有我我中有你的情况注意编码即可。
构建类型
工厂模式
okey, 那么接下来我们一个一个来玩玩。这里我们举一个生成汽车的例子 在这里我们首先定义了我们的汽车接口然后我们可以生产两种汽车。
public interface ICar {void run();
}
public class SuperCar implements ICar {Overridepublic void run() {System.out.println(我是超跑);}
}
public class Truck implements ICar {Overridepublic void run() {System.out.println(我是卡车);}
}
之后的话我们创建了一个工厂这个工厂可以帮助我们生成汽车
public class CarFactory {public static ICar buildCar(Class? extends ICar car) throws InstantiationException, IllegalAccessException {return car.newInstance();}
}
这里的话我们直接通过反射就可以创建一个对象了。于是在使用的时候就是这样
public class Test {public static void main(String[] args) throws InstantiationException, IllegalAccessException {ICar superCar CarFactory.buildCar(SuperCar.class);superCar.run();}
}
我们只需要传入到对应的类名即可。当然这里你会发现我们每次都是通过反射创建了一个新的对象。那么这个时候实际上我们可以再优化一下的还记得我们的SpringIOC容器嘛。实际上我们也可以来个简单一点的IOC容器
public class CarFactory {private static MapClass? extends ICar,ICar IOC new HashMap();static {IOC.put(SuperCar.class,new SuperCar());IOC.put(Truck.class,new Truck());}public static ICar buildCar(Class? extends ICar car) throws InstantiationException, IllegalAccessException {return car.newInstance();}public static ICar getBean(Class? extends ICar car){return IOC.get(car);}
}
我们这里只是略加改造加了一个HashMap来维护我们的对象即可。只是与Spring不同的是我们这里采用的是自己手动添加了对象而Spring是通过xml配置文件或者注解扫包等其他方式来完成了对象的注入。
学过Java反射的我们都知道当我们得到对象的时候尤其是类的时候我们是可以做非常多的操作的例如我们的方法增强等等。这里的话我们放出一张Spring的Bean周期你就明白了 在这里面BeanDefinition里面存放了一个JavaBean的一些包类等等信息通过这个可以得到初始化的对象。然后这里面有个Aware接口可以得到一些信息方便你自己在这边实例化前后做一些操作之后是PostProcessor。这边就是我们对方法进行增强了也就是AOP。因为我们这里要执行一些东西主要还是靠接口嘛。 当然里面实际上处理到的细节还是很多的。这里的话我们不做过多探讨以后机会话分享一些阅读源码的博客。当然按照我的风格基本上少不了看完这个东西之后手写一个lite版本的。先前我们其实写过了一个简单的Spring和MVC包括一个任务执行框架。
抽象工厂
我们刚刚是聊到了工厂模式其实我们抽象工厂和我们的工厂是一样的。区别在哪呢那就是生成的对象不同。实际上我们刚刚的工厂模式只是一个统称实际上我们刚刚的例子只是生成的一台汽车。那么实际上我们还可以生成汽车工厂。
于是我们刚刚只是生成汽车的工厂叫做简单工厂 现在在生产建造汽车的工厂的工厂叫做工厂方法 后来随着企业的状态不在满足生成汽车于是我们又开始生产飞机了这个时候我们有一个东西可以生产一个可以生产工厂的工厂这个时候这个玩意叫做抽象工厂
画个图你就明白了 说白了就是一层一层抽象。我们这里有个玩笑话遇事不决先抽象一层其实就是这个意思。你知道这里可能需要这个东西来完成但是我不知道这个东西具体怎么实现那没事先写个接口不着急定义方法再写个工厂或者其他的管理器等等这个东西可以生产或者管理那个接口。之后我们在讨论具体的实现。
这个的话就比较简单了说白了就是一层套一层。从简单工厂开始写再写到顶级的抽象工厂即可。
建造者模式
建造者模式其实就一句话化繁为简 还是拿到我们刚刚的例子我们有一台车。 车有轮子有发动机有架子假设就这写东西的话那么我们可以这样干
首先这个小项目长这个样 然后关系长这样
代码如下
public interface CarEngine {void engine();
}
public interface CarFrame {void frame();
}
public interface CarWheel {void wheel();
}
public class CarbonFibreFrame implements CarFrame {Overridepublic void frame() {System.out.println(碳纤维车架良好);}
}
public class MiQIWheel implements CarWheel {Overridepublic void wheel() {System.out.println(米其林轮胎温度正常);}
}
public class V8Engine implements CarEngine {Overridepublic void engine() {System.out.println(V8引擎启动);}
}
之后是我们的小汽车
public class GreatCar {CarFrame carFrame;CarEngine carEngine;CarWheel carWheel;public GreatCar(CarFrame carFrame, CarEngine carEngine, CarWheel carWheel) {this.carFrame carFrame;this.carEngine carEngine;this.carWheel carWheel;}public GreatCar() {}public void start(){carEngine.engine();carWheel.wheel();carFrame.frame();}
}
然后的话
public class Test {public static void main(String[] args) {GreatCar greatCar new GreatCar(new CarbonFibreFrame(), new V8Engine(), new MiQIWheel());greatCar.start();}
}
一辆小汽车完成构建。其实这个模式再我们写Controller的时候不自觉就会用到比如一个Controller里面有很多个Service。
当然同样的实际上你还可以再搞个HashMap维护这些组件直接add加入这个组件就可以了。然后遍历处理一下或者其他的。我自己在实现那个任务小框架的那个任务清单的实现的时候考虑的就是这个玩法。之后你再配合工厂模式去搞一下。
原型模式
什么是原型模式呢用户创建重复的对象同时还要保证性能的一张设计模式。 这个的话我们说实话没啥东西就是怎么快速创建对象的一些操作比如我们在创建的对象的时候我们可以把数据先预处理加载过来创建。在设计类对象的时候多注意模块化设计然后在创建多个对象的时候我们直接用Java的clone然后重写如果有需要的话clone 的方法给它额外添加数据。
举个例子我们创建试卷
这里的话我们核心就是看到这里
public class QuestionBank implements Cloneable{private String candidate; // 考生private String number; // 考号private ArrayListChoiceQuestion choiceQuestionList new ArrayList();private ArrayListAnswerQuestion answerQuestionList new ArrayList();public QuestionBank append(ChoiceQuestion choiceQuestion) {choiceQuestionList.add(choiceQuestion);return this;}public QuestionBank append(AnswerQuestion answerQuestion) {answerQuestionList.add(answerQuestion);return this;}Overridepublic Object clone() throws CloneNotSupportedException {QuestionBank questionBank (QuestionBank) super.clone();//对数据进行额外处理在这里是打乱题目序号questionBank.choiceQuestionList (ArrayListChoiceQuestion) choiceQuestionList.clone();questionBank.answerQuestionList (ArrayListAnswerQuestion) answerQuestionList.clone();// 题目乱序Collections.shuffle(questionBank.choiceQuestionList);Collections.shuffle(questionBank.answerQuestionList);// 答案乱序ArrayListChoiceQuestion choiceQuestionList questionBank.choiceQuestionList;for (ChoiceQuestion question : choiceQuestionList) {Topic random TopicRandomUtil.random(question.getOption(), question.getKey());question.setOption(random.getOption());question.setKey(random.getKey());}return questionBank;}public void setCandidate(String candidate) {this.candidate candidate;}public void setNumber(String number) {this.number number;}}注意看到他里面重新实现的clone方法即可。也即是说它在重新创建对象的时候做了一个加强
然后直接clone对象
public class QuestionBankController {private QuestionBank questionBank new QuestionBank();public QuestionBankController() {questionBank.append(new ChoiceQuestion(JAVA所定义的版本中不包括, new HashMapString, String() {{//省略创建试卷的过程}public String createPaper(String candidate, String number) throws CloneNotSupportedException {QuestionBank questionBankClone (QuestionBank) questionBank.clone();questionBankClone.setCandidate(candidate);questionBankClone.setNumber(number);return questionBankClone.toString();}}单例模式
这个的话是老朋友了想想我们经常使用的框架Spring就知道我们经常把我们的这种功能性代码作为一个Bean放到我们的IOC容器当中。那么什么东西适合单例呢
全局唯一变量无状态对象
那么这个代码的话我就不给了比较熟悉了。
当然这块的话我们的单例模式又分为懒汉模式饿汉模式。然后在并发环境下还要记得上锁在懒汉模式下
结构型
okey,接下来到了我们的结构型模式了。
适配器模式
这个我们直接举个非常常见的例子。那就是Mybatis配置多数据源或者说适应不同的配置的时候。我们就需要使用到我们的适配器模式。
注意的我们的适配器模式和我们的代理模式有点像但是目的不同 适配器模式的目标是实现接口的转换而代理模式的目标是对对象的访问进行控制
那么这个的话我们直接举个非常简单的例子就过去了。我们举个用老安卓充电线冲type-c的例子。这里的话我们搞个转换器其实就是适配器就可以完成充电了。
public interface Typec {//type-C接口void charge();
}
public class AndroidType {//安卓充电线public void chargeForOlderAndroid() {System.out.println(老安卓充电线);}}
public class AdapterForTypeC implements Typec {//转换器适配器private AndroidType androidType;public AdapterForTypeC(AndroidType androidType) {this.androidType androidType;}Overridepublic void charge() {androidType.chargeForOlderAndroid();}
}
然后装上就能happy了。
public class Test {public static void main(String[] args) {AdapterForTypeC adapterForTypeC new AdapterForTypeC(new AndroidType());adapterForTypeC.charge();}
}
桥接模式
这个模式的话和我们搞个写的建造者的代码其实很像其实就类似的。只不过这边重组合使用。 在桥接模式中抽象接口和实现的关系是通过桥接接口来建立的。抽象类包含了对实现类的引用这样就可以调用实现类的方法。抽象类和实现类可以在运行时动态地绑定和替换。
假设我们有一个 Shape 接口它定义了一个 draw 方法。我们还有两个实现类 Circle 和 Rectangle 分别表示圆形和矩形并且它们都有一个颜色属性。我们希望能够在不同的颜色下绘制不同形状的图形。
public interface Color {String getColor();
}然后我们定义两个实现类 Red 和 Green 来实现 Color 接口
public class Red implements Color {Overridepublic String getColor() {return Red;}
}public class Green implements Color {Overridepublic String getColor() {return Green;}
}接下来我们定义 Shape 接口并引入 Color 接口作为桥接接口
public interface Shape {void draw();void setColor(Color color);
}public class Circle implements Shape {private Color color;public Circle(Color color) {this.color color;}Overridepublic void draw() {System.out.println(Drawing Circle with color.getColor() color);}Overridepublic void setColor(Color color) {this.color color;}
}public class Rectangle implements Shape {private Color color;public Rectangle(Color color) {this.color color;}Overridepublic void draw() {System.out.println(Drawing Rectangle with color.getColor() color);}Overridepublic void setColor(Color color) {this.color color;}
}最后测试
public static void main(String[] args) {Color red new Red();Color green new Green();Shape circle new Circle(red);Shape rectangle new Rectangle(green);circle.draw();rectangle.draw();circle.setColor(green);rectangle.setColor(red);circle.draw();rectangle.draw();
}其实这个你会发现我们在写SpringBoot程序的时候经常这样干。
组合模式
组合模式用一颗树的形式来表述出我们的整个结构。 允许你将对象组合成树状结构来表示“整体-部分”的层次关系。组合模式使得用户对单个对象和组合对象的使用具有一致性。尤其是我们在优化我们的if-else判断的时候
举个例子
if 一个大的情况if 小的情况if ...elseelse
else if ...if ....这种依托if-else的情况下。 我们就可以用一个组件优化一下
if 一个大的情况大的情况的处理器情况
else if ...然后这个处理器里面你再处理处理。这里面可能会用到其他的设计模式。 这块的话我们举个权限验证的例子吧虽然我很想举个我自己写的那个小框架的例子但是比较抽象因为我没有给到对应的背景读者阅读会比较困难
okey, 现在我们来看到我们一个可能的权限验证的情况
public boolean hasPermission(User user, String permission) {if (user.getRoles() ! null) {for (Role role : user.getRoles()) {if (role.getPermissions() ! null) {for (Permission p : role.getPermissions()) {if (p.getName().equals(permission)) {return true;}}}}}return false;
}我们的需求是这样的 首先的话我们又这个Permession然后有role。然后有User。之后的话我们用户里面有规则。规则里面有权限。 然后为了统一我们都有一个统一接口
public interface Component {boolean hasPermission(String permission);
}
然后有一个定义权限的类
public class Permission implements Component {private String name;public Permission(String name) {this.name name;}Overridepublic boolean hasPermission(String permission) {return this.name.equals(permission);}
}之后是我们的 规则
public class Role implements Component {private ListComponent components;public Role() {this.components new ArrayList();}public void addComponent(Component component) {components.add(component);}public void removeComponent(Component component) {components.remove(component);}Overridepublic boolean hasPermission(String permission) {for (Component component : components) {if (component.hasPermission(permission)) {return true;}}return false;}
}规则里面也要看权限。就是看这个规则有没有对应到这个权限我们在查看用户有没有这个权限的时候是看到用户的这些规则里面有没有这个权限有的话就是true
然后是我们的User类
public class User implements Component {private ListComponent components;public User() {this.components new ArrayList();}public void addComponent(Component component) {components.add(component);}public void removeComponent(Component component) {components.remove(component);}Overridepublic boolean hasPermission(String permission) {for (Component component : components) {if (component.hasPermission(permission)) {return true;}}return false;}
}
最后是我们的测试代码
public class Test {public static void main(String[] args) {Permission permission1 new Permission(read);Permission permission2 new Permission(write);Permission permission3 new Permission(execute);Role role1 new Role();role1.addComponent(permission1);Role role2 new Role();role2.addComponent(permission2);role2.addComponent(permission3);User user new User();user.addComponent(role1);user.addComponent(role2);System.out.println(user.hasPermission(read)); // 输出trueSystem.out.println(user.hasPermission(write)); // 输出trueSystem.out.println(user.hasPermission(execute)); // 输出trueSystem.out.println(user.hasPermission(delete)); // 输出false}
} 装饰器模式
这个装饰器模式其实玩过Python的小兄弟应该很熟悉了。我们有个语法糖可以做装饰器。它们的思想是类似的装饰器模式也是通过包装对象来实现功能的扩展。在装饰器模式中通常会定义一个装饰器类该类接受一个对象作为参数在运行时动态地为对象添加额外的行为。通过装饰器模式可以在不改变原始对象的情况下通过包装对象来扩展其功能。
那么这个时候我们的装饰器模式和代理模式有什么区别 装饰器模式Decorator Pattern的目的是在不改变原有对象的基础上动态地扩展其功能。它允许通过将对象包装在装饰器中来为对象添加额外的行为或责任。 代理模式Proxy Pattern的目的是控制对对象的访问。它提供了一个代理对象用于在客户端和实际对象之间进行间接访问从而可以在访问对象时添加额外的逻辑。
// 定义一个接口
public interface Component {void operation();
} // 具体的组件实现类,我们要装饰的对象
public class ConcreteComponent implements Component {Overridepublic void operation() {System.out.println(执行具体组件的操作);}
}
// 装饰器抽象类
public abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component component;}Overridepublic void operation() {component.operation();}
} // 具体的装饰器类
public class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}Overridepublic void operation() {super.operation();additionalOperation();}public void additionalOperation() {System.out.println(执行额外的操作A);}
}
// 具体的装饰器类
public class ConcreteDecoratorB extends Decorator {public ConcreteDecoratorB(Component component) {super(component);}Overridepublic void operation() {super.operation();additionalOperation();}public void additionalOperation() {System.out.println(执行额外的操作B);}
}
最后是我们的测试
public class Test {public static void main(String[] args) {// 创建具体组件对象Component component new ConcreteComponent();// 使用装饰器包装组件对象Component decoratedComponent new ConcreteDecoratorA(new ConcreteDecoratorB(component));// 执行操作decoratedComponent.operation();}
}代理模式
代理模式的话我们分为动态代理和静态代理。这里的话我们主要是学习思想所以我们这里就来玩玩静态代理。那么这个静态代理和我们的装饰器模式区别在哪呢。其实区别没有那么大
在代理模式中代理类充当的是客户端和真实对象之间的中介控制客户端对真实对象的访问。代理类可以在访问真实对象前后执行额外的操作并且可以选择延迟加载真实对象从而优化性能。代理模式的目的是保护真实对象并提供更高级别的访问控制。
在装饰器模式中装饰器类包装了被装饰对象通过动态地为被包装对象添加新的行为或修改现有行为从而扩展其功能。装饰器模式的目的是增强原始对象的功能而不是控制对它的访问。
虽然说两者都是通过外层的类来进行控制的。但是你可理解为主动权不一样。
这里我就不多说了可以看到这篇文章而且确实也是很常见的。
Java DomeAOP模式回顾小Dome
我们可以用代理来实现AOP切面。
外观模式
一句话隐藏系统的复杂性并向客户端提供了一个客户端可以访问的系统接口。这个活我觉得大部分的人都很喜欢干。比如我我有个习惯就是每次在开发一个东西的时候要用到什么第三方或者什么新的 东西然后想要实现某些功能的时候它的API调用比较反人类反我的编码习惯的时候我就喜欢封装一下然后给一个接口我只关心它要什么输出什么什么时候用。举个例子玩Redis的时候对redistemplate的api直接做一个封装要么自己封装要么嫖现成的避免关注到太多细节不利于编码和学习。扯到这个就不得不提到思维导读在学习当中的重要性了。
这个我们常常使用的SpringBootMVC的时候我们用的注解啥的就是一个非常直观的例子。
这个具体案例就不给了太常见了。
享元模式
享元模式Flyweight Pattern是一种软件设计模式它旨在优化大量细粒度对象的内存使用和性能。该模式通过共享对象来减少内存占用同时提高系统的性能。
在享元模式中将对象分为可共享的内部状态和不可共享的外部状态。内部状态可以被多个对象共享而外部状态则取决于特定的对象环境并且不能被共享。
享元模式的核心思想是利用共享来避免创建大量相似对象从而减少内存占用。当需要创建一个对象时首先检查对象池中是否已经存在相同内部状态的对象如果存在则直接返回共享的对象如果不存在则创建一个新的对象并将其加入到对象池中以供后续使用。
通过使用享元模式可以有效地减少系统中对象的数量降低内存占用并提高系统的性能。但需要注意的是在使用享元模式时要确保共享对象的状态是不可变的否则可能会导致对象池中的对象状态被修改从而引发错误。
人话该公用就公用节约资源该多例就多例
能够共享的对象我们就放在一起进行维护。比如缓存这种一段时间内是不变的我们直接走缓存大家共享呗如果不是或者情况不同比如每个用户对应的信息订单这种我们肯定没法共享。 ·
行为模式
okey,到了我们这边的行为模式咯。我们实际的代码都是这些模式好几个混着用的还是那句话其实是没有必要分那么清楚真的会用你写代码的时候除非是遇到了某些比较吻合我们这些设计模式里面的情况的情况下你可能会自觉的使用外其实很多时候你尊从我们的六个设计原则很自然就能够写出比较合理的代码。因为实际工程上还要避免过度设计的问题。
责任链模式
说白了就是流水线。假设有一个订单处理系统订单需要经过多个环节进行处理包括验证、支付、库存检查和配送等环节。每个环节都有自己的处理规则和责任。
public abstract class Handler {protected Handler nextHandler;public void setNextHandler(Handler nextHandler) {this.nextHandler nextHandler;}public abstract void handleRequest(Order order);
}之后是我们具体的Handler public class ValidateHandler extends Handler {public void handleRequest(Order order) {if (order.isValid()) {System.out.println(订单验证通过);} else {if (nextHandler ! null) {nextHandler.handleRequest(order);} else {System.out.println(订单验证未通过);}}}
}public class PaymentHandler extends Handler {public void handleRequest(Order order) {if (order.hasPaid()) {System.out.println(订单支付成功);} else {if (nextHandler ! null) {nextHandler.handleRequest(order);} else {System.out.println(订单支付失败);}}}
}public class StockCheckHandler extends Handler {public void handleRequest(Order order) {if (order.hasEnoughStock()) {System.out.println(库存检查通过);} else {if (nextHandler ! null) {nextHandler.handleRequest(order);} else {System.out.println(库存不足);}}}
}public class ShippingHandler extends Handler {public void handleRequest(Order order) {if (order.canBeShipped()) {System.out.println(订单已发货);} else {if (nextHandler ! null) {nextHandler.handleRequest(order);} else {System.out.println(订单无法发货);}}}
}然后是测试代码
Handler validateHandler new ValidateHandler();
Handler paymentHandler new PaymentHandler();
Handler stockCheckHandler new StockCheckHandler();
Handler shippingHandler new ShippingHandler();// 设置处理器的下一个处理器
validateHandler.setNextHandler(paymentHandler);
paymentHandler.setNextHandler(stockCheckHandler);
stockCheckHandler.setNextHandler(shippingHandler);其实很多框架比如Spring的Bean周期Vue的生命周期其实宏观上面看就是一个责任链路。
命令模式
将请求封装成一个对象从而使得可以使用不同的请求来参数化其他对象并且能够将请求排队或记录日志、撤销等操作。这种模式让请求发送者和接收者彼此独立它们不需要知道彼此的存在只需要通过Command对象来进行交互。
举个简单的例子就比如我们的遥控器我们按下遥控器的按钮此时发送了命令。然后电视接收到了命令完成操作。
所以这个场景模式的话我们是包括了这几个部分的
命令抽象具体命令发送者接收者定义了执行方法客户端根据命令设置接收者执行方法
这个例子的话其实我的上一篇博文netty的一个整合其实对不不同的消息类型的处理其实就是一个命令模式使用。
现在我们还是举个电视机的例子吧
首先我们有个TV
public class TV {public void turnOn() {System.out.println(电视已开机);}public void turnOff() {System.out.println(电视已关机);}public void volumeUp() {System.out.println(音量增加);}public void volumeDown() {System.out.println(音量减小);}public void changeChannel() {System.out.println(频道切换);}
}然后我们有个抽象的指令
public interface Command {void execute();
}之后我们有好几个具体的指令这里我就只贴出一个了
public class TurnOnCommand implements Command {private TV tv;public TurnOnCommand(TV tv) {this.tv tv;}Overridepublic void execute() {tv.turnOn();}
}之后是我们的一个调用者 public class RemoteControl {private Command command;public void setCommand(Command command) {this.command command;}public void pressButton() {command.execute();}
}之后的话我们直接使用
public class Client {public static void main(String[] args) {TV tv new TV();Command turnOnCommand new TurnOnCommand(tv);Command turnOffCommand new TurnOffCommand(tv);Command volumeUpCommand new VolumeUpCommand(tv);Command volumeDownCommand new VolumeDownCommand(tv);Command changeChannelCommand new ChangeChannelCommand(tv);RemoteControl remoteControl new RemoteControl();// 设置命令并执行remoteControl.setCommand(turnOnCommand);remoteControl.pressButton(); // 执行开机命令remoteControl.setCommand(volumeUpCommand);remoteControl.pressButton(); // 执行增加音量命令}
}这个时候你发现其实和我们的代理装饰器模式有那么点像只是呢首先没有对方法增强也可以增强然后只是把某一个抽离出来。使得在业务上面看起来更加明朗。
迭代器模式
顺着走其实我们这边搞个举到了一个责任链的模式其实有点像只是区别是当前状态用到了上一个状态有点DP的意思哈然后硬编码的形式走你。其实我们也可以走迭代器对于简单的一个情况下。那么我们优化一下就变成了这个
首先我们先抽象出一层搞一个HandlerIterator最外层的。
java
public class HandlerIterator implements IteratorHandler {private ListHandler handlers;private int current;public HandlerIterator(ListHandler handlers) {this.handlers handlers;this.current 0;}Overridepublic boolean hasNext() {return current handlers.size();}Overridepublic Handler next() {Handler handler handlers.get(current);current;return handler;}
}然后迭代处理就可以了
public class Client {public static void main(String[] args) {ListHandler handlers new ArrayList();handlers.add(new ValidateHandler());handlers.add(new PaymentHandler());handlers.add(new StockCheckHandler());handlers.add(new ShippingHandler());HandlerIterator iterator new HandlerIterator(handlers);Order order new Order();// 处理订单while (iterator.hasNext()) {Handler handler iterator.next();handler.handleRequest(order);}}
}中介模式
中介模式和我们的代理模式其实看上去很像但是区别很明显的一个就是我们的代理模式是一种结构型模式主要在于对象的一个控制。中介模式是一种行为模式是对一类对象进行处理。 一个对一个对象进行控制和增强一个是对一类对象进行处理。
比如我们的ORM框架他就是个中介。多个数据库多种数据库连接到我们的ORM框架然后ORM框架为我们的应用提供服务。 这个我感觉没啥好说的。
备忘录模式
这个我觉得没啥好说的
记得数据备份是好习惯数据预加载也是好习惯记得Config备份回滚版本控制不限于git代码配置数据也注意
观察者模式
用于在对象之间建立一对多的依赖关系使得当一个对象的状态发生变化时所有依赖它的对象都能够得到通知并自动更新。
主题Subject也称为被观察者或可观察对象主题维护了一组观察者对象并提供了添加、删除和通知观察者的方法。主题可以是具体的类或接口。观察者Observer观察者定义了接收和处理主题通知的方法。观察者通过订阅主题来注册自己并在主题状态发生变化时得到通知。具体主题Concrete Subject和具体观察者Concrete Observer具体主题是主题的具体实现类具体观察者是观察者的具体实现类。它们实现了主题和观察者的相应接口并根据业务需求定义具体的行为。
举个简答的例子就是我们那个订阅的一个例子有哪些用户订阅了什么对象之类的。
举个例子我们现在有个专栏 public class Column {private String name;private ListObserver subscribers;public Column(String name) {this.name name;this.subscribers new ArrayList();}public void subscribe(Observer subscriber) {subscribers.add(subscriber);}public void unsubscribe(Observer subscriber) {subscribers.remove(subscriber);}public void notifySubscribers(String article) {for (Observer subscriber : subscribers) {subscriber.update(article);}}
}然后我们有个观察者其实就是我们的用户
java
public interface Observer {void update(String article);
}public class User implements Observer {private String name;public User(String name) {this.name name;}Overridepublic void update(String article) {System.out.println(Hi name ! A new article article has been published in the subscribed column.);}
}之后我们的测试代码我们可以看到哪些用户订阅了然后给通知等等。
public class Test {public static void main(String[] args) {// 创建专栏Column techColumn new Column(Technology);// 创建用户User user1 new User(Alice);User user2 new User(Bob);// 用户订阅专栏techColumn.subscribe(user1);techColumn.subscribe(user2);// 发布新文章techColumn.notifySubscribers(Introduction to AI);// 用户取消订阅techColumn.unsubscribe(user2);// 再次发布新文章techColumn.notifySubscribers(Deep Learning Applications);}
}状态模式
它允许对象在内部状态改变时改变其行为。该模式将对象的状态封装成独立的类并将状态的转换逻辑封装在状态类中。这样当对象的状态发生改变时它可以自动切换到适当的状态类从而改变其行为。
其实很多时候我们直接用枚举类也是ok的当然如果你的状态有特殊的操作也是okey的。
public interface State {void handle();
}java
public class NormalState implements State {Overridepublic void handle() {System.out.println(Normal state: Performing normal operations...);}
}public class WarningState implements State {Overridepublic void handle() {System.out.println(Warning state: Performing warning operations...);}
}public class ErrorState implements State {Overridepublic void handle() {System.out.println(Error state: Performing error operations...);}
}public class Context {private State currentState;public Context() {// 初始状态为正常状态currentState new NormalState();}public void setState(State state) {currentState state;}public void request() {currentState.handle();}
}策略模式
它允许在运行时选择算法的行为。该模式将不同的算法封装成独立的策略类并且这些策略类实现了相同的接口以便在运行时可以互相替换使用。
在代码上其实和我们的装饰器模式很像的。只不过装饰器模式在于创建新的对象而我们的策略模式相当于替换不同的策略组件。
public interface Strategy {void execute();
}然后我们这里定义不同的策略
public class ConcreteStrategyA implements Strategy {Overridepublic void execute() {System.out.println(Executing strategy A...);}
}public class ConcreteStrategyB implements Strategy {Overridepublic void execute() {System.out.println(Executing strategy B...);}
}public class ConcreteStrategyC implements Strategy {Overridepublic void execute() {System.out.println(Executing strategy C...);}
}然后愉快玩耍
public class Context {private Strategy strategy;public void setStrategy(Strategy strategy) {this.strategy strategy;}public void executeStrategy() {strategy.execute();}
}当然实际上你还可以配合枚举类然后搞个HashMap,把这些对象都放在一个容器当中。
然后你也发现了这个状态模式和策略模式很像是的其实只是表示的状态不同一个侧重状态的描述一个侧重不同的状态采用不同的算法方案。
模板模式
顾名思义其实就是模板它定义了一个算法的骨架将一些步骤的实现延迟到子类中。这样可以在不改变算法结构的情况下通过子类对某些步骤进行重定义从而实现算法的定制化。比如我那个任务框架里面的那个任务清单的模板当然我那个模板本质上还是一个代理方法都是动态加上去的
public abstract class AbstractTemplate {public void templateMethod() {// 步骤1step1();// 步骤2step2();// 步骤3step3();}protected abstract void step1();protected abstract void step2();protected void step3() {System.out.println(Default implementation of step3);}
}然后实现类就这样玩
public class ConcreteTemplate extends AbstractTemplate {Overrideprotected void step1() {System.out.println(Step1 implementation in ConcreteTemplate);}Overrideprotected void step2() {System.out.println(Step2 implementation in ConcreteTemplate);}Overrideprotected void step3() {System.out.println(Step3 implementation in ConcreteTemplate);}
访问者模式
访问者模式的核心思想是将数据结构和操作解耦使得操作可以独立变化。它通过在数据结构中定义一个公共的接受访问者的方法让访问者对象对数据结构中的每个元素进行访问并执行相应的操作。 直接参考MVC设计思想。
总结
在这里我们有六大设计法则
单一职责开闭原则里氏替换原则迪米特法则接口隔离原则依赖倒置原则
之后我们有23个基本设计模式我们对设计模式进行简单分类又分为三大类型。
创建型结构性行为型
具体到每一个分类是
一 创建型
简单工厂工厂方法抽象工厂建造者模式原型模式单例模式
二 结构型
适配器桥接模式组合模式装饰器代理模式外观模式享元模式
三 行为型
责任链模式命令模式迭代模式中介模式备忘录模式观察者模式状态模式策略模式模板模式 10.访问者模式
以上就是全部内容了~ 文章转载自: http://www.morning.yfmwg.cn.gov.cn.yfmwg.cn http://www.morning.xpqsk.cn.gov.cn.xpqsk.cn http://www.morning.mlbn.cn.gov.cn.mlbn.cn http://www.morning.daxifa.com.gov.cn.daxifa.com http://www.morning.zlrsy.cn.gov.cn.zlrsy.cn http://www.morning.jppb.cn.gov.cn.jppb.cn http://www.morning.qyllw.cn.gov.cn.qyllw.cn http://www.morning.yxwnn.cn.gov.cn.yxwnn.cn http://www.morning.1000sh.com.gov.cn.1000sh.com http://www.morning.rtryr.cn.gov.cn.rtryr.cn http://www.morning.hwycs.cn.gov.cn.hwycs.cn http://www.morning.xbyyd.cn.gov.cn.xbyyd.cn http://www.morning.pprxs.cn.gov.cn.pprxs.cn http://www.morning.wbxbj.cn.gov.cn.wbxbj.cn http://www.morning.npmx.cn.gov.cn.npmx.cn http://www.morning.ryxdr.cn.gov.cn.ryxdr.cn http://www.morning.rwxnn.cn.gov.cn.rwxnn.cn http://www.morning.nzkc.cn.gov.cn.nzkc.cn http://www.morning.mnjwj.cn.gov.cn.mnjwj.cn http://www.morning.xbdrc.cn.gov.cn.xbdrc.cn http://www.morning.xskbr.cn.gov.cn.xskbr.cn http://www.morning.lfsmf.cn.gov.cn.lfsmf.cn http://www.morning.beeice.com.gov.cn.beeice.com http://www.morning.kybpj.cn.gov.cn.kybpj.cn http://www.morning.nlywq.cn.gov.cn.nlywq.cn http://www.morning.bzlsf.cn.gov.cn.bzlsf.cn http://www.morning.ffydh.cn.gov.cn.ffydh.cn http://www.morning.tnjz.cn.gov.cn.tnjz.cn http://www.morning.pwwjs.cn.gov.cn.pwwjs.cn http://www.morning.frnjm.cn.gov.cn.frnjm.cn http://www.morning.rnlx.cn.gov.cn.rnlx.cn http://www.morning.yrflh.cn.gov.cn.yrflh.cn http://www.morning.mpnff.cn.gov.cn.mpnff.cn http://www.morning.mwkwg.cn.gov.cn.mwkwg.cn http://www.morning.8yitong.com.gov.cn.8yitong.com http://www.morning.nxbsq.cn.gov.cn.nxbsq.cn http://www.morning.fdrb.cn.gov.cn.fdrb.cn http://www.morning.kstgt.cn.gov.cn.kstgt.cn http://www.morning.mngh.cn.gov.cn.mngh.cn http://www.morning.ymfzd.cn.gov.cn.ymfzd.cn http://www.morning.zwxfj.cn.gov.cn.zwxfj.cn http://www.morning.fddfn.cn.gov.cn.fddfn.cn http://www.morning.trnhy.cn.gov.cn.trnhy.cn http://www.morning.wiitw.com.gov.cn.wiitw.com http://www.morning.kdhrf.cn.gov.cn.kdhrf.cn http://www.morning.xnwjt.cn.gov.cn.xnwjt.cn http://www.morning.qwdqq.cn.gov.cn.qwdqq.cn http://www.morning.xmjzn.cn.gov.cn.xmjzn.cn http://www.morning.zxgzp.cn.gov.cn.zxgzp.cn http://www.morning.rxsgk.cn.gov.cn.rxsgk.cn http://www.morning.ynlpy.cn.gov.cn.ynlpy.cn http://www.morning.npqps.cn.gov.cn.npqps.cn http://www.morning.czrcf.cn.gov.cn.czrcf.cn http://www.morning.xinxianzhi005.com.gov.cn.xinxianzhi005.com http://www.morning.khpgd.cn.gov.cn.khpgd.cn http://www.morning.qkrqt.cn.gov.cn.qkrqt.cn http://www.morning.xqzrg.cn.gov.cn.xqzrg.cn http://www.morning.hgfxg.cn.gov.cn.hgfxg.cn http://www.morning.wqfj.cn.gov.cn.wqfj.cn http://www.morning.fzlk.cn.gov.cn.fzlk.cn http://www.morning.qmqgx.cn.gov.cn.qmqgx.cn http://www.morning.mbrbg.cn.gov.cn.mbrbg.cn http://www.morning.sacxbs.cn.gov.cn.sacxbs.cn http://www.morning.smcfk.cn.gov.cn.smcfk.cn http://www.morning.rdlong.com.gov.cn.rdlong.com http://www.morning.clpdm.cn.gov.cn.clpdm.cn http://www.morning.mnqg.cn.gov.cn.mnqg.cn http://www.morning.lskyz.cn.gov.cn.lskyz.cn http://www.morning.yhrfg.cn.gov.cn.yhrfg.cn http://www.morning.ftwlay.cn.gov.cn.ftwlay.cn http://www.morning.tqhpt.cn.gov.cn.tqhpt.cn http://www.morning.wlxfj.cn.gov.cn.wlxfj.cn http://www.morning.qxwwg.cn.gov.cn.qxwwg.cn http://www.morning.qrpdk.cn.gov.cn.qrpdk.cn http://www.morning.fbdtd.cn.gov.cn.fbdtd.cn http://www.morning.czqqy.cn.gov.cn.czqqy.cn http://www.morning.llsrg.cn.gov.cn.llsrg.cn http://www.morning.mrccd.cn.gov.cn.mrccd.cn http://www.morning.yltyr.cn.gov.cn.yltyr.cn http://www.morning.yzktr.cn.gov.cn.yzktr.cn