Skip to content

Commit

Permalink
✨ 14. 점진적인 개선 - 리팩토링 version 5 (Final) (#14)
Browse files Browse the repository at this point in the history
* 1. 사용하지 않는 usage() 제거

* 2. schema 필드 제거

* 3. argList 필드 제거 및 메서드명 변경

* 4. parsexxx() 리팩토링

* 5. cardinality() 제거

* 6. getxxx() 내부 로직을 타입별 ArgumentMarshaler로 이동

* 7. ArgumentMarshaler get() 제거

* 8. 책과 동일하게 메서드 순서 및 괄호 등 format 맞춤

* 9. ErrorCode.OK errorMessage 변경

* 10. 사용 코드 목록 14-1과 동일하게 변경
  • Loading branch information
viiviii authored May 12, 2022
1 parent 127aaea commit aac8128
Show file tree
Hide file tree
Showing 13 changed files with 257 additions and 121 deletions.
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

0 comments on commit aac8128

Please sign in to comment.