三层架构就不面向对象了?

本文探讨了三层架构常被误解为不面向对象的问题,指出三层架构与四层架构的区别主要在于应用层。强调通过设计模式如组合模式和外观模式来改善三层架构。同时,作者提醒开发者关注代码质量,遵循SOLID原则,提高代码的可读性和可维护性,并分享了几个优化代码的实例,包括方法职责单一、利用return提前返回、使用基础类型、参数封装以及使用Creation Method替换构造函数。文章强调,面向对象设计的挑战在于如何将复杂数据转化为行为对象,呼吁开发者重视代码质量。
摘要由CSDN通过智能技术生成

经常在群讨论系统架构的事情,从三层架构 — 四层架构 — 六边形架构,开始有了鄙视链,使用过四层架构的开始鄙视三层架构了,用过六边形架构的就更不用说了。这就好比使用了领域模型后开始吐槽 “Service + 贫血模型” 和 “事务脚本” 。

 

也经常看到吐槽的,现在公司用的三层架构就是咸鱼,事实上三层架构和四层架构之间只有一个区别,那就是应用层。应用层做的事情则是对领域服务对编排,事务的处理。

 

那对于三层架构来说,我们可以通过设计模式中“组合模式”或者“外观模式”去创建编排领域服务。

 

void save(){
    xxxSerivce.save();
    xxxxService.save();
    xxxxxService.save();
}

 

private Animal cat;
private Animal dog;
public AnimalFacade() {
    this.cat = new Cat();
    this.dog = new Dog();
}

public String dogWalk(){
    return dog.walk();
}

public String catWalk(){
    return cat.walk();
}

 

@Test
public void should_show_test() {
    AnimalFacade animalFacade = new AnimalFacade();
    assertThat(animalFacade.catWalk(), is("cat walk"));
    assertThat(animalFacade.dogWalk(), is("dog walk"));
}

 

另外,有同学会说大部分系统不需要什么复杂的架构模式,也不需要什么CQRS,只需要把代码库写得更 OO 一些,把SOLID设计原则理解透了就行。

 

是的,没错,我们经常忽略了代码的问题,忽略一个可复用面向对象的代码库。经常去套用这些架构模式,事实这些架构模式本质是通过SOLID原则和GoF 设计模式演变而来的。

 

昨天我们小伙伴分享了一篇文章叫 Java函数优雅之道,分享的特别好。讲到了很多人写代码不注意的地方,导致系统可维护性、可调整、可读性变差。

 

分享几个案例:

 

1、一个方法干几件事情,代码可读性差,要使用内部的业务方法没法使用

 

void save(){
    if (relateTable.equals("1")){
        // 去做等于1事情的代码
        // xxxxx
        // xxxx
    }
    if (relateTable.equals("2")){
        // 去做等于2事情的代码
        // xxxxx
        // xxxxx
    }
    if (relateTable.equals("3")){
        // 去做等于3事情的代码
        // xxxxx
        // xxxx
    }
}

 

调整如下:

 

void save(){
    if (relateTable.equals("1")){
        relateTable1();
    }
    if (relateTable.equals("2")){
        relateTable2();
    }
    if (relateTable.equals("3")){
        relateTable3();
    }
}

void relateTable1(){
    // 业务
}

void relateTable2(){
    // 业务
}

void relateTable3(){
    // 业务
}

 

还能优化吗? 肯定是可以的,if 里面判断是不是可以提取一个方法。

 

void save(){
    if (isRelatedTable("1")){
        relateTable1();
    }
    if (isRelatedTable("2")){
        relateTable2();
    }
    if (isRelatedTable("3")){
        relateTable3();
    }
}

private boolean isRelatedTable(String relatedTable) {
    return relateTable.equals(relatedTable);
}

 

2、利用 return 提前返回,这个是大多数时候都忽略的点,我们的习惯都是当某个对象不为空,然后去处理业务,否则 再干什么。代码如下:

 

User modify() {
    User user = getUser(id);
    if (user != null) {
        // xxxx 业务
    } else {
        return null;
    }
    return null;
}

 

调整如下

 

User modify() {
    User user = getUser(id);
    if (user == null) {
        return null;
    }
    // 业务
    return user;
}

 

是不是看着舒服,清爽些。

 

3、尽量使用基础类型

 

Double price = 5D;
Integer number = 2;
Double calculate(Double price, Integer number){
    return price * number;
}

 

建议如下

 

double price = 5D;
int number = 2;
double calculate(double price, int number){
    return price * number;
}

 

为啥?因为Java 内一切皆对象,基本类型不是对象,一个是将值存在堆栈中,一个是将对象实例存在堆中。哪个快自然就知道了。

 

4、参数进行封装,这个是最基本的,早期个人没有注意导致代码可读性差,修改起来贼麻烦。

 

void modify(int id, String name, String age, String sex, String phone);

 

要加一个字段,你得把数据层、领域层、用户层都给改一遍,你就痛苦了。

 

void modify(User user);

 

不管你后期要加什么,只需要修改对象user,和对应资源库的映射。

 

5、Creation Method 替换构造函数,构造函数最头疼的是属性参数数量的问题,构造函数一多,new 的时候就不知道用哪个了,出现问题非常不好找,导致要去一个个去对照相应的属性。

 

class Order{
    int id;
    String no;
    double total;
    double discount;
    int number;
    Date date;
    public Order(int id, String no, double total, double discount, int number, Date date) {
        this.id = id;
        this.no = no;
        this.total = total;
        this.discount = discount;
        this.number = number;
        this.date = date;
    }

    public Order(int id, String no, double total, double discount, int number) {
        this.id = id;
        this.no = no;
        this.total = total;
        this.discount = discount;
        this.number = number;
    }

    public Order(int id, String no, double total, double discount) {
        this.id = id;
        this.no = no;
        this.total = total;
        this.discount = discount;
    }

    public Order(int id, String no, double total) {
        this.id = id;
        this.no = no;
        this.total = total;
    }
}

 

建议如下:

 

 
public static Order saveOrder(int id, String no, double total, double discount, int number, Date date) {
    return new Order(id, no, total, discount, number, date);
}

 

很好的暴露了使用意图,便于后来开发者调用。

 

写了一篇随笔,最后做个总结

 

忘了,在哪本书,哪篇文章里面看到,面向对象最难的在于如何将一个表里面20个属性,拆分成一个个行为对象,这个得依据实际经验与实际场景。

 

重视代码、重视代码、重视代码,重要的事情说三遍。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值