[WELC] 21. I’m Changing the Same Code All Over the Place

488 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
488
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

[WELC] 21. I’m Changing the Same Code All Over the Place

  1. 1. Chapter 21. I’m Changing the Same Code All Over the Place ohyecloudy(http://dodoubt.tistory.com)
  2. 2. 많은 중복이 있는 Class AddEmployeeCmd LoginCommand name : String - userName : String address : String - passwd : String city : String - header : byte[] stat : String - commandChar : byte[] yearlySalary : String - footer : byte[] - header : byte[] - SIZE_LENGTH : int - commandChar : byte[] - CMD_BYTE_LENGTH : int - footer : byte[] - SIZE_LENGTH : int - CMD_BYTE_LENGTH : int - getSize() : int - getSize() : int + AddEmployeeCmd(…) + LoginCommand(…) + write(OutputStream) + write(OutputStream)
  3. 3. outputStream.write(userName.getBytes()); outputStream.write(0x00); outputStream.write(passwd.getBytes()); outputStream.write(0x00); void writeField(OutputStream outputStream, String field) { outputStream.write(field.getBytes()); outputStream.write(0x00); }
  4. 4. public class AddEmployeeCmd { … public void write(OutputStream outputStream) throws Exception { outputStream.write(header); outputStream.write(getSize()); outputStream.write(commandChar); writeField(outputstream, name); writeField(outputstream, address); writeField(outputstream, city); writeField(outputstream, state); writeField(outputstream, yearlySalary); outputStream.write(footer); } 중복 } public class LoginCommand { … public void write(OutputStream outputStream) throws Exception { outputStream.write(header); outputStream.write(getSize()); outputStream.write(commandChar); writeField(outputstream, username); writeField(outputstream, passwd); outputStream.write(footer); } }
  5. 5. public class LoginCommand { … private void writeBody(OutputStream outputStream) throws Exception { writeField(outputstream, username); writeField(outputstream, passwd); } … } public class AddEmployeeCmd { … private void writeBody(OutputStream outputStream) throws Exception { writeField(outputstream, name); writeField(outputstream, address); writeField(outputstream, city); writeField(outputstream, state); writeField(outputstream, yearlySalary); } … }
  6. 6. public class AddEmployeeCmd extends Command { String name, address, city, state, yearlySalary; private static final byte[] commandChar = {0x02}; private static final byte[] header = {(byte)0xde, (byte)0xad}; private static final byte[] footer = {(byte)0xbe, (byte)0xef}; private static final int SIZE_LENGTH = 1; private static final int CMD_BYTE_LENGTH = 1; … } public class LoginCommand extends Command 중복 { private String userName, passwd; private static final byte[] commandChar = {0x01}; private static final byte[] header = {(byte)0xde, (byte)0xad}; private static final byte[] footer = {(byte)0xbe, (byte)0xef}; private static final int SIZE_LENGTH = 1; private static final int CMD_BYTE_LENGTH = 1; … }
  7. 7. public class Command { protected static final byte[] header = {(byte)0xde, (byte)0xad}; protected static final byte[] footer = {(byte)0xbe, (byte)0xef}; protected static final int SIZE_LENGTH = 1; protected static final int CMD_BYTE_LENGTH = 1; protected abstract char[] getCommandChar(); … } public class LoginCommand extends Command { protected char[] getCommandChar() { return new char[] {0x01}; } } public class AddEmployeeCmd extends Command { protected char[] getCommandChar() { return new char[] {0x02}; } }
  8. 8. 현재 Command Class public class Command { protected static final byte[] header = {(byte)0xde, (byte)0xad}; protected static final byte[] footer = {(byte)0xbe, (byte)0xef}; protected static final int SIZE_LENGTH = 1; protected static final int CMD_BYTE_LENGTH = 1; protected abstract char[] getCommandChar(); protected abstract void writeBody(OutputStream outputStream); protected void writeField(OutputStream outputStream, String field) { outputStream.write(field.getBytes()); outputStream.write(0x00); } public void write(OutputStream outputStream) throws Exception { outputStream.write(header); outputStream.write(getSize()); outputStream.write(getCommandChar()); writeBody(outputStream); outputStream.write(footer); } … }
  9. 9. public class LoginCommand extends Command { private int getSize() { return header.length + SIZE_LENGTH + CMD_BYTE_LENGTH + footer.length + userName.getBytes().length + 1 + passwd.getBytes().length + 1; } } 중복 public class AddEmployeeCmd extends Command { private int getSize() { return header.length + SIZE_LENGTH + CMD_BYTE_LENGTH + footer.length + name.getBytes() + 1 + address.getBytes() + 1 + city.getBytes() + 1 + state.getBytes() + 1 + yearlySalary.getBytes() + 1; } }
  10. 10. public class Command { private int getSize() { return header.length + SIZE_LENGTH + CMD_BYTE_LENGTH + footer.length + getBodySize(); } } public class LoginCommand extends Command { protected int getBodySize() { return userName.getBytes().length + 1 + passwd.getBytes().length + 1; } }
  11. 11. public class Command { protected int getFieldSize(String field) { return field.getBytes().length + 1; } } public class LoginCommand extends Command { protected int getBodySize() { return getFieldSize(userName) + getFieldSize(passwd); } }
  12. 12. public class Command { protected List fields = new ArrayList(); private int getBodySize() { int result = 0; for (Iterator it = fields.iterator(); it.hasNext(); ) { String field = (String)it.next(); result += getFieldSize(field) } return result; } private writeBody(OutputStream outputStream) { for (Iterator it = fields.iterator(); it.hasNext(); ) { String field = (String)it.next(); writeField(outputStream, field); } } } public class LoginCommand extends Command { public LoginCommand(String name, String password) { fields.add(name); fields.add(password); } }
  13. 13. before AddEmployeeCmd LoginCommand name : String - userName : String address : String - passwd : String city : String - header : byte[] stat : String - commandChar : byte[] yearlySalary : String - footer : byte[] - header : byte[] - SIZE_LENGTH : int - commandChar : byte[] - CMD_BYTE_LENGTH : int - footer : byte[] - SIZE_LENGTH : int - CMD_BYTE_LENGTH : int - getSize() : int - getSize() : int + AddEmployeeCmd(…) + LoginCommand(…) + write(OutputStream) + write(OutputStream)
  14. 14. After Command - header : byte[] - footer : byte[] - SIZE_LENGTH : int - CMD_BYTE_LENGTH : int - fields : List # getCommandChar() : byte[] {abstract} - writeField(OutputStream, String) - writeBody(OutputStream) - getFieldSize(String) : int - getBodySize() : int - getSize() : int + write(OutputStream) AddEmployeeCmd LoginCommand # getCommandChar() : byte[] # getCommandChar() : byte[] + AddEmployeeCommand(…) + LoginCommand(…)
  15. 15. Abbreviations(생략) • 가독성이 안 좋다. • 이해할 수 있게 통일해서 쓰면 오케이 • 비슷하게 섞어서 쓰면 괴롭다. – ___Mgr, ___Mngr • Rename – AddEmployeeCmd -> AddEmployeeCommand
  16. 16. Orthogonality(직교성) • == independence • 동작을 변경할 때 정확히 한 곳만 고치면 오케이 – 중복 코드 없다 • 예제에서 terminator로 0x00을 쓰고 있는 데, 0x01로 변경하려면 몇 군데를 고쳐야 하나?
  17. 17. Duplication removal • 디자인을 유연하게 만든다. – 기능 추가 및 변경이 쉽다. • 지나침은 금물

×