我正在开发一个Java小库,它可以从压缩的图像数据源(例如PNG文件)中读取图像并对其进行解码,返回Image
个对象。 Image
类具有名为Image.createImage(...)
的各种函数,可以根据指定的参数创建图像。
我已经向库API添加了几个公共Image.createImage(...)
方法,每种方法对应一种数据源类型:Image.createImage(Path)
,Image.createImage(InputStream)
,Image.createImage(String)
,Image.createImage(byte[])
,...,让用户轻松从各种数据源获取Image
,而无需输入大量代码。
然而,这意味着每个方法都重复使用Javadoc并且API变得更大,所以有点难以学习,即使辅助方法本身非常简单(例如Image.createImage(byte[])
只是return Image.createImage(new ByteArrayInputStream(array));
) ,所以我决定重新设计我的库API设计。
我想到了三种不同的方法来重新设计我的Image
API:
Image.createImage(InputStream)
,让用户自己从他的数据源创建一个输入流(也许包括Javadoc中的一些示例代码,例如“解码存储在文件中的图像,你可以使用Files.newInputStream(Paths.get(...))
。 ..“)Image.createImage(ByteBuffer)
,Image.createImage(Path)
,...每个方法都重复使用Javadoc (这实际上是当前情况) DataSource
类,可以从其中一种数据源类型构建(例如new DataSource(Path)
,...),并使用单个图像解码方法获取DataSource
对象,例如Image.createImage(DataSource)
我想知道哪种设计是最好的设计。
InputStream
。我很想选择这种设计。Image
和{{1}的Javadoc,那么用户获得Image
会变得太复杂然后找到如何创建一个DataSource
,我个人也发现它非常“重量级”-ish(让我想起非常大的框架,包含大量的类和包,而我喜欢让我的项目保持小简洁)。如果您要使用此库,您更喜欢哪种设计?第一个设计是最好的吗?
答案 0 :(得分:3)
约书亚布洛赫说,
API应尽可能小但不小“
•如有疑问,请将其删除──功能,类别,方法, 参数等──您可以随时添加,但永远不能删除
从这个链接看第14页
http://www.cs.bc.edu/~muller/teaching/cs102/s06/lib/pdf/api-design
答案 1 :(得分:3)
你的实际设计似乎很好。
为每种数据源类型提供(辅助)方法,例如 Image.createImage(ByteBuffer),Image.createImage(Path),... with 每个方法都重复使用Javadoc(这实际上是 现状)
更多的API使用起来更简单,更好
提供方法重载通常是一个优点,因为客户端不需要记住很多东西来应用处理/创建具有不同风格的对象。
他/她必须只记住the
方法。
查看java.io
包中的JDK类:FileInputStream
,FileOutputStream
。
这些是以这种方式设计的:
public FileInputStream(String name)抛出FileNotFoundException {
public FileInputStream(File file)抛出FileNotFoundException {
public FileInputStream(FileDescriptor fdObj){
当然,如果您定义了许多重载方法,例如8个或更多,则情况会有所不同 您的API可能变得更难阅读,使用并且可能容易出错 对你来说似乎不是这样。
使用javadoc来记录每种方法应该不是问题
客户不必刻意学习。
此外,它们的javadoc应该非常相似:
Image.createImage(Path)
Image.createImage(InputStream)
,Image.createImage(String)
, - Image.createImage(byte[])
这些方法的javadoc可能总是引用@see
或{@link}
javadoc注释的常用方法。
最后,由于每种方法都使用不同的类型作为参数,我们可以轻松猜出。
之间的差异答案 2 :(得分:3)
你已经得到了很好的答案,但是关于javadoc:只需使用链接到其他方法,使用:
{@link package.class#member label}
含义:如果你真的有一组相关的方法做“相同”需要不同的参数 - 那么不仅避免代码重复,而且避免文档重复是一种好的做法。所以:
/**
* This is the extensively documented "anchor" method ...
* @param String path to image as String ...
*/
public void createImage(String path) { ...
/**
* See {@link ...
* and some additional information ...
答案 3 :(得分:1)
从设计的角度来看,它实际上取决于您对图书馆的目标是什么以及您想要扩展它的距离。
第一个选项创建了一个非常轻量级的库,可以在多种场合使用,但是向用户提供了许多你知道需要完成的工作,还有一些你并不知道的工作。它很容易编写,并没有限制你使用它的方式,但它不是那么容易使用,如果你只是想要使用大量的代码,它可能真的不值得
如果你保持原样,你将保持一个巨大的(从外面)库非常容易使用。但是,正如其他人提到的那样,可能难以保留。
在我看来,第三种情况是面向对象的。您抽象出DataSource
的概念,您基本上可以创建类的层次结构,每种类型的源都需要一个。易于扩展,易于使用(采用适当的工厂方法)。要创建一个可维护的库,我会使用这种方法。
另一方面,如果你唯一担心的是重复JavaDoc描述,你可以随时使用{@link} tag to write it once and refer it everywhere else
答案 4 :(得分:-1)
问题似乎与创建有关。考虑支持多个数据源的Image
。胶水代码在工厂中,因此只有一个Image
构造函数。
也许将npm install ngx-bootstrap bootstrap-sass
的构造函数设为私有,以便用户需要使用工厂。