【设计模式七大原则及Java示例】

阅读: 评论:0

【设计模式七大原则及Java示例】

【设计模式七大原则及Java示例】

设计模式七大原则及Java示例

  • 设计模式七大原则
    • 单一职能原则
    • 接口隔离原则
    • 倒转置换原则
    • 里氏替换原则
    • 合成/聚合复用原则
    • 开闭原则
    • 迪米特法则


CSDN博客地址
Github项目下载地址


设计模式七大原则

UML图中,绿线标识继承或者实现,白线表示依赖关系
原则并不是孤立存在的,它们相互依赖,相互补充。

单一职能原则

单一职责原则(Single Responsibility Principle) SRP

单一职责原则好处

  • 降低类的复杂性 每个类实现单一职责,并且单一职责都有清楚明确的定义,复杂性当然降低。
  • 提高可读性
    类的复杂性降低了,当然提高了可读性了。
  • 提高可维护性
    类的复杂性降低,可读性好,当然好维护。
  • 提高扩展性
    通俗点的话来说就是一个类只干一件事,或者一个方法只干一件事。

代码这里不再做过多的演示

接口隔离原则

客户端不应该依赖它不需要的接口
类间的依赖关系应该建立在最小的接口上

利用马,和鱼的例子还说名。
马需要吃饭和走路
鱼需要吃饭和游动
设计的实现接口如下

/*** @Author mabo* @Description   接口隔离原则*/
public class InterfaceIsolation {//吃interface Eat{public void eat();}//走路interface Walk{public void walk();}//游动interface Swim {public void swim();}//马在吃和走路class Horse implements Eat , Walk{@Overridepublic void eat() {System.out.println("马在吃");}@Overridepublic void walk() {System.out.println("马在走");}}//鱼在吃和游class Fish implements Eat ,Swim{@Overridepublic void eat() {System.out.println("鱼在吃");}@Overridepublic void swim() {System.out.println("鱼在游");}}
}

倒转置换原则

依赖倒转(倒置)的中心思想是面向接口编程
依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在java中,抽象指的是接口或抽象类,细节就是具体的实现类
使用接口或抽象类的目的是:制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。
倒转置换可以有三种写法

这里用小猫小狗跑来做示例

1.接口作为方法参数

/*** @Author mabo* @Description 依赖倒转* @Description 方法接口作为参数*/
public class DependencyInversion1 {private interface Animal {public void run();}private static class Action {public void go(Animal animal) {animal.run();}}private static class Dog implements Animal {@Overridepublic void run() {System.out.println("小狗在跑");}}private static class Cat implements Animal {@Overridepublic void run() {System.out.println("猫在跑");}}public static void main(String[] args) {Action action = new Action();(new Dog());(new Cat());}
}

2.接口作为属性,利用构造方法初始化接口


/*** @Author mabo* @Description     依赖倒转* @Description     类参数为接口*/
public class DependencyInversion2 {private interface Animal{public void run();}private static class Action{private Animal animal;/*** @Author mabo* @Description   通过构造方法传入接口*/public Action(Animal animal) {this.animal=animal;}public void go() {animal.run();}}private static class Dog implements Animal {@Overridepublic void run() {System.out.println("小狗在跑");}}private static class Cat implements Animal {@Overridepublic void run() {System.out.println("猫在跑");}}public static void main(String[] args) {Action dogAction=new Action(new Dog());();Action catAction=new Action(new Cat());();}
}

3.接口作为属性,利用set方法初始化接口


/*** @Author mabo* @Description     依赖倒转* @Description     setter方法传入接口*/
public class DependencyInversion3 {private interface Animal{public void run();}private static class Action{private Animal animal;public void setAnimal(Animal animal) {this.animal = animal;}//通过构造方法传入接口public void go() {animal.run();}}private static class Dog implements Animal {@Overridepublic void run() {System.out.println("小狗在跑");}}private static class Cat implements Animal {@Overridepublic void run() {System.out.println("猫在跑");}}public static void main(String[] args) {Action dogAction=new Action();dogAction.setAnimal(new Dog());();Action catAction=new Action();catAction.setAnimal(new Cat());();}
}

里氏替换原则

里氏替换原则的主要作用

