๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

์ฑ…/CleanCode

โœจ Clean Code 6์žฅ: ๊ฐ์ฒด์™€ ์ž๋ฃŒ๊ตฌ์กฐ

๐Ÿ“Œ ์ž๋ฃŒ ์ถ”์ƒํ™”

์•„๋ž˜ ๋‘ ์ฝ”๋“œ๋Š” 2์ฐจ์› ์ ์„ ํ‘œํ˜„ํ–ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ฝ”๋“œ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ž๋ฃŒ ๊ตฌ์กฐ๋ฅผ ๋ช…๋ฐฑํ•˜๊ฒŒ ํ‘œํ˜„ํ•œ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ฝ”๋“œ๋Š” ๋ณ€์ˆ˜๋ฅผ private๋กœ ์„ ์–ธํ•˜๋”๋ผ๋„ ๊ฐ’๋งˆ๋‹ค get/set ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•œ๋‹ค๋ฉด ๊ตฌํ˜„์„ ์™ธ๋ถ€๋กœ ๋…ธ์ถœ์‹œํ‚ค๋Š” ๊ฒƒ์€ ๋งˆ์ฐฌ๊ฐ€์ง€๋‹ค. ๋”ฐ๋ผ์„œ ์ถ”์ƒ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌํ˜„์„ ๋ชจ๋ฅธ ์ฑ„ ์ž๋ฃŒ์˜ ํ•ต์‹ฌ์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ์ง„์ •ํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๋Š” ํด๋ž˜์Šค๋ฅผ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰ ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ์ฒด์˜ ์ž๋ฃŒ๋ฅผ ํ‘œํ˜„ํ•  ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์„ ์‹ ์ค‘ํ•˜๊ฒŒ ๊ณ ๋ฏผํ•ด์•ผ ํ•œ๋‹ค. ์ƒ๊ฐ ์—†์ด get/set ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

public class Point {
  public double x;
  public double y;
}
public interface Point {
    double getX();
    double getY();
    void setCartesian(double x, double y);
    double getR();
    double getTheta();
    void setPolar(double r, double theta);
}

๐Ÿ“Œ ์ž๋ฃŒ/๊ฐ์ฒด ๋น„๋Œ€์นญ

  • ๊ฐ์ฒด๋Š” ์ถ”์ƒํ™” ๋’ค๋กœ ์ž๋ฃŒ๋ฅผ ์ˆจ๊ธด ์ฑ„ ์ž๋ฃŒ๋ฅผ ๋‹ค๋ฃจ๋Š” ํ•จ์ˆ˜๋งŒ ๊ณต๊ฐœํ•œ๋‹ค.
  • ์ž๋ฃŒ ๊ตฌ์กฐ๋Š” ์ž๋ฃŒ ๊ทธ๋Œ€๋กœ ๊ณต๊ฐœํ•˜์—ฌ ๋ณ„๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.
  • ๊ฐ์ฒด ์ง€ํ–ฅ ์ฝ”๋“œ์—์„œ ์–ด๋ ค์šด ๋ณ€๊ฒฝ์€ ์ ˆ์ฐจ์ ์ธ ์ฝ”๋“œ์—์„œ ์‰ฝ๊ณ , ์ ˆ์ฐจ์ ์ธ ์ฝ”๋“œ์— ์–ด๋ ค์šด ๋ณ€๊ฒฝ์€ ๊ฐ์ฒด ์ง€ํ–ฅ ์ฝ”๋“œ์—์„œ ์‰ฝ๋‹ค. 

๐Ÿ“Œ ๋””๋ฏธํ„ฐ ๋ฒ•์น™

๋””๋ฏธํ„ฐ ๋ฒ•์น™์€ ๋ชจ๋“ˆ์€ ์ž์‹ ์ด ์กฐ์ž‘ํ•˜๋Š” ๊ฐ์ฒด์˜ ์†์‚ฌ์ •์„ ๋ชฐ๋ผ์•ผ ํ•œ๋‹ค๋Š” ๋ฒ•์น™์„ ๋งํ•œ๋‹ค. ๋””๋ฏธํ„ฐ ๋ฒ•์น™์€ ํด๋ž˜์Šค C์˜ ๋ฉ”์„œ๋“œ F๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋งŒ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

  • ํด๋ž˜์Šค C
  • f๊ฐ€ ์ƒ์„ฑํ•œ ๊ฐ์ฒด
  • f๊ฐ€ ์ธ์ˆ˜๋กœ ๋„˜์–ด์˜จ ๊ฐ์ฒด
  • C ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์— ์ €์žฅ๋œ ๊ฐ์ฒด

์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋””๋ฏธํ„ฐ ๋ฒ•์น™์„ ์–ด๊ธฐ๋Š” ์ฝ”๋“œ์ด๋‹ค. ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ํ•œ ์ค„๋กœ ์ด์–ด์ง„ ๊ธฐ์ฐจ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๊ธฐ์ฐจ ์ถฉ๋Œ(train wreck)์ด๋ผ ๋ถ€๋ฅธ๋‹ค.

