API design

S

Stefan Ram

I assume that one wants to design an API with the option to
open a FileOutputStream for /append mode/. There are several
possibilities, and one can compare their readability,
extendability (fitness for later API extensions), usability
and other software quality factors. (feel free to comment):

==

new FileOutputStream( "path", "a" );

==

new FileOutputStream( "path", "append" );

==

new FileOutputStream( "path", true );

==

new FileOutputStream( "path", FileOutputStream.APPEND_MODE );

==

new FileOutputStream( "path", FileAccessMode.APPEND_MODE );

==

new FileOutputStream( path, new AppendMode() );

/* here, »AppendMode« might be a subtype of another type »FileAccessMode« */

==

new FileOutputStream( path, new FileAccessMode( "append" ));

==

new AppendFileOutputStream( path );

/* here, »AppendFileOutputStream« might be a subtype of »FileOutputStream« */

==

Possibly, I have missed others possibilities to design this.
 
K

Knute Johnson

Stefan said:
I assume that one wants to design an API with the option to
open a FileOutputStream for /append mode/. There are several
possibilities, and one can compare their readability,
extendability (fitness for later API extensions), usability
and other software quality factors. (feel free to comment):

==

new FileOutputStream( "path", "a" );

==

new FileOutputStream( "path", "append" );

==

new FileOutputStream( "path", true );

==

new FileOutputStream( "path", FileOutputStream.APPEND_MODE );

==

new FileOutputStream( "path", FileAccessMode.APPEND_MODE );

==

new FileOutputStream( path, new AppendMode() );

/* here, »AppendMode« might be a subtype of another type »FileAccessMode« */

==

new FileOutputStream( path, new FileAccessMode( "append" ));

==

new AppendFileOutputStream( path );

/* here, »AppendFileOutputStream« might be a subtype of »FileOutputStream« */

==

Possibly, I have missed others possibilities to design this.

I like FileAppendStream but what is the point of this? FileOutputStream
already has a constructor that will append.
 
M

markspace

Stefan said:
new FileOutputStream( "path", FileOutputStream.APPEND_MODE );


Something like this, where APPEND_MODE is a reference, not an integer.


public class FileOutputStream2 {

public static enum Mode { APPEND, READ, WRITE, READ_WRITE }

// ....

}


You can get rid if the unwieldy naming syntax with a static import:


import static package.FileOutputStream2.Mode.*;


will allow you to use APPEND, READ, etc. with no other name qualifiers.
You can also omit the * and use just the eunm name as a qualifier:


import static package.FileOutputStream2.Mode;
...
new FileOutputStream2( "path", Mode.APPEND );
...
 
D

Daniel Pitts

Stefan said:
I assume that one wants to design an API with the option to
open a FileOutputStream for /append mode/. There are several
possibilities, and one can compare their readability,
extendability (fitness for later API extensions), usability
and other software quality factors. (feel free to comment):

==

new FileOutputStream( "path", "a" ); Meh.

==

new FileOutputStream( "path", "append" );
Eh, verbose is good, string is bad.
==

new FileOutputStream( "path", true ); Ew, no.

==

new FileOutputStream( "path", FileOutputStream.APPEND_MODE );
Sure, if that is an enum value.
==

new FileOutputStream( "path", FileAccessMode.APPEND_MODE );
Sure, if that is an enum value.
==

new FileOutputStream( path, new AppendMode() );

/* here, »AppendMode« might be a subtype of another type »FileAccessMode« */
No, because a user would then be able to create a new FileAccessMode
class that doesn't make sense to FileOutputStream.
==

new FileOutputStream( path, new FileAccessMode( "append" ));
Only slightly better than (path, "append").
==

new AppendFileOutputStream( path ); No.

/* here, »AppendFileOutputStream« might be a subtype of »FileOutputStream« */

==

Possibly, I have missed others possibilities to design this.

Another possibility: FileOutputStream.openForAppend(path);
Although, I still would prefer FileAccessMode.APPEND_MODE over all the
others for this particular case.
 
R

Roedy Green

and other software quality factors. (feel free to comment):

The original form was boolean, so that would be your choice for
backward compatibility.

Using strings has the problem of typos not being detected, or only
being detected at run time.

Enums are the safest.
--
Roedy Green Canadian Mind Products
http://mindprod.com

If everyone lived the way people do in Vancouver, we would need three more entire planets to support us.
~ Guy Dauncey
 
A

Arne Vajhøj

Stefan said:
I assume that one wants to design an API with the option to
open a FileOutputStream for /append mode/. There are several
possibilities, and one can compare their readability,
extendability (fitness for later API extensions), usability
and other software quality factors. (feel free to comment):

==

new FileOutputStream( "path", "a" );

==

new FileOutputStream( "path", "append" );

==

new FileOutputStream( "path", true );

==

new FileOutputStream( "path", FileOutputStream.APPEND_MODE );

==

new FileOutputStream( "path", FileAccessMode.APPEND_MODE );

==

new FileOutputStream( path, new AppendMode() );

/* here, »AppendMode« might be a subtype of another type »FileAccessMode« */

==

new FileOutputStream( path, new FileAccessMode( "append" ));

==

new AppendFileOutputStream( path );

/* here, »AppendFileOutputStream« might be a subtype of »FileOutputStream« */

==

Possibly, I have missed others possibilities to design this.

I would prefer:

new FileOutputStream( "path", FileAccessMode.APPEND_MODE )

Nice standard way of doing things.

Type safe (assuming it is an enum).

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top