设计原则和思想:面向对象
面向对象两个重要的概念:类(class)和对象(object)。
面向对象编程是一种范式、一种风格,以类和对象做为组织代码的基本单元,封装、抽象、继承、多态、作为代码设计和实现的基石。
面向对象软件开发的三个阶段:面向对象分析(OOA),面向对象设计(OOD),面向对象编程(OOP)。
面向对象分析和设计最终产物是类的设计,包括程序被拆分为那些类,每个类有哪些属性和方法,类和类之间如何交互等。
面向对象分析是搞清楚要做什么,面向对象设计是搞清楚怎么做。
UML,统一建模语言,是一种沟通工具,以能说明白能看懂为第一准则。
封装:信息隐藏或数据访问保护。
封装解决的问题:
1、如果类中的属性可以随意修改,并且修改的方法散落各处,会影响代码的可读性和可维护性。
2、类提供有限的修改属性的方法可以使调用者更能正确的使用。
抽象:隐藏方法的实现细节,让调用者只关心方法提供了哪些功能,并不需要知道这些功能是怎么实现的。
抽象解决的问题:
1、让调用者更专注于使用,是处理复杂问题的有效手段
2、修改实现而不需要修改定义
继承:用来表达类于类之间的is-a关系,比如猫是一种哺乳类动物。
继承解决的问题:
1、解决代码复用问题
2、表达is-a关系,一种结构美感
3、继承存在一个问题就是层次过深之后就会导致代码可读性差,维护性差等问题,因此慎用,多用组合少用继承。
多态:子类方法 替换父类方法,包含以下三种机制:
1、父类对象可以引用子类对象
2、子类与父类存在继承关系
3、子类可以重写父类方法
多态解决的问题:
1、多态提高了代码的扩展性和可复用性。
2、是很多设计原则,设计模式,编程技巧的实现基础。
应该避免的看似是面向对象,实际是面向过程的操作:
1、滥用get()、set()方法
这种做法无视了封装的特性,跟直接设置publish属性没有区别。
2、滥用全局变量和全局方法
public class Constants { public static final String MYSQL_ADDR_KEY = "mysql_addr"; public static final String MYSQL_DB_NAME_KEY = "db_name"; public static final String MYSQL_USERNAME_KEY = "mysql_username"; public static final String MYSQL_PASSWORD_KEY = "mysql_password"; public static final String REDIS_DEFAULT_ADDR = "192.168.7.2:7234"; public static final int REDIS_DEFAULT_MAX_TOTAL = 50; public static final int REDIS_DEFAULT_MAX_IDLE = 50; public static final int REDIS_DEFAULT_MIN_IDLE = 20; public static final String REDIS_DEFAULT_KEY_PREFIX = "rt:"; // ...省略更多的常量定义... }
定义一个什么都有的Constants 类,这样做降低代码维护性,增加代码编译时间,影响代码复用性。应该哪个类用到了那个常量,就放到哪个类里面。
也不要定义一个大而全的Utils类 里面放着烂七八糟的静态方法,要将Utils类进行分类。
3、定义数据和方法分离的类(贫血模型)
一个类的属性和方法应该作为一个整体,一个类对象(充血模型)。
如何决定该用抽象类还是接口
如果我们要表示一种 is-a 的关系,并且是为了解决代码复用的问题,我们就用抽象类;
从类的继承层次上来看,抽象类是一种自下而上的设计思路,先有子类的代码重复,然后再抽象成上层的父类(也就是抽象类)。
如果我们要表示一种 has-a 关系,并且是为了解决抽象而非代码复用的问题,那我们就可以使用接口。
它是一种自上而下的设计思路。我们在编程的时候,一般都是先设计接口,再去考虑具体的实现。
基于接口而非实现编程
或者叫基于抽象而非实现编程,在软件开发的过程中应对不断变化的需求是最大的挑战之一,这也是考验代码设计好坏的一个标准。
越抽象、越顶层、越脱离具体某一实现的设计,越能提高代码的灵活性,越能应对未来的需求变化。好的代码设计,不仅能应对当下的需求,而且在将来需求发生变化的时候,仍然能够在不破坏原有代码设计的情况下灵活应对。而抽象就是提高代码扩展性、灵活性、可维护性最有效的手段之一。
比如使用阿里云oss作为文件存储时,上传文件需要进行如下步骤:1、创建存储目标 2、获取token 3、将带有token的文件上传至目标 。实现大家应该脑子一过就猜到了,如何进行抽象才是好设计的关键。如果换用私有云文件服务器进行存储,怎么能够抽象出不变的接口,而替换变化的实现,那就是好的设计。
1、获取token 就应该进行封装,不要暴露于抽象功能无关的细节。
2、创建存储目标和上传文件至目标,再抽象成定义文件目录,和上传至文件目录,抽象出一致的行为,遵从一致的上传下载协议。
3、接口不能带有uploadToAliyun,这种指向性强的字眼,要使抽象出来的行为具有通用性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通