final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();

 

์œ„ ์ฝ”๋“œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์กฐ์žกํ•ด ๋ณด์—ฌ ์ง€์–‘ํ•ด์•ผ ํ•˜๋ฉฐ, ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜๋ˆ„๋Š” ๊ฒƒ์ด ๋‚ซ๋‹ค. ctxt๊ฐ์ฒด๊ฐ€ Options๋ฅผ ํฌํ•จํ•˜๊ณ , Options๊ฐ€ ScratchDir์„ ํฌํ•จํ•˜๋ฉฐ, ScratchDir์ด AbsolutePath๋ฅผ ํฌํ•จํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ–ˆ๋‹ค๊ณ  ํ•ด์„œ ๋””๋ฏธํ„ฐ ๋ฒ•์น™์„ ์–ด๊ธฐ์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•  ์ˆœ ์—†๋‹ค. ๊ฐ์ฒด์ธ์ง€ ์ž๋ฃŒ ๊ตฌ์กฐ์ธ์ง€์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ฐ์ฒด๋ผ๋ฉด ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ์ˆจ๊ฒจ์•ผ ํ•˜๋‹ˆ ๋””๋ฏธํ„ฐ ๋ฒ•์น™์„ ์œ„๋ฐ˜ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ž๋ฃŒ ๊ตฌ์กฐ๋ผ๋ฉด ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ๋…ธ์ถœํ•˜๋ฏ€๋กœ ๋””๋ฏธํ„ฐ ๋ฒ•์น™์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

Options opts = ctxt.getOptions();
File scratchDir = opts.getScratchDir();
final String outputDir = scratchDir.getAbsolutePath();

 

๊ทธ๋ ‡๋‹ค๋ฉด ๋งค๋ฒˆ ๋‚ด๋ถ€๋ฅผ ๋“ค์—ฌ๋ด์•ผ ํ• ๊นŒ? ์ƒ๊ฐ์ด ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์œ„ ์ฝ”๋“œ์—์„  get ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ˜ผ๋™์ด ์˜ฌ ์ˆ˜ ์žˆ์ง€๋งŒ ์ž๋ฃŒ ๊ตฌ์กฐ๋Š” ํ•จ์ˆ˜ ์—†์ด ๊ณต๊ฐœ ๋ณ€์ˆ˜๋งŒ ํฌํ•จํ•œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ๊ฐ์ฒด์ธ์ง€ ์ž๋ฃŒ ๊ตฌ์กฐ์ธ์ง€ ์‰ฝ๊ฒŒ ํŒ๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

final String outputDir = ctxt.options.scratchDir.absolutePath;

 

์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๋Š” ์ ˆ๋ฐ˜์€ ๊ฐ์ฒด์ด๊ณ , ์ ˆ๋ฐ˜์€ ์ž๋ฃŒ ๊ตฌ์กฐ์ธ ์žก์ข… ๊ตฌ์กฐ๊ฐ€ ๋˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค. ์–‘์ชฝ ๋‹จ์ ์„ ๋ชจ์•„๋†“์€ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋„ ์žˆ๊ณ , ๊ณต๊ฐœ ๋ณ€์ˆ˜๋‚˜ ๊ณต๊ฐœ get/set ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒƒ์„ ํ”ผํ•ด์•ผ ํ•œ๋‹ค. 

๐Ÿ“Œ ์ž๋ฃŒ ์ „๋‹ฌ ๊ฐ์ฒด(DTO)

๋ณ€์ˆ˜๋งŒ ๊ฐ€์ง€๊ณ  ๋ณ„๋‹ค๋ฅธ ํ•จ์ˆ˜๊ฐ€ ์—†๋Š” ํ˜•ํƒœ์˜ ๊ฐ์ฒด๋ฅผ ์ž๋ฃŒ ์ „๋‹ฌ ๊ฐ์ฒด(DTO)๋ผ๊ณ  ํ•œ๋‹ค. ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฐ›์€ ๋ฉ”์‹œ์ง€๋‚˜ ๋ ˆ์ด์–ด ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค. DTO ํ•˜๋ฉด ๊ผญ ๋”ฐ๋ผ๋‹ค๋‹ˆ๋Š” ๊ฒƒ์ด VO(Value Object)์ด๋‹ค. VO๋Š” ๋ฐ์ดํ„ฐ ๊ทธ ์ž์ฒด๋ฅผ ์˜๋ฏธํ•˜๋Š”๋ฐ ์ด ๋‘˜์˜ ์ฐจ์ด์ ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค. (์˜์ƒ)

public class Address {
    private String street;
    private String streetExtra;
    ...
    
    public Address(String street, String streetExtra, ...) {
    	this.street = street;
        this.streetExtra = streetExtra;
        ...
    }
    
    public String getStreet() {
    	return street;
    }
    
    public String getStreetExtra() {
    	return streetExtra;
    }
    
    ...
}