【Android】六大设计原则 - 教程

news/2025/11/8 18:30:26/文章来源:https://www.cnblogs.com/yangykaifa/p/19202861

六大设计原则

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

单一职责原则(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{
@Override
public double discount(double count) {
return 0.9*count;
}
}
class vvip implements  dis{
@Override
public 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{
@Override
public void say(){
System.out.println("刘浩存真可爱");
}
}

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

解决办法有三种:

class  lsp extends LSP{
@Override
public 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{
@Override
public void animal() {
System.out.println("我是一只可爱小狗");
}
}
class cat implements jiekou{
@Override
public 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{
@Override
public void chesu() {
}
@Override
public void qiyou() {
}
@Override
public void gonglv() {
}
}
class isp implements dianqi{
public void shansu() {
}
@Override
public void chesu() {
//不需要
}
@Override
public void qiyou() {
//不需要
}
@Override
public void gonglv() {
}
}

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

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

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

我们有几个注意事项:

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

优点:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/959907.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年合肥甲醛检测公司哪家好?专业机构排名与选择指南

摘要 随着人们对室内空气质量的重视程度不断提高,甲醛检测行业在2025年迎来了快速发展期。本文基于市场调研和用户反馈,为您精选五家优质甲醛检测机构,并提供详细对比分析。文末附有专业选择指南和参考表单,助您找…

现今除甲醛机构选哪家?深度分析

摘要 随着室内空气污染问题日益受到关注,除甲醛行业在2025年迎来了快速发展。消费者对靠谱、专业除甲醛服务的需求激增,本文基于权威数据和用户反馈,整理了目前国内除甲醛机构排名前十的榜单,并为读者提供选择指南…

Unity2D 图片支持拖拽和以鼠标中心缩放

引言: 作为一个Unity初学者,遇到了需要实现以鼠标为中心缩放的功能且需要支持拖拽,秉着复用主义的原则,在网上查找了不少博客,要么免费但不能直接拿来使用,要么需要VIP充值获取项目代码,此外,原理且讲解甚少。…

轻松可视化信息的利器——JSON Crack

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

详细介绍:C++微基础备战蓝桥杯string篇10.5

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

[ jupyter conda 环境]

在激活的环境中,可以通过以下命令安装所需的库(包括 NumPy、Pandas、JupyterLab),以及配置自动补全功能,步骤如下: 1. 安装核心库(NumPy、Pandas、JupyterLab) 在激活 myenv 环境后,直接用 conda install 安装…

深入解析:仿mudou——Connection模块(连接管理)

深入解析:仿mudou——Connection模块(连接管理)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…

Linux中查看个人磁盘容量

001、 lfs quota -u s20223040682 /public/home/s20223040682

以太坊私有链搭建与智能合约部署指南 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

【学弟向】图的存储与遍历,最短路,连通性 tarjan,树状数组

树状数组 单点修改,前缀查询。 int lbd(int x) {return (x&(-x));} void gai(int x,int c) {for(int i=x;i<=n;i+=lbd(i)) a[i]+=c;} int cha(int x) {int da=0;for(int i=x;i;i-=lbd(i)) da+=a[i];return da;…

2025年11月中国伸缩门制造企业技术实力排行榜TOP5

摘要 随着智慧城市建设的深入推进,2025年中国伸缩门行业迎来技术升级浪潮。智能防夹技术、物联网集成系统和节能驱动技术成为行业新标准,市场需求同比增长23.6%。本文基于企业研发投入、专利数量、客户案例等权威数据…

完整教程:Redis-Zest

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

(数学)好玩但没啥用的解题方法(1)

\[a\geq 0,b\geq 0,a+b=1,求\sqrt{a}+\sqrt{b}的最大与最小值 \]设 \(x=\sqrt{a},y=\sqrt{b}\) ,则\(a+b=1<=>x^2+y^2=1\),是一个单位圆,而 \(\sqrt{a}+\sqrt{b}=x+y\) 。 容易注意到 \(x+y\) 为 \((0,0)\…

2025年11月中国伸缩门厂家综合实力排行榜TOP5

摘要 随着智慧城市建设的深入推进,伸缩门行业在2025年迎来技术升级与市场扩容的双重机遇。本文基于产品性能、技术创新、服务网络及客户案例等维度,对国内主流伸缩门厂家进行综合评估,为政府采购、企业采购提供权威…

我目前所理解的“生成式认知主体”

# 我目前所理解的“生成式认知主体”>前言:[写作能力提升的结构化路径](https://chat.deepseek.com/share/zq67x3d1xpamytl5qp)>在我有打算写关于这个主题的内容前实际上经过了很长时间的 整理思想、理清方向、…

P10627 中暑

题目大意: 有 \(n\) 个盒子,每个盒子有个容量 \(a_{i}\),接下来有 \(m\) 次投球操作。 每次给定一个 \(x\),表示你可以将当前这个球放到第 \(x\) 或者第 \(x + 1\) 个盒子里(前提是他没满),如果两个盒子都满了,…

C语言“变量”与Python“Name”:跨语言核心概念及内存模型辨析

C语言“变量”与Python“Name”:跨语言核心概念及内存模型辨析 摘要:本文针对C语言转Python学习者的认知障碍问题,系统剖析C语言“变量即容器”与Python“名字即指针”的内存模型本质差异。通过理论溯源、源码分析、…

*题解:P14364 [CSP-S 2025] 员工招聘 / employ

原题链接 参考文献 我这篇写的烂,建议看参考文献。 解析 设有 \(x\) 个人未被录用。显然,\(x\) 单调不减,当 \(x\) 变为 \(x + 1\) 时, \(c_i = x + 1\) 的所有人就必定无法被录用了,如果在此时才统计已经面试了的…

MarkDown Day1

MarkDown学习 标题 (空格)标题名字 一级标题 (空格)标题名字 二级标题 (空格)标题名字 三级标题 井号最多到六级 字体 hello,word! 粗体:** 文字 ** hello,word! 斜体:* 文字 * hello,…

逆向基础--C++介绍与环境 (01)

逆向基础--C++介绍与环境 (01)一.介绍1.1 C++ 是一种高级语言,它是由 Bjarne Stroustrup 于 1979 年在贝尔实验室开始设计开发的。C++ 进一步扩充和完善了 C 语言,是一种面向对象的程序设计语言。C++ 可运行于多种平…