【问题标题】:How to prevent generic usage of a certain API (e.g Streaming API or Builder API) with ArchUnit?如何防止 ArchUnit 对某个 API(例如 Streaming API 或 Builder API)的通用使用?
【发布时间】:2021-09-27 11:38:46
【问题描述】:

给定一组不应禁止使用某些 API(无论出于何种原因)的类。

例如,禁止 Java 8 Streaming API,或调用 Builder 内部类,因为您想强制对特定类使用循环和构造函数。

关键部分是您事先不知道 ownerName 并且没有 callMethod(methodName) 我可以粗粒度地禁止调用 stream()build() 方法。

有什么想法吗?

【问题讨论】:

    标签: archunit


    【解决方案1】:

    您可以使用谓词而不是流畅的 API 来编写强大的ArchRules;在你的情况下 .callMethodWhere(DescribedPredicate<? super JavaMethodCall> predicate).

    为了防止someCollection.stream()的使用,你可以以HasName.Predicates.name开头:

    noClasses().should().callMethodWhere(name("stream"))
    

    为避免误报,规则应该更加具体。

    ArchUnit 提供了许多有用的预定义谓词;您只需要找到它们(并可能通过DescribedPredicate.forSubtype 处理它们的协变参数类型):

    noClasses().should().callMethodWhere(target(
        name("stream").<CodeUnitCallTarget>forSubtype().and(
            owner(assignableTo(Collection.class)).<CodeUnitCallTarget>forSubtype().and(
                    rawParameterTypes(new Class[0])
            )
        )
    ))
    

    我个人觉得定义一个自定义谓词更简单(例如,使用 DescribedPredicate.describe):

    noClasses().should().callMethodWhere(target(describe("is Collection.stream()",
        target -> "stream".equals(target.getName()) &&
                target.getOwner().isAssignableTo(Collection.class) &&
                target.getParameterTypes().isEmpty()
    )))
    

    仅供参考:我的解决方案使用以下导入:

    import static com.tngtech.archunit.base.DescribedPredicate.describe;
    import static com.tngtech.archunit.core.domain.JavaCall.Predicates.target;
    import static com.tngtech.archunit.core.domain.JavaClass.Predicates.assignableTo;
    import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.name;
    import static com.tngtech.archunit.core.domain.properties.HasOwner.Predicates.With.owner;
    import static com.tngtech.archunit.core.domain.properties.HasParameterTypes.Predicates.rawParameterTypes;
    import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 2021-12-02
      • 1970-01-01
      • 2018-04-12
      • 1970-01-01
      • 2013-10-18
      • 1970-01-01
      相关资源
      最近更新 更多