Java和Golang到底哪个语言更简单?

Java和Golang到底哪个语言更简单?,第1张

一旦您开始使用多种语言,您可能会开始质疑现状。您可能会以不同的方式看待事物,并为您钟爱的编程语言带回一些良好的习惯。我认为“代码简单”是软件开发的一个被低估的特性,我们需要更加关注代码的可读性和简单性。

Java 是并且一直是我在整个职业生涯中使用的主要编程语言。如果我想为原型快速构建一些东西,或者如果我需要在紧迫的期限内选择技术堆栈,那么 Java 是我的第一选择。特别是在 Java 8 之后,它的功能变得越来越丰富和强大。

当来自非 Java 社区的人抱怨 Java 冗长而复杂时,我实际上不明白这是什么意思?

近年来,我有机会在我的官方项目中使用 Go 和 DotNet Core 。除此之外,我还使用了NodeJS和Python,供我个人使用。

我理解为什么很多人喜欢NodeJS和Python,因为它们是一种包含电池的东西。对于 Java 中的相同任务,您可能需要包含外部库,而在 Python/NodeJS 中,标准库本身以非详细的方式提供大多数常用功能。如果您熟悉Kotlin,那么在使用C 时您会感到宾至如归 。

我对 Go 有过这样的经历。我第一次使用它时不太喜欢它,但关于 Go 的简单让我印象深刻!

我们来看下面的Java/SpringBoot代码。

@Service
@Transactional
@RequiredArgsConstructor
public class CustomerService {
    private final CustomerRepository customerRepository;
    private final AddressRepository addressRepository;

    public void createCustomer(Customer customer) {
        customerRepository.save(customer);
        addressRepository.saveCustomerAddress(customer.getAddress());
    }
}

对于至少使用过一次 SpringBoot 的任何 Java 开发人员,这段代码应该不需要任何解释。但是这里发生了很多事情。

在为CustomerService被标记为一个Spring bean可以注入到其它Spring Bean由于 Spring 4.x 不需要在构造函数上添加@Autowired注释。如果只有一个构造函数,它将自动用于创建 bean。该类使用@Transactional进行注释,这意味着当有人调用createCustomer()方法时,将启动并在成功完成后提交数据库事务。如果customerRepository.save()或addressRepository.saveCustomerAddress()方法抛出任何RuntimeException,则事务将自动回滚。如果CustomerService.createCustomer()是从不同类的另一个事务方法调用的,那么它将在父事务中运行而不是启动新事务。

虽然这看起来很熟悉且易于阅读,但在幕后发生了很多事情。

让我们看看下面的 Go 代码,它的作用与上面相同:

type CustomerService struct {
   customerRepository CustomerRepository
   addressRepository AddressRepository
}

func (c CustomerService) createCustomer(customer Customer) error {
    // Get a Tx for making transaction requests.
    tx, err := db.BeginTx(ctx, nil)
    if err != nil {
        return err
    }
    // Defer a rollback in case anything fails.
    defer tx.Rollback()
    
    err := customerRepository.save(tx, customer)
    if err != nil {
        return err
    }
    err = addressRepository.saveCustomerAddress(tx, customer.Address)
    if err != nil {
        return err
    }
    // Commit the transaction.
    if err = tx.Commit(); err != nil {
        return err
    }
    return nil
}

嗯,这是我们上面实现的相同功能的典型 Go 实现。假设它做了它打算做的事情,乍一看,这就是我的感觉:

每次第三条语句的错误检查都非常冗长DB 事务处理无处不在,我们可能需要对所有 DB 交互方法重复相同的 *** 作。业务逻辑和底层技术细节(错误/事务处理)纠缠不清

这里没有魔法:没有隐藏的魔法。一个有 20 多年经验的开发人员可以阅读和理解这段代码,就像一个有 6 个月经验的毕业生可以阅读和理解它一样。

但是,没有魔法意味着:……只有当你不明白它是如何运作的时候,它才是魔法。

这一点将我引向我想讨论的下一点。但首先让我们不要急于得出哪种语言更好的结论,因为这不是本文的意图。

开发人员在软件开发过程中面临的最大挑战是什么?

我们都知道,与编写新代码相比,我们花在阅读现有代码上的时间更多。在典型的长期企业应用程序开发中,现有开发人员离开,新开发人员加入项目,最大的挑战是理解现有代码。如果代码很简单,那么它很容易理解。

但是量化“代码简单性”并不容易。对你来说看起来更简单的东西,对我来说可能看起来很复杂,反之亦然。所以我们(开发人员和社区)尽最大努力寻找尽可能简单地编写代码的方法。不同的社区根据上下文、时间、需求等采取不同的方法。

