Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ 14. 점진적인 개선 - 리팩토링 version 5 (Final) #14

Merged
merged 10 commits into from
May 12, 2022
2 changes: 1 addition & 1 deletion src/main/java/chapter14/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static void main(String[] args) {
String directory = arg.getString('d');
executeApplication(logging, port, directory);
} catch (ArgsException e) {
System.out.printf("Argument error: %s\n", e.getMessage());
System.out.printf("Argument error: %s\n", e.errorMessage());
}
}

Expand Down
140 changes: 49 additions & 91 deletions src/main/java/chapter14/args/Args.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,148 +2,106 @@

import java.util.*;

import static chapter14.args.ArgsException.ErrorCode.*;

public class Args {
private String schema;
private Map<Character, ArgumentMarshaler> marshalers = new HashMap<>();
private Set<Character> argsFound = new HashSet<>();
private Iterator<String> currentArgument;
private List<String> argsList;
private Map<Character, ArgumentMarshaler> marshalers;
private Set<Character> argsFound;
private ListIterator<String> currentArgument;

public Args(String schema, String[] args) throws ArgsException {
this.schema = schema;
argsList = Arrays.asList(args);
parse();
}
marshalers = new HashMap<>();
argsFound = new HashSet<>();

private void parse() throws ArgsException {
parseSchema();
parseArguments();
parseSchema(schema);
parseArgumentStrings(Arrays.asList(args));
}

private boolean parseSchema() throws ArgsException {
private void parseSchema(String schema) throws ArgsException {
for (String element : schema.split(",")) {
if (element.length() > 0) {
parseSchemaElement(element.trim());
}
}
return true;
}

private void parseSchemaElement(String element) throws ArgsException {
char elementId = element.charAt(0);
String elementTail = element.substring(1);
validateSchemaElementId(elementId);
if (elementTail.length() == 0) {
if (elementTail.length() == 0)
marshalers.put(elementId, new BooleanArgumentMarshaler());
} else if (elementTail.equals("*")) {
else if (elementTail.equals("*"))
marshalers.put(elementId, new StringArgumentMarshaler());
} else if (elementTail.equals("#")) {
else if (elementTail.equals("#"))
marshalers.put(elementId, new IntegerArgumentMarshaler());
} else if (elementTail.equals("##")) {
else if (elementTail.equals("##"))
marshalers.put(elementId, new DoubleArgumentMarshaler());
} else {
throw new ArgsException(ArgsException.ErrorCode.INVALID_ARGUMENT_FORMAT,
elementId, elementTail);
}
else
throw new ArgsException(INVALID_ARGUMENT_FORMAT, elementId, elementTail);

}

private void validateSchemaElementId(char elementId) throws ArgsException {
if (!Character.isLetter(elementId)) {
throw new ArgsException(ArgsException.ErrorCode.INVALID_ARGUMENT_NAME,
elementId, null);
}
}

private void parseArguments() throws ArgsException {
for (currentArgument = argsList.iterator(); currentArgument.hasNext(); ) {
String arg = currentArgument.next();
parseArgument(arg);
throw new ArgsException(INVALID_ARGUMENT_NAME, elementId, null);
}
}

private void parseArgument(String arg) throws ArgsException {
if (arg.startsWith("-"))
parseElements(arg);
}

private void parseElements(String arg) throws ArgsException {
for (int i = 1; i < arg.length(); i++) {
parseElement(arg.charAt(i));
private void parseArgumentStrings(List<String> argsList) throws ArgsException {
for (currentArgument = argsList.listIterator(); currentArgument.hasNext(); ) {
String argString = currentArgument.next();
if (argString.startsWith("-")) {
parseArgumentCharacters(argString.substring(1));
} else {
currentArgument.previous();
break;
}
}
}

private void parseElement(char argChar) throws ArgsException {
if (setArgument(argChar))
argsFound.add(argChar);
else {
throw new ArgsException(ArgsException.ErrorCode.UNEXPECTED_ARGUMENT,
argChar, null);
private void parseArgumentCharacters(String argChars) throws ArgsException {
for (int i = 0; i < argChars.length(); i++) {
parseArgumentCharacter(argChars.charAt(i));
}
}

private boolean setArgument(char argChar) throws ArgsException {
private void parseArgumentCharacter(char argChar) throws ArgsException {
ArgumentMarshaler m = marshalers.get(argChar);
if (m == null)
return false;
try {
m.set(currentArgument);
return true;
} catch (ArgsException e) {
e.setErrorArgumentId(argChar);
throw e;
if (m == null) {
throw new ArgsException(UNEXPECTED_ARGUMENT, argChar, null);
} else {
argsFound.add(argChar);
try {
m.set(currentArgument);
} catch (ArgsException e) {
e.setErrorArgumentId(argChar);
throw e;
}
}
}

public int cardinality() {
return argsFound.size();
public boolean has(char arg) {
return argsFound.contains(arg);
}

public String usage() {
if (schema.length() > 0)
return "-[" + schema + "]";
else
return "";
public int nextArgument() {
return currentArgument.nextIndex();
}

public boolean getBoolean(char arg) {
ArgumentMarshaler am = marshalers.get(arg);
boolean b = false;
try {
b = am != null && (Boolean) am.get();
} catch (ClassCastException e) {
b = false;
}
return b;
return BooleanArgumentMarshaler.getValue(marshalers.get(arg));
}

public String getString(char arg) {
ArgumentMarshaler am = marshalers.get(arg);
try {
return am == null ? "" : (String) am.get();
} catch (ClassCastException e) {
return "";
}
return StringArgumentMarshaler.getValue(marshalers.get(arg));
}

public int getInt(char arg) {
ArgumentMarshaler am = marshalers.get(arg);
try {
return am == null ? 0 : (Integer) am.get();
} catch (ClassCastException e) {
return 0;
}
return IntegerArgumentMarshaler.getValue(marshalers.get(arg));
}

public double getDouble(char arg) {
ArgumentMarshaler am = marshalers.get(arg);
try {
return am == null ? 0.0 : (Double) am.get();
} catch (ClassCastException e) {
return 0.0;
}
}

public boolean has(char arg) {
return argsFound.contains(arg);
return DoubleArgumentMarshaler.getValue(marshalers.get(arg));
}
}
4 changes: 2 additions & 2 deletions src/main/java/chapter14/args/ArgsException.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ public void setErrorCode(ErrorCode errorCode) {
this.errorCode = errorCode;
}

public String errorMessage() throws Exception {
public String errorMessage() {
switch (errorCode) {
case OK:
throw new Exception("TILT: Should not get here.");
return "TILT: Should not get here.";
case UNEXPECTED_ARGUMENT:
return String.format("Argument(s) -%c unexpected.", errorArgumentId);
case MISSING_STRING:
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/chapter14/args/ArgumentMarshaler.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

public interface ArgumentMarshaler {
void set(Iterator<String> currentArgument) throws ArgsException;

Object get();
}
9 changes: 6 additions & 3 deletions src/main/java/chapter14/args/BooleanArgumentMarshaler.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ public void set(Iterator<String> currentArgument) throws ArgsException {
booleanValue = true;
}

@Override
public Object get() {
return booleanValue;
public static boolean getValue(ArgumentMarshaler am) {
if (am != null && am instanceof BooleanArgumentMarshaler) {
return ((BooleanArgumentMarshaler) am).booleanValue;
} else {
return false;
}
}
}
9 changes: 6 additions & 3 deletions src/main/java/chapter14/args/DoubleArgumentMarshaler.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ public void set(Iterator<String> currentArgument) throws ArgsException {
}
}

@Override
public Object get() {
return doubleValue;
public static double getValue(ArgumentMarshaler am) {
if (am != null && am instanceof DoubleArgumentMarshaler) {
return ((DoubleArgumentMarshaler) am).doubleValue;
} else {
return 0.0;
}
}
}
9 changes: 6 additions & 3 deletions src/main/java/chapter14/args/IntegerArgumentMarshaler.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ public void set(Iterator<String> currentArgument) throws ArgsException {
}
}

@Override
public Object get() {
return intValue;
public static int getValue(ArgumentMarshaler am) {
if (am != null && am instanceof IntegerArgumentMarshaler) {
return ((IntegerArgumentMarshaler) am).intValue;
} else {
return 0;
}
}
}
9 changes: 6 additions & 3 deletions src/main/java/chapter14/args/StringArgumentMarshaler.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ public void set(Iterator<String> currentArgument) throws ArgsException {
}
}

@Override
public Object get() {
return stringValue;
public static String getValue(ArgumentMarshaler am) {
if (am != null && am instanceof StringArgumentMarshaler) {
return ((StringArgumentMarshaler) am).stringValue;
} else {
return "";
}
}
}
11 changes: 1 addition & 10 deletions src/test/java/chapter14/args/ArgsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ void noSchemaAndArguments() throws Exception {
Args args = new Args(schema, arguments);

//then
assertThat(args.cardinality()).isZero();
assertThat(args.nextArgument()).isZero();
}

@DisplayName("schema가 없고 argument가 1개 있는 경우")
Expand Down Expand Up @@ -52,7 +52,6 @@ void multipleSchemasButNoArguments() throws Exception {
Args args = new Args(schema, arguments);

//then
assertThat(args.cardinality()).isZero();
assertThat(args.has('x')).isFalse();
assertThat(args.has('y')).isFalse();
assertThat(args.has('z')).isFalse();
Expand Down Expand Up @@ -108,7 +107,6 @@ void spacesInFormat() throws Exception {
Args args = new Args(schema, arguments);

//then
assertThat(args.cardinality()).isEqualTo(2);
assertThat(args.has('x')).isTrue();
assertThat(args.has('y')).isTrue();
}
Expand All @@ -124,7 +122,6 @@ void simpleBooleanPresent() throws Exception {
Args args = new Args(schema, arguments);

//then
assertThat(args.cardinality()).isOne();
assertThat(args.getBoolean('x')).isTrue();
}

Expand All @@ -139,7 +136,6 @@ void simpleBooleanMultiplePresent() throws Exception {
Args args = new Args(schema, arguments);

//then
assertThat(args.cardinality()).isEqualTo(2);
assertThat(args.has('x')).isTrue();
assertThat(args.has('y')).isTrue();
assertThat(args.has('z')).isFalse();
Expand Down Expand Up @@ -172,7 +168,6 @@ void simpleStringPresent() throws Exception {
Args args = new Args(schema, arguments);

//then
assertThat(args.cardinality()).isOne();
assertThat(args.has('x')).isTrue();
assertThat(args.getString('x')).isEqualTo("param");
}
Expand All @@ -188,7 +183,6 @@ void simpleStringMultiplePresent() throws Exception {
Args args = new Args(schema, arguments);

//then
assertThat(args.cardinality()).isEqualTo(2);
assertThat(args.has('x')).isTrue();
assertThat(args.has('y')).isTrue();
assertThat(args.has('z')).isFalse();
Expand Down Expand Up @@ -221,7 +215,6 @@ void simpleIntPresent() throws Exception {
Args args = new Args(schema, arguments);

//then
assertThat(args.cardinality()).isOne();
assertThat(args.has('x')).isTrue();
assertThat(args.getInt('x')).isEqualTo(42);
}
Expand All @@ -237,7 +230,6 @@ void simpleIntMultiplePresent() throws Exception {
Args args = new Args(schema, arguments);

//then
assertThat(args.cardinality()).isEqualTo(2);
assertThat(args.has('x')).isTrue();
assertThat(args.has('y')).isTrue();
assertThat(args.has('z')).isFalse();
Expand Down Expand Up @@ -270,7 +262,6 @@ void simpleDoublePresent() throws Exception {
Args args = new Args(schema, arguments);

//then
assertThat(args.cardinality()).isOne();
assertThat(args.has('x')).isTrue();
assertThat(args.getDouble('x')).isEqualTo(42.3);
}
Expand Down
Loading