  • 里氏替换原则是实现开闭原则的重要方式之一。
  • 它克服了继承中重写父类造成的可复用性变差的缺点。
  • 它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。
  • 加强程序的健壮性,同时变更时可以做到非常好的兼容性,提高程序的维护性、可扩展性,降低需求变更时引入的风险。

里氏替换原则的定义可以总结如下:

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
  • 子类中可以增加自己特有的方法
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的输入参数)要比父类的方法更宽松
  • 当子类的方法实现父类的方法时(重写/重载或实现抽象方法),方法的后置条件(即方法的的输出/返回值)要比父类的方法更严格或相等

    这里用燕子和麻雀继承鸟做说明
/*** @Author mabo* @Description   里氏置换原则*/
public class RichterSubstitutionPrinciple {public static void main(String[] args) {Bird bird1 = new Swallow();Bird bird2 = new Sparrow();bird1.setSpeed(120);bird2.setSpeed(120);System.out.println("如果飞行300公里:");try {System.out.println("燕子将飞行" + FlyTime(300) + "小时.");System.out.println("几维鸟将飞行" + FlyTime(300) + "小时。");} catch (Exception err) {System.out.println("发生错误了!");}}//鸟类public static class Bird {double flySpeed;public void setSpeed(double speed) {flySpeed = speed;}public double getFlyTime(double distance) {return (distance / flySpeed);}}//燕子类public static class Swallow extends Bird {}//麻雀public static class Sparrow extends Bird {//不应该重写父类方法
//        public void setSpeed(double speed) {
//            flySpeed = 0;
//        }public  void getFar(double distance){System.out.println(distance);}}
}

合成/聚合复用原则

合成复用原则(Composite Reuse Principle,CRP)又叫组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP)
简单理解合成复用就是将现有对象作为当前类的成员变量,开发中很常见

开闭原则

开闭原则

  • 类的改动是通过增加代码进行的,不是修改源代码。
  • 抽象化是开闭原则的关键。

这里用三角形和圆继承图像来说明

/*** @Author mabo* @Description   开闭原则*/
public class OpenClosePrinciple {static abstract class Sharp{public abstract void paint();}static class DrawingEditor{public void draw(Sharp sharp){sharp.paint();}}static class Rectangle extends Sharp{@Overridepublic void paint() {System.out.println("画一个矩形");}}static class Circle extends Sharp{@Overridepublic void paint() {System.out.println("画一个圆形");}}public static void main(String[] args) {DrawingEditor drawingEditor=new DrawingEditor();drawingEditor.draw(new Circle());drawingEditor.draw(new Rectangle());}}

迪米特法则

迪米特法则又叫做最少知道原则,就是说一个对象应当对其它对象有尽可能少的了解,不要和陌生人说话。
强调只和朋友说话,不和陌生人说话。这里的朋友指的是:出现在成员变量,方法输入,输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类
迪米特法则初衷在于降低类之间的耦合。由于每个类尽量减少对其它类的依赖,因此。很容易使得系统的功能模块独立,相互之间不存在(或很少有)依赖关系。
错误的例子

/*** @Author mabo* @Description   迪米特法则* @Description   直接朋友 要求依赖的类是成员变量,方法参数,方法返回值* @Description   最好将自己依赖的类作为成员变量,叫做类之间是朋友关系* @Description   对自己依赖的类,最好直接调用类的方法,而不是将类作为局部变量*/
public class DemeterBadExample {private static class Student{private List list=new ArrayList();public List getList() {return list;}public void setList(List list) {this.list = list;}public void addList(){list.add(1);}}public static void main(String[] args) {Student student=new Student();student.addList();List list = List();int size = list.size();System.out.println(size);}
}

正确写法

/*** @Author mabo* @Description   迪米特法则* @Description   直接朋友 要求依赖的类是成员变量,方法参数,方法返回值* @Description   最好将自己依赖的类作为成员变量,叫做类之间是朋友关系* @Description   对自己依赖的类,最好直接调用类的方法,而不是将类作为局部变量*/
public class DemeterPrinciple {//将需要依赖的类作为成员变量private static Student student=new Student();private static class Student{private List list=new ArrayList();public List getList() {return list;}public void setList(List list) {this.list = list;}public void addList(){list.add(1);}public int size(){return list.size();}}public static void main(String[] args) {student.addList();
//        List list = List();
//        int size = list.size();int size = student.size();System.out.println(size);}
}

本文发布于:2024-02-01 09:57:17,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170675263935827.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:示例   原则   模式   Java
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23