面向对象编程与面向对象分析
- 面向对象编程
- 不是使用面向对象的编程语言进行编程就叫面向对象编程
- 面向对象编程,应该是利用多态等面向对象的特性进行编程
- 多态是面向对象语言区别于其他语言的根本特点
- 面向对象分析
- 充血模型与贫血模型
- 领域驱动设计DDD
框架
用来实现某一类应用的结构性的程序,是对某一类架构方案可复用的设计与实现。
- 简化开发者的工作
- 框架会影响一个架构师在团队中的技术地位。
- 框架是架构落地的保证。
- 和工具的区别
- Junit是框架。框架调用我们写的代码。
- log4j是工具。我们在代码中调用工具。
软件设计的『臭味』
- 僵硬;不易改变。
- 脆弱;只想修改A,结果B被意外破坏。
- 不可移植;不能适应环境的变化。
- 容易被误用:做错误的事比做正确的事情更容易;
- 过度设计
- 不必要的重复,重复代码
- 牢固性:很难解开系统模块,不利于重用
- 粘滞性:做正确的事情比做错误的事情要困难
软件设计的原则
- 开闭原则
- 依赖倒置原则(DIP)
- DIP倒置了什么
- 倒置的是高层模块和低层模块之间的抽象是属于谁的,谁来定义的
- controller->IService->ServiceImpl
- IService应该由controller根据自身的逻辑定义有哪些方法,而不是由Service定义。
- controller定义了IService,具体实现再由低层模块去实现。
- 开发顺序和职责
- 倒置的是高层模块和低层模块之间的抽象是属于谁的,谁来定义的
- 框架是基于DIP实现的
- 框架不需要让你的代码调用,而是用来调用你的代码。
- 框架完成程序的架构,负责组织和调用你的代码
- 开发人员只需要按照框架提供的约定,来实现具体业务逻辑,甚至不需要了解框架的运行机制,也能保证程序的正常
- 提供具体接口让开发人员来调用的,不是框架,而是工具。
- 倒转层次依赖关系
- 框架不需要让你的代码调用,而是用来调用你的代码。
- DIP倒置了什么
- 里氏替换原则(LSP)
- 程序中使用父类的地方,都可以用子类替代。
- 子类要拥有父类的所有接口。
- 子类重写父类的方法,子类的要求不可能比父类更严格(父类是protect,子类是private)。
- 正方形不应该继承长方形。
- 因为如果父类的输入参数类型宽于子类的输入参数类型,会出现父类存在的地方,子类就未必可以存在
- 子类重写父类的方法,父类方法抛出异常A,子类方法抛出的异常B一定是A或者A的子类
- 怎么解决
- 用组合替换继承
- 程序中使用父类的地方,都可以用子类替代。
- 单一职责原则(SRP)
- 接口分离原则(ISP)
- 不应该强迫客户依赖他们不需要的方法。
经验
- 少写或不写if/else
- JDK中违反LSP的案例
- 推荐设计原则的书:敏捷软件开发:原则、模式与实践
参考资料
轻松学,浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)