• Home
  • Archives
  • 随笔
所有文章 友链 关于我

  • Home
  • Archives
  • 随笔

OOP面向对象的思想

发布于: 2021-09-16
更新于: 今天

OOP

继承与组合

关系浅时可用继承,复杂时组合代替,像装饰者模式、策略模式、组合、模板等设计模式

当没办法修改一个外部类代码时,可以通过继承形式进行重写函数代码

class ForeignApi{
   public void hello(){ // need override}
}

class NewApi extends ForeignApi{
 @Override
 public void hello() { //new thing}
}

class God{
 public void xxxFunction(ForeignApi api){
  // need override
  api.hello();
 }

 void main(){
  ForeignApi api=new NewApi()
  xxxFunction(api);
 }
}

为什么不推荐用继承

  • 继承层次过深,继承关系过于复杂影响可读性和可维护性

  • 比如说粽子有甜的、咸的、辣的,AbstractSweet··· 同时还有方的三角形的,AbstractSweetTriangle··· 太过复杂

  • 如果用接口实现

    • 道滘粽子 implements Sweetable,Triangle
    • 福建粽子 implements Slaty, Triangle
    • 但每个粽子都要实现重复的三角形代码,造成代码重复
  • 如果用组合实现

    • 给接口定义实现类, TriangleAblity{ triangle(){ //make triangle}

    • 原本的实现地方通过委托,把实现代码交给 Ablity

      class 道滘粽子 implements Triangle{
           // 组合
           TriangleAblity ablity=new TriangleAblity();
           @Override
           public void triangle(){
                 // 委托
                 ablity.triangle()
           }
      }
      

抽象类与接口

抽象类不能被实例化,只能被子类继承,表达 is-a 的关系

  • 实现代码复用功能
  • 编译器强制要求实现 Override 抽象方法

而接口表达 has-a 关系,表示具有某种功能,表达协议(contract)

  • 侧重于解耦,对行为的一种抽象,表达一组协议或者契约(比如说 Cloneable)

  • 如何实现基于接口编程呢?(三点)

    • 函数命名不暴露细节(比如说 sendRabbitMq)
    • 封装具体的实现细节,对外提供服务的接口应该是抽象涵盖所有含义的,比如说+send(msg)/+receive()
    • 为实现类定义抽象的接口。使用者依赖接口实现 RabbitMq implements Mq

四大特性

封装(Encapsulation)

  • 通过暴露有限的访问接口,授权外部通过类的方式访问内部数据或者数据(通过修饰符 private、protected、public 控制)
  • 保护数据不被随意修改、提高可维护性
  • 提高类的易用性

抽象

  • 关心方法提供什么功能,不关注实现方式(通过 interface、abstract class 实现)
  • 提高代码可扩展性、维护性,修改实现不需要改变定义,减少改动范围
  • 解决复杂系统,有效过滤不必要的关注信息

继承

  • 表达类之间 is-a 的关系,比如 Dog is a Animal,分为单继承、多继承
  • 解决代码复用的问题

多态

  • 指子类可以替代父类
  • 继承、接口、duck-typing
  • 提高代码的扩展性和复用性

面向对象与面向过程的开发模式

面向对象与面向过程的开发模式

贫血与充血

贫血(Anemic Domain Model)

  • 数据与操作分离,PrizePO、PrizeBO+搭配 PrizeRepository 进行操作

充血(Rich Domain Model) 与 DDD(Domain Driven Design)

  • 将原本操作数据的逻辑迁移至实体类中,由 Service 操作数据变成委托实体自己操作数据

    
    public class Prize{
     private long remainStock;
     public void deductPrizeInventory(){
      this.remainStock--;
     }
    }
    
    class XXXService{
     public void deductPrizeStock(){
      Prize prize= xxx.getPrize();
      // 委托Prize进行奖品库存的扣减
      prize.deductPrizeInventory();
     }
    
    }
    

DDD 与 MVC 的差异

DDD 的特点

DDD 开发时要划分业务领域间的边界,定义上下文,跨领域访问都必须通过制定服务操作

MVC 的特点

MVC 大多是 SQL 驱动的开发模式,由表结构定义到具体的仓储层、服务处、操作器层(Repository/Service/controller)换句话说对应 PO、Entity、VO

差异

  • 主要在 Service 层的实现,Controller 和 Repository 层基本一致

  • DDD 的 Service 相比更薄

    • 负责与仓储层交流
    • 负责跨领域的访问以及聚合的功能,比如说想要调用第三方系统进行奖品的发放,就要通过 Service 去访问第三方系统的逻辑。如果简单可以集成到 Service,如果较为复杂,可以将发奖模块抽象成一个领域模型

Controller 与 Repository 都是贫血模型

  • Controller 一般只负责将数据透传给其他系统,不涉及复杂的业务逻辑,使用 VO 简单开发即可
  • Repository 一般只负责与第三方系统进行交互,通常只是数据的 CRUD,不涉及复杂的业务逻辑,简单开发即可
OOP面向对象的思想
/archives/undefined/
作者
tyrantqiao
发布于
2021-09-16
更新于
2024-06-30
许可协议
CC BY-NC-SA 4.0
赏

蟹蟹大佬的打赏,大家一起进步

支付宝
微信
  • JAVA

扫一扫,分享到微信

微信分享二维码
扫码登录的实现逻辑
Spring源码系列一始而终
© 2024 tyrantqiao 本站总访问量次 本站访客数人次 载入天数...载入时分秒...
  • 所有文章
  • 友链
  • 关于我

tag:

  • 复盘
  • 我
  • 规划
  • java
  • 面试
  • 源码
  • 架构
  • Hadoop
  • HTTP
  • TCP
  • 学习笔记
  • IDEA
  • maven
  • idea
  • Java
  • jdk
  • 面经
  • linux
  • 爱情
  • mysql
  • 性能
  • sql
  • Mysql
  • JAVA
  • 技术
  • Redis
  • MQ
  • Spring
  • 数据库
  • TIDB
  • spring
  • unity
  • chatgpt
  • 经验分享
  • 前端
  • redis
  • vue
  • git
  • shadowsocks
  • hexo
  • blog
  • bug
  • 开发
  • 业务
  • jvm
  • 算法
  • MySQL
  • nginx
  • Linux
  • mq
  • db
  • springCloud
  • ssh
  • python
  • 爬虫
  • test
  • vim
  • 影视剧
  • 中间件
  • 事务
  • 性格
  • 音乐
  • 程序员
  • 随笔
  • mybatis
  • 演讲
  • 域名
  • 猫咪
  • 她
  • github
  • 计划
  • 旅游
  • 软件
  • 心理
  • 情商
  • 幽默
  • 才艺
  • 穿搭
  • 编程
  • 排序
  • 查找
  • 缓存
  • 网络
  • 设计模式
  • c
  • 课程设计
  • centos
  • 数学
  • 本网站主题yilia设计者的主页
如果有问题或者想讨论的可以联系[email protected]或者[email protected]