当前位置: 首页 > news >正文

【Android】六大设计原则

六大设计原则

为了提高代码的可维护性,可扩展性,减少开发人员开发和维护的成本,减少系统出错;我们需要做到高内聚,低耦合;那么这里有六大设计原则,快来学习一下把;

单一职责原则(SRP)

介绍:

一个类应该只有一个引起它变化的原因。每一个类应该只负责一个职责。

违反常见问题:

  1. 当一个类承担过多职责时,耦合度比较高,当一个实则需要修改时,可能会导致其他职责被迫修改;
  2. 由于职责较多代码量较大,开发人员维护困难;
  3. 难以进行单个功能的测试;

例子:

public class SRP {private int elpee;private int money;public SRP(int elpee, int money) {this.elpee = elpee;this.money = money;}public int getMoney() {return money;}public int getreport() {return 12;}
}

修改后:

public class SRP {private int elpee;private int money;public SRP(int elpee, int money) {this.elpee = elpee;this.money = money;}public int getMoney() {return money;}
}
class getmoney{public int getMoney(SRP S) {return S.getMoney();}
}
class getreport{public int getrepoet(SRP S) {return 23;}
}

修改前后的区别在于为不同的功能创建了不同的类,这样的话如果要修改类,不需要需要SRP这个类,只需要修改对应的功能类就好,还方便测试等;

可能违反SRP的情况:

  1. 当一个类承担了很多职责,比如ui,数据库,业务逻辑处理;
  2. 当一个类被修改多次;
  3. 方法很多的时;

扩展点:

我们可以引入多层次的划分,例如:

  • 业务逻辑层:具体的业务和数据处理;
  • 数据访问层:与数据库文件等数据存储相关操作;
  • 服务层:封装业务逻辑层,数据访问层的交互;

根据不同层次的划分,使用单一职责原则更加得心应手;

开放-关闭原则(OCP)

介绍:

软件实体(如类、模块、函数等)应该对扩展开放,对修改关闭。当有需求变化时,软件系统应该拓展新功能,而不是修改现有的代码;

优点:

  1. 有利于代码的稳定性和可维护性。当有新功能时,我们不修改现有的类或者方法,而是通过继承或者接口去添加新的模块来实现功能;
  2. 减少代码量的重复。只需要扩展特定的模块,不需要在系统其他地方去增加代码量,减少代码量;
  3. 减少修改风险。减少因为修改代码而破坏已有功能;

如何实现:

开放-关闭原则通常依赖于多态性继承接口编程,而非依赖具体实现;在不修改原有代码的基础上进行扩展;

这里选择了策略模式来实现OCP原则:
策略模式:定义一系列算法(策略),并将每种算法封装到独立的类中,使它们可以互相替换;客户端(使用者)可以在运行时选择不同的策略,而不用修改原有代码。

class OrderService {public double calculateDiscount(String type, double price) {if ("normal".equals(type)) {return price;} else if ("vip".equals(type)) {return price * 0.9;} else if ("svip".equals(type)) {return price * 0.8;}return price;}
}

现在需要新增功能,那么就是需要新增else if语句,如果在软件系统其他地方用到,那么就会新增代码量;那么使用ocp原则这么写:

public interface dis {public double discount(double count);
}public class vip implements  dis{@Overridepublic double discount(double count) {return 0.9*count;}}class vvip implements  dis{@Overridepublic double discount(double count) {return 0.8*count;}}
class discount{public double getdiscout(dis dis,double money){return dis.discount(money);}
}

定义一个接口,功能通过实现这个接口的方法来完成,通过一个类,参数是接口,通过多态来调用不同类中的方法来实现功能;

里氏替换原则(LSP)

介绍:

  1. 定义:任何基类可以出现的地方,子类一定可以出现。
  2. 和开闭原则的关联:里氏替换原则其实是对开闭原则的补充,开闭原则的重要一步就是抽象化,基类和子类的继承就是抽象化的一种表现,那么LSP就是对实现抽象化的规范;
  3. 为什么要这么要求:这么要求的情况下,子类才是对基类做到了扩展,有利于代码的维护和减少了错误;

这就要求我们尽量不要重写和重载基类的方法,否则有可能造成基类的方法原有功能的故障;(有时候我们会使用final来强制遵循);不仅如此,假如改变了基类,那么所有的子类有可能会发生故障;

如何实现:

public class LSP {public void say(){System.out.println("所有人都好可爱");}
}
class  lsp extends LSP{@Overridepublic void say(){System.out.println("刘浩存真可爱");}
}

这里将say方法进行了重写,那么我们将无法使用基类的功能,所有人都好可爱;

解决办法有三种:

   class  lsp extends LSP{@Overridepublic void say(){super.say();System.out.println("刘浩存真可爱");}}

保留父类的方法和功能,子类进行扩展;

  1. 重新写构造一个方法功能,不重写,写一个Liusay()方法;

  2. 抽象出一个新类,使得父类和子类都去继承这个类;把原来的继承关系去掉,采用依赖,组合等关系代替;

理解里氏替换原则:

核心:不改变父类的功能,而是对父类的功能进行扩展;

  1. 不改变父类的功能:可以实现抽象方法,但不能覆盖父类的非抽象方法;
  2. 可以增加新的方法功能;
  3. 当子类重载父类的方法时,后置条件(参数)要比父类更宽松,使得能使用父类这个功能的条件也能使用子类的方法;
  4. 当子类实现父类的抽象方法时,前置条件(返回值)要比父类更严格;可以代替而且还更加精确了;

依赖倒置原则(DIP)

