如何利用 Enums 的简单性设计一个易于扩展的 API? [英] How to design an easily-extensible API with the simplicity of Enums?

查看:23
本文介绍了如何利用 Enums 的简单性设计一个易于扩展的 API?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

抱歉标题模糊;想不出如何更清楚地表达出来.以下是问题的重点:

Sorry for the vague title; couldn't think of how to word it more clearly. Here are the highlights of the questions:

亮点

  • 询问有关 ExifTool for Java 的 API 设计问题 图书馆.
  • 以下是当前 API 外观的示例.
  • 作为用户,该 API 使用起来非常简单,因为您只需为想要返回的图像元数据传入 Enum.
  • 作为 DEV,API 有点糟糕,因为您无法轻松地使用更多 Enum 类型扩展基类以支持库中可能不直接支持的其他元数据.
  • 简单地预先定义和支持所有元数据"是非平凡.
  • Asking an API design question about the ExifTool for Java library.
  • Here is an example of what the current API looks like.
  • As a USER, the API is super-simple to use because you just pass in Enums for the image metadata you want back.
  • As a DEV, the API somewhat sucks because you cannot easily extend the base class with more Enum types to support additional metadata that may not be supported directly in the lib.
  • Simply pre-defining and supporting "all the metadata" is non-trivial.

问题

鉴于这些设置信息,我想要找到一种方法来预定义人们通常希望从图像中获得的 30 或 40 个最常见的元数据标志;现在一切都定义为枚举,但该类不能以这种方式扩展.

Given that setup information, what I am after is trying to find a way to pre-define the 30 or 40 most common metadata flags that people typically want from their images; right now everything is defined as an Enum, but the class is not extensible this way.

如果我走Class-per-Metadata-flag"路线,可扩展性会很简单,但开箱即用的 API 会不太友好.

If I go the "Class-per-Metadata-flag" route, the extensibility will be simple, but the API will be a lot less friendly to use out of the box.

如果闭包提供了一个非常漂亮和简单的解决方案,我将考虑将此库的 v2.0 设为 Java 8+,否则我显然更愿意让它与更多系统(Java 6/7)兼容而不是更少.

I will consider making v2.0 of this library Java 8+ if closures offer a really beautiful and simple solution, but otherwise I'd obviously prefer to keep it compatible with more systems (Java 6/7) than less.

总结

我对该库的目标是易于使用和扩展"——我觉得我已经在 1.x 版本中确定了易于使用"的方面,但该库不容易扩展,我想纠正在 2.x 系列中.

My goals for the library are "simple to use and extend" - I feel I have nailed the "simple to use" aspect with the 1.x release, but the library is not easily extensible and I'd like to correct that in the 2.x series.

我在 2.x 版本上等待了一年多的时间来等待灵感的出现,但它一直没有出现;我希望有人能发现我的错误,我可以以一种非常优雅的方式向前推进 lib.

I have been sitting on the 2.x release for over a year waiting for inspiration to strike and it has eluded me; I am hoping someone can spot my mistake and I can move the lib forward in a really elegant way.

谢谢你们的时间!

推荐答案

Java 枚举不可扩展,但它们可以实现接口.

Java enums are not extensible, but they can implement interfaces.

您通常可以通过定义提供者可以实现的接口和实现接口并包含用户可以直接使用的常用实例的枚举来两全其美:

You can often get the best of both worlds by defining an interface that providers can implement, and an enum that implements it and contains commonly used instances that the users will be able to use directly:

public interface Pet {
    public String talk();
}

public enum CommonPet implements Pet {
    CAT("Meow!"),
    DOG("Woof! Woof!");

    private final String cry;

    CommonPet(String cry) {
        this.cry = cry;
    }

    @Override
    public String talk() {
        return cry;
    }
}

过去接受原始枚举实例的 API 现在应该接受接口的任何实例.

The API that used to accept instances of the original enum should now take any instance of the interface.

用户可以使用相同的模式提供自己的实现:

Users can provide their own implementations using the same pattern:

public enum UncommonPet implements Pet {
    LION;

    @Override
    public String talk() {
        return "Roar!";
    }
}

最后,没有要求所有实现都应该是枚举,因此在更复杂的情况下,用户可以选择将接口实现为成熟的类:

Finally, there is no requirement that all implementations should be enums, so in more complex cases the user can choose to implement the interface as a full-fledged class:

public class Parrot implements Pet {
    private String phrase = "Pieces of eight!";

    @Override
    public String talk() {
        return phrase;
    }

    public void teach(String phrase) {
        this.phrase = phrase;
    }
}

这篇关于如何利用 Enums 的简单性设计一个易于扩展的 API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