下面是我对 Java 和 Go 如何采用不同方法来实现代码简单性的看法。

Java实现简单代码的方式:抽象

我觉得 Java 的标准库太低级和冗长,无法执行许多常见任务,例如读取文件、进行 HTTP 调用等。为了避免样板和冗长,创建了commons-lang、Guava等库,提供更高级别的抽象屏蔽开发人员的所有低级细节。

最重要的是,许多企业应用程序需要一组通用的功能,如日志记录、配置、监控等。因此创建框架来解决这些通用需求,抽象出通用应用程序级样板代码。

随着时间的推移,抽象之上有抽象之上的抽象……

但是,这些抽象通过处理应用程序级样板代码并 让您专注于业务逻辑来帮助您更快地构建业务应用 。

这样做的缺点是:程序员如果很好奇,需要“了解这些抽象在幕后如何工作,并在框架/库中发挥作用”。

在我看来,这就是事情严重出错的地方

现在,每家公司都希望全栈开发人员能够编写前端、后端和一些基础设施即代码。没有时间正确学习所有这些抽象在幕后是如何工作的。为了满足交付时间表,开发人员希望尽快完成工作。在那里添加这 2 个注释,在此处添加这 4 行配置,如果它正在工作,那么它就完成了。如果遇到任何错误,请搜索 stackoverflow 中的第一个建议,如果它有效,则完成。工作已经完成,但没有任何关于它实际工作方式的线索。

随着时间的推移,这种工作模式让人害怕说“Java 很复杂”。

Go实现简单的方式:清晰/详细胜过聪明

Go 社区更喜欢通过“no-magic”来保持代码简单,这意味着没有注释、没有反射、没有 ORM 等。有很多用于 ORM、Http 路由器等的库,但 Go 社区更喜欢“如果可能的话坚持标准库”方法。

Go 社区似乎更喜欢编写更清晰和冗长的代码,而不是创建巧妙的更高抽象。

最好的部分是使用 Go 的标准库,您可以在不需要外部依赖的情况下实现大部分应用程序需求,当然还有更多的代码行。

冗长的好处是“任何对 Go 有点熟悉的人都可以轻松阅读任何惯用的 Go 代码并理解它”!

如果你现在是 Go 的崇拜者,你可能会因为一遍又一遍地阅读“冗长”而生气,并问“冗长”是什么意思?

上面代码中几乎每三行实现一次错误检查,我们检查Map是否包含键等的方式在我看来都很冗长。

基于我对 Go 的有限经验,我非常喜欢它,因为它的“无聊”性质。为了学习 Go,我在 GitHub 上阅读了许多文章和开源代码库,没有太多新东西要学习。

在看到几个 Go 代码存储库后,认为:从企业长期应用程序开发的角度来看,这是一件了不起的事情。学习的魔力更少,新开发人员更容易入职。

我们如何让 Java 变得“更简单”?

Java 是大型企业的首选是有原因的。开发速度快,上市速度快。我可以自信地说,您可以在几个小时内使用 SpringBoot/Quarkus/Micronaut 创建生产级 Java 应用程序,而不是几周或几个月。由于这些框架已经提供了包含电池的应用程序框架,您需要做的就是编写业务逻辑。

如果我能从 Go 中汲取一些想法并将它们带到 Java,特别是 SpringBoot,那么这些将是:

除非是简单的 CRUD 应用程序,否则不要用ORM。我更愿意花费编写更多代码的一次性成本而不是重复调试成本。我更喜欢 JOOQ 而 不是JPA。我知道向后兼容性是 Java/SpringBoot 成功的关键原因之一。但我喜欢从 SpringBoot 中剥离一些东西 支持 XML 配置,我没有看到任何使用 XML 配置的绿地项目。XML 支持可以作为单独的模块提取。无需 从 14 个不同来源加载配置属性使用和调试 AOP 的一些更简单的方法(如果您曾经尝试过调试 AOP 代码,那么您就知道我在说什么)Quarkus喜欢实时重新加载和连续测试我们真的需要“com.mycompany.myproject.mymodule”的私有业务应用程序封装结构吗?对于开源库是的,但是对于商业应用程序??

总结

如果您是从未尝试过 Go 的 Java 开发人员,我强烈建议您看看 Go。你可能完全喜欢也可能不喜欢 Go,但你会爱上的东西却很少。

说了这么多,“Java 是并将永远是我最喜欢的语言”,从其他语言中学习东西的感觉很好。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/994859.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存