介绍

  1. 定义:高层模块不应该依赖底层模块,而是依赖于抽象;抽象不应该依赖于细节,细节依赖于抽象;

优点

  1. 降低了耦合度;
  2. 增加了可维护性和可拓展性;

实例:

public class DIP {public void dog(){System.out.println("我是一只可爱小狗");}
}
class dip {public void animal(DIP D){D.dog();}
}

这里dip类依赖于低层模块DIP,违反了依赖倒置原则;

interface jiekou{void animal();
}
public class DIP implements jiekou{@Overridepublic void animal() {System.out.println("我是一只可爱小狗");}
}
class cat implements jiekou{@Overridepublic void animal() {System.out.println("我是一只可爱小(>^ω^<)喵");}
}
class dip {public void say(jiekou a){a.animal();}
}

这里即使新增加低层,也蛮符合单一职责原则的;

这里有一个接口,低层实现这个接口,那么高层则可以依赖接口而不是依赖细节;这里细节指的是具体的实现;

迪米特法则(lOD)

介绍

  1. 也称最少知识原则,一个对象尽可能少的了解其他对象的细节;一个对象不应该过多的依赖其他对象的内部结构和实现细节。对象之间应该尽可能通过有限的,直接的接口进行,不是一长串的调用链;
  2. 只与朋友通信,不与陌生人通信;

这里的朋友是指:

  1. 自身:自己的方法和属性;
  2. 成员对象:;
  3. 方法参数;
  4. 创建的对象;
  5. 全局变量或实例对象;

实例:

public class LOD {public lod getlhc(){return  new lod();}
}
class lod{public  void getljx(){}
}
class lods{public  void get(LOD lod){lod.getlhc().getljx();}
}

这里lods类直接依赖于lod,不应该暴露lod类,违反了迪米特法则;

public class LOD {private lod lod;public void getlhc(){lod.getljx();}
}
class lod{public  void getljx(){}
}
class lods{public  void get(LOD lod){lod.getlhc();}
}

这里使用了方法对lod类的对象进行了封装,直接调用,而不是新new了一个对象,把对象暴露了出来违法法则;

接口隔离原则(ISP):

介绍:

一个类对另一个类的依赖应该建立在最小的接口上;

接口尽量小而精;不要建立庞大的接口,接口中的方法最好少而精;

尽量为一个类定制一个接口,而不是用一个庞大接口使依赖它的所有类通用;

例子:

比如ISP类代表汽车,需要实现三个方法 void chesu();void qiyou(); void gonglv();

但是isp类代表风扇,需要实现两个方法 shansu()void gonglv();

interface dianqi{void chesu();void qiyou();void gonglv();
}
public class ISP implements dianqi{@Overridepublic void chesu() {}@Overridepublic void qiyou() {}@Overridepublic void gonglv() {}
}
class isp implements dianqi{public void shansu() {}@Overridepublic void chesu() {//不需要}@Overridepublic void qiyou() {//不需要}@Overridepublic void gonglv() {}
}

这样的接口就很臃肿;而且实现了不需要的两个方法;

interface dianqi{void gonglv();
}
interface ISPI{void chesu();void qiyou();
}
interface shan{void shnsu();
}

这样设计的接口合理且精确;

我们有几个注意事项:

  1. 接口尽量小,但是要有限度;接口的粒度较小,可以增加灵活性;但接口的数量过多,也会使设计复杂化;
  2. 建立最小的依赖关系,给需要依赖的类定制方法;

优点:

降低耦合度,提高可维护性和灵活性;
本次介绍到此结束,谢谢大家!

http://www.dtcms.com/a/470066.html

相关文章:

  • 液压位置控制源代码实现与解析(C语言+MATLAB联合方案)
  • 技术拆解:基于成品源码的海外外卖跑腿平台部署指南
  • 宽城网站制作山东网站建设网站
  • 申论素材学习笔记-把握好人才工作辩证法
  • 深度学习入门(三)——优化算法与实战技巧
  • 最新短视频AI智能营销询盘获客系统源码及搭建教程 源码开源可二次开发
  • 易优cms仿站教程wordpress文章搜索排序
  • 什么网站能免费做简历wordpress汉字注册
  • 喜报!网易灵动荣获2025全球数贸创新大赛机器人赛道金奖
  • AI IDE/插件(二)
  • 一文掌控系统网络性能:Linux环境时延与带宽测试指南
  • Effective Python 第44条:用纯属性与修饰器取代旧式的 setter 与 getter 方法
  • 中国网站排名站长之家有哪些好玩的网页游戏
  • 从零开始:Godot打造2D像素冒险游戏
  • 全球十大互联网企业深圳网站设计专家乐云seo品牌
  • 如何进行后端开发:一个详细指南
  • 基于Spring Boot的酒店管理系统
  • 怎么用腾讯云服务器做网站建个人网站做导购怎么备案
  • 单页面网站设计有人做网站吗
  • 编程与数学 03-007 《看潮资源管理器》项目开发 03 技术选型
  • LeetCode每日一题,20251011
  • Linux c 在内存中创建zip,最后写入测试
  • 做品牌推广用什么网站眉山网站开发
  • 静态网站源码下载东营免费网站制作
  • 智能体架构设计
  • 2025年三个月自学手册 网络安全(黑客技术),新手小白看这一篇就够了!
  • 无锡做网站要多少钱织梦网站栏目不能更新
  • 网站设计制作公司需要什么资质西部数码网站管理助手 破解版
  • 物联网卡的TAC
  • 学习物联网可以做什么工作?