后端学习 - 设计模式与设计原则
文章目录
- 设计原则
- 1 单一职责原则
- 2 开闭原则
- 3 Liskov 替换原则
- 4 依赖倒置原则
- 5 接口隔离原则
- 6 迪米特法则
- 设计模式:创建型模式
- 1 工厂模式
- 2 抽象工厂模式
- 3 单例模式
- 设计模式:行为型模式
- 1 观察者模式
- 2 模板模式
- 3 备忘录模式
- 设计模式:结构型模式
- 1 代理模式
- 2 装饰器模式
- 3 适配器模式
设计原则
六大设计原则详解
1 单一职责原则
- 一个类只专注于做一件事
2 开闭原则
- 开闭原则是 OOP 中最基础的设计原则
- 对拓展开放,对修改关闭,尽可能在不改变原有代码的情况下进行拓展
- 要实现开闭原则,首先实现面向接口编程(依赖倒置原则)
3 Liskov 替换原则
- 子类必须能够替换它们的基类型
- “父类能做的事,子类必须能做,要做到相等或更好”
4 依赖倒置原则
- 核心思想是面向接口编程,依赖于抽象而不依赖于具体
- 写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互
- 使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的操作,把展现细节的任务交给他们的实现类完成
5 接口隔离原则
- 使用多个隔离的接口,比使用单个臃肿庞大接口要好(尽量细化接口,接口中的方法尽量少)
- 如果接口过于臃肿,只要接口中出现的方法,不管对依赖于它的类有没有用处,实现类中都必须去实现这些方法
6 迪米特法则
- 一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立
设计模式:创建型模式
1 工厂模式
- 主要解决接口选择的问题:将同一类对象的创建过程,转移到一个工厂类实现
- 在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象
// 1.创建接口
public interface Shape {void draw();
}// 2.创建接口的实现类
public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Inside Rectangle::draw() method.");}
}public class Square implements Shape {@Overridepublic void draw() {System.out.println("Inside Square::draw() method.");}
}// 3.创建工厂
public class ShapeFactory {public Shape getShape(String shapeType){if(shapeType == null){return null;} if(shapeType.equalsIgnoreCase("CIRCLE")){return new Circle();} else if(shapeType.equalsIgnoreCase("RECTANGLE")){return new Rectangle();} else if(shapeType.equalsIgnoreCase("SQUARE")){return new Square();}return null;}
}
public class FactoryPatternDemo {public static void main(String[] args) {ShapeFactory shapeFactory = new ShapeFactory();//获取 Circle 的对象,并调用它的 draw 方法Shape shape1 = shapeFactory.getShape("CIRCLE");//调用 Circle 的 draw 方法shape1.draw();//...}
}
2 抽象工厂模式
- 生产工厂的工厂,将属于同一类型的工厂聚合在一起
- 从工厂生产器中获取的工厂,也用共用的接口指向同一对象
// 1.创建形状和颜色的接口,及其实现类(略)// 2.设置形状和颜色的抽象工厂
public abstract class AbstractFactory {public abstract Color getColor(String color);public abstract Shape getShape(String shape);
}// 3.继承抽象工厂,实现各自对应的方法
public class ShapeFactory extends AbstractFactory {@Overridepublic Shape getShape(String shapeType){if(shapeType == null){return null;}if(shapeType.equalsIgnoreCase("CIRCLE")){return new Circle();} else if(shapeType.equalsIgnoreCase("RECTANGLE")){return new Rectangle();} else if(shapeType.equalsIgnoreCase("SQUARE")){return new Square();}return null;}@Overridepublic Color getColor(String color) {return null;}
}public class ColorFactory extends AbstractFactory {@Overridepublic Shape getShape(String shapeType){return null;}@Overridepublic Color getColor(String color) {if(color == null){return null;} if(color.equalsIgnoreCase("RED")){return new Red();} else if(color.equalsIgnoreCase("GREEN")){return new Green();} else if(color.equalsIgnoreCase("BLUE")){return new Blue();}return null;}
}// 4.工厂生产器——工厂的工厂
public class FactoryProducer {public static AbstractFactory getFactory(String choice){if(choice.equalsIgnoreCase("SHAPE")){return new ShapeFactory();} else if(choice.equalsIgnoreCase("COLOR")){return new ColorFactory();}return null;}
}
public class AbstractFactoryPatternDemo {public static void main(String[] args) {//获取形状工厂AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");//获取形状为 Circle 的对象Shape shape1 = shapeFactory.getShape("CIRCLE");//调用 Circle 的 draw 方法shape1.draw();//获取颜色工厂AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");//获取颜色为 Red 的对象Color color1 = colorFactory.getColor("RED");//调用 Red 的 fill 方法color1.fill();}
}
3 单例模式
一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建
可以直接访问,不需要实例化该类的对象
最常用的 DCL (double-checked locking) 实现:
构造方法使用private
修饰,保证该类只有自己能实例化自己
使用volatile
修饰属性,指示 JVM,变量是共享且不稳定的,每次使用它都到主存中进行读取,并禁止指令重排
public class Singleton { private volatile static Singleton singleton; private Singleton (){} public static Singleton getSingleton() { if (singleton == null) { synchronized (Singleton.class) {if (singleton == null) {singleton = new Singleton(); } } } return singleton; }
}
设计模式:行为型模式
1 观察者模式
- 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
// 1.被观察者类
public class Subject {private List<Observer> observers = new ArrayList<Observer>(); // 用List存放所有观察者private int state;public int getState() {return state;}public void setState(int state) {this.state = state;notifyAllObservers();}public void attach(Observer observer){ // 添加观察者observers.add(observer); }public void notifyAllObservers(){ // 通知观察者,自己的状态变化for (Observer observer : observers) {observer.update();}}
}// 2.观察者抽象类及其实现
public abstract class Observer {protected Subject subject;public abstract void update();
}public class BinaryObserver extends Observer{public BinaryObserver(Subject subject){this.subject = subject;this.subject.attach(this); // 调用被观察者的attch方法,将自己注册为它的观察者}@Overridepublic void update() {System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); }
}
......
public class ObserverPatternDemo {public static void main(String[] args) {Subject subject = new Subject();new HexaObserver(subject);new OctalObserver(subject);new BinaryObserver(subject);System.out.println("First state change: 15"); subject.setState(15);System.out.println("Second state change: 10"); subject.setState(10);}
}
2 模板模式
- 一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行
- 模板方法被声明为
final
,因为执行它的流程是固定的
// 1.模板类
public abstract class Game {abstract void initialize();abstract void startPlay();abstract void endPlay();// 模板方法,它规定了其他方法的执行流程是固定的public final void play(){//初始化游戏initialize();//开始游戏startPlay();//结束游戏endPlay();}
}// 2.模板类的不同实现
public class Football extends Game {@Overridevoid endPlay() {System.out.println("Football Game Finished!");}@Overridevoid initialize() {System.out.println("Football Game Initialized! Start playing.");}@Overridevoid startPlay() {System.out.println("Football Game Started. Enjoy the game!");}
}public class Cricket extends Game {@Overridevoid endPlay() {System.out.println("Cricket Game Finished!");}@Overridevoid initialize() {System.out.println("Cricket Game Initialized! Start playing.");}@Overridevoid startPlay() {System.out.println("Cricket Game Started. Enjoy the game!");}
}
public class TemplatePatternDemo {public static void main(String[] args) {// 不同的实现使用相同的模板Game game = new Cricket();game.play();game = new Football();game.play(); }
}
3 备忘录模式
- 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态
- 备忘录模式使用三个类
Memento
、Originator
和CareTaker
Memento
包含了要被恢复的对象的状态,相当于每一个存档;
Originator
创建并在Memento
对象中存储状态,是要被存储的对象;
Caretaker
对象负责从Memento
中恢复对象的状态,相当于存档的集合
// 1.Memento 类,包含了要被恢复的对象的状态
public class Memento {private String state;public Memento(String state){this.state = state;}public String getState(){return state;}
}// 2.Originator 类,要被记录的类
public class Originator {private String state;public void setState(String state){this.state = state;}public String getState(){return state;}public Memento saveStateToMemento(){return new Memento(state);}public void getStateFromMemento(Memento Memento){state = Memento.getState();}
}// 3.CareTaker 类,负责从 Memento 中恢复对象的状态
public class CareTaker {private List<Memento> mementoList = new ArrayList<Memento>();public void add(Memento state){mementoList.add(state);}public Memento get(int index){return mementoList.get(index);}
}
public class MementoPatternDemo {public static void main(String[] args) {Originator originator = new Originator();CareTaker careTaker = new CareTaker();originator.setState("State #1");originator.setState("State #2");careTaker.add(originator.saveStateToMemento());originator.setState("State #3");careTaker.add(originator.saveStateToMemento());originator.setState("State #4");System.out.println("Current State: " + originator.getState()); originator.getStateFromMemento(careTaker.get(0));System.out.println("First saved State: " + originator.getState());originator.getStateFromMemento(careTaker.get(1));System.out.println("Second saved State: " + originator.getState());}
}Current State: State #4
First saved State: State #2
Second saved State: State #3
设计模式:结构型模式
1 代理模式
- 直接访问会给使用者或者系统结构带来很多麻烦时,为其他对象提供一种代理以控制对这个对象的访问
- 示例:图像首次显示时需要先加载,再次访问不需要;通过代理自动化地完成这一过程
// 1.创建接口及其实现类
public interface Image {void display();
}public class RealImage implements Image {private String fileName;public RealImage(String fileName){this.fileName = fileName;loadFromDisk(fileName);}@Overridepublic void display() {System.out.println("Displaying " + fileName);}private void loadFromDisk(String fileName){System.out.println("Loading " + fileName);}
}// 2.创建代理
public class ProxyImage implements Image {private RealImage realImage;private String fileName;public ProxyImage(String fileName){this.fileName = fileName;}@Overridepublic void display() { // 代理的功能if(realImage == null){realImage = new RealImage(fileName);}realImage.display();}
}
public class ProxyPatternDemo {public static void main(String[] args) {Image image = new ProxyImage("test_10mb.jpg");// 图像将从磁盘加载image.display(); // 图像不需要从磁盘加载image.display(); }
}
2 装饰器模式
- 动态地给一个对象添加一些额外的职责,将其包装成功能更强大的类,效果类似于继承,作为继承的一种替代方式
- 就增加功能来说,装饰器模式相比生成子类更为灵活
// 1.创建形状接口及其实现类
public interface Shape {void draw();
}public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Shape: Rectangle");}
}// 2.抽象装饰类及其实现
public abstract class ShapeDecorator implements Shape {protected Shape decoratedShape;public ShapeDecorator(Shape decoratedShape){this.decoratedShape = decoratedShape;}public void draw(){decoratedShape.draw();}
}public class RedShapeDecorator extends ShapeDecorator {public RedShapeDecorator(Shape decoratedShape) {super(decoratedShape); }@Overridepublic void draw() {decoratedShape.draw(); setRedBorder(decoratedShape);}private void setRedBorder(Shape decoratedShape){System.out.println("Border Color: Red");}
}
public class DecoratorPatternDemo {public static void main(String[] args) {Shape circle = new Circle();ShapeDecorator redCircle = new RedShapeDecorator(new Circle());ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());//Shape redCircle = new RedShapeDecorator(new Circle());//Shape redRectangle = new RedShapeDecorator(new Rectangle());System.out.println("Circle with normal border");circle.draw();System.out.println("\nCircle of red border");redCircle.draw();System.out.println("\nRectangle of red border");redRectangle.draw();}
}
3 适配器模式
- 适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁,结合了两个独立接口的功能
// 1.创建要捏合的两个接口
public interface MediaPlayer {public void play(String audioType, String fileName);
}public interface AdvancedMediaPlayer { public void playVlc(String fileName);public void playMp4(String fileName);
}// 2.创建加强播放器的实现类
public class VlcPlayer implements AdvancedMediaPlayer{@Overridepublic void playVlc(String fileName) {System.out.println("Playing vlc file. Name: "+ fileName); }@Overridepublic void playMp4(String fileName) {//什么也不做}
}public class Mp4Player implements AdvancedMediaPlayer{@Overridepublic void playVlc(String fileName) {//什么也不做}@Overridepublic void playMp4(String fileName) {System.out.println("Playing mp4 file. Name: "+ fileName); }
}// 3.创建 实现加强播放器方法的 适配器类
public class MediaAdapter implements MediaPlayer {AdvancedMediaPlayer advancedMusicPlayer;public MediaAdapter(String audioType){if(audioType.equalsIgnoreCase("vlc") ){advancedMusicPlayer = new VlcPlayer(); } else if (audioType.equalsIgnoreCase("mp4")){advancedMusicPlayer = new Mp4Player();} }@Overridepublic void play(String audioType, String fileName) {if(audioType.equalsIgnoreCase("vlc")){advancedMusicPlayer.playVlc(fileName);}else if(audioType.equalsIgnoreCase("mp4")){advancedMusicPlayer.playMp4(fileName);}}
}// 4.创建未增强的播放器,注入适配器
public class AudioPlayer implements MediaPlayer {MediaAdapter mediaAdapter; @Overridepublic void play(String audioType, String fileName) { //播放 mp3 音乐文件的内置支持if(audioType.equalsIgnoreCase("mp3")){System.out.println("Playing mp3 file. Name: "+ fileName); } //mediaAdapter 提供了播放其他文件格式的支持else if(audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")){mediaAdapter = new MediaAdapter(audioType);mediaAdapter.play(audioType, fileName);}else{System.out.println("Invalid media. "+audioType + " format not supported");}}
}
public class AdapterPatternDemo {public static void main(String[] args) {AudioPlayer audioPlayer = new AudioPlayer();audioPlayer.play("mp3", "beyond the horizon.mp3");audioPlayer.play("mp4", "alone.mp4");audioPlayer.play("vlc", "far far away.vlc");}
}
后端学习 - 设计模式与设计原则相关推荐
- 设计模式 - 七大设计原则(一)
设计模式 - 七大设计原则(一) 概述 简单介绍一下七大设计原则: 开闭原则:是所有面向对象设计的核心,对扩展开放,对修改关闭 依赖倒置原则:针对接口编程,依赖于抽象而不依赖于具体 单一职责原则:一个 ...
- 设计模式-六大设计原则(附加实际开发建议以及计算器例子)
使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.设计模式使代码编制真正工程化,是软件工程的基石脉络,如同大厦的结构一样. 文章结构: 1.单一职责原则(SRP): 2.里氏替换原 ...
- 设计一个矩形类rectangle_万字长文带你捋清六种设计模式的设计原则(建议收藏)...
对于设计模式,自己很早之前就看了好多本设计模式书籍,其中一些还看了好几遍,也一直希望自己能在编码的时候把这些设计模式用上去.可是,在日常的打码中,用的最多的就是单例,其次是观察者和建造者模式 ( bu ...
- c# 设计原则需要学习吗_向最好的学习:产品设计原则
c# 设计原则需要学习吗 重点 (Top highlight) In my job as Design Team Lead at SimpleSite, I've recently been part ...
- Go设计模式(3)-设计原则
上一篇文章Go设计模式(2)-面向对象分析与设计里讲过,做设计最重要的是保留合适的扩展点.如何才能设计出合适的扩展点呢? 这篇文章会讲解一下经典的设计原则.这些设计原则大家可能都听过,但可能没有想过为 ...
- 【设计模式】设计原则
[设计模式]设计原则 在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据6条原则来开发程序,从而提高软件开发效率.节约软件开发成本和维护成本. 1 开闭原 ...
- 学习6大设计原则、23种设计模式
了解设计模式的朋友们,想必都听说过"六大设计原则"吧.其实最经典的 23 种设计模式中或多或少地都在使用这些设计原则,也就是说,设计模式是站在设计原则的基础之上的.所以在学习设计模 ...
- 《设计模式之禅》第二版 学习之六大设计原则(二)
昨天学习了六个设计原则中的单一职责原则和里氏替换原则,今天继续学习依赖倒置原则和接口隔离原则,因为都是一些偏理论的东西,虽说理解,但在使用中还是会比较吃力,建议没事的时候多回过头来看几遍,孰能生巧,用 ...
- 从零开始学习Java设计模式 | 软件设计原则篇:开闭原则
从本讲开始,咱们就要开始学习第一章中的第三部分内容,即软件设计原则了. 在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据6条原则来开发程序,从而提高软件 ...
最新文章
- Luogu T24242 购物券Ⅰ(数据已加强)
- 数据意识上的“代沟”
- SQL Server 日志清理、数据文件收缩
- 【Gamma】 Phylab 发布说明
- PS VR发售临近,索尼的VR影视内容也不远了
- hdoj 1728 逃离迷宫
- Network Address Translation 网络地址转换
- 熊出没之奇幻空间里面的机器人图片_武汉欢乐谷奇幻灯光节12月24日盛大开幕...
- python模块--subprocess
- Ios精品源码,扁平化的ActionSheet仿花椒截屏demo文件签名重叠卡片滚动汽车仪表盘...
- Request请求转发
- FPGA之通信算法工程师面试题3
- html5页面风格,H5页面的设计风格有哪些?
- python 读取文件到字典读取顺序_python顺序的读取文件夹下名称有序的文件方法...
- python 操作excel(xlsx)进行保存
- (6)关于整型short、int、long和long long
- VBA编程_常用函数总结2
- 使用FEST-Swing测试GUI
- matlab的无穷大怎样表示_matlab中从一到无穷大怎么表示
- 电商项目--------------------商品(SKU)规格、价格功能
热门文章
- 微软的FreeBSD社区推广活动 北京站,你没看错!微软现在是一家名副其实的开源公司
- 从Unity3D编译器升级聊起Mono
- 3分钟看完Build2016 Day 1 Keynote
- 发布composer包到 Packagist,并设置自动同步(从github到Packagist)
- [转]小白都能看懂的softmax详解
- 华为云GaussDB,11.11让企业无后顾之忧
- Android之matrix类控制图片的旋转、缩放、移动
- mysql数据库rp集群,使用MySQL-Cluster搭建MySQL数据库集群
- html5储存类型,html5本地存储-留言板
- 薅羊毛丨5个平价好物,终于终于终于打折了!