CleanCode TIL (2022.02.09)

Henry Choยท2022๋…„ 2์›” 9์ผ
0

๋…ธ๊ฐœ๋ถ

๋ชฉ๋ก ๋ณด๊ธฐ
17/31

DAY 20

๐Ÿ”–ย ์˜ค๋Š˜ ์ฝ์€ ๋ฒ”์œ„ : 10. ํด๋ž˜์Šค (172~185p)


๐Ÿค“ย ์ฑ…์—์„œ ๊ธฐ์–ตํ•˜๊ณ  ์‹ถ์€ ๋‚ด์šฉ

ํด๋ž˜์Šค ์ฒด๊ณ„

  • ์‹ ๋ฌธ ๊ธฐ์‚ฌ์ฒ˜๋Ÿผ ์ฝํžˆ๋Š” ์ˆœ์ฐจ์  ์ถ”์ƒํ™” ๋‹จ๊ณ„
  1. public static variable
  2. private static variable
  3. private instance variable
  4. public instance variable ( ๊ฑฐ์˜ ์“ฐ์ง€ ์•Š์Œ )
  5. public function
  6. private function

์บก์Šํ™”

  • ๋ณ€์ˆ˜๋‚˜ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋ฅผ protected๋กœ ์„ ์–ธํ•ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์— ์ ‘๊ทผ ํ—ˆ์šฉํ•ด๋„๋œ๋‹ค
  • ํ•˜์ง€๋งŒ ๊ทธ ์ „์— ๋น„๊ณต๊ฐœ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ๋ฐฉ๋ฒ•์„ ์ตœ๋Œ€ํ•œ ๊ฐ•๊ตฌ
  • ์บก์Šํ™”๋ฅผ ํ•ด์ œํ•˜๋Š” ๊ฒฐ์ •์€ ์ตœํ›„์˜ ์ˆ˜๋‹จ

ํด๋ž˜์Šค๋Š” ์ž‘์•„์•ผ ํ•œ๋‹ค!

  • ์–ผ๋งˆ๋‚˜?: ์ฑ…์ž„์˜ ๊ฐœ์ˆ˜
  • ํด๋ž˜์Šค ์ด๋ฆ„์€ ํ•ด๋‹น ํด๋ž˜์Šค ์ฑ…์ž„์„ ๊ธฐ์ˆ ํ•ด์•ผ ํ•œ๋‹ค
  • ์ž‘๋ช…์ด ํด๋ž˜์Šค ํฌ๊ธฐ๋ฅผ ์ค„์ด๋Š” ์ฒซ ๋ฒˆ์งธ ๊ด€๋ฌธ
  • ๊ฐ„๊ฒฐํ•œ ์ด๋ฆ„์ด ๋– ์˜ค๋ฅด์ง€ ์•Š๋Š”๋‹ค โ†’ ํด๋ž˜์Šค ํฌ๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ํฌ๊ธฐ ๋•Œ๋ฌธ
  • ํด๋ž˜์Šค ์„ค๋ช…์€ if, and, or, but ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  25๋‹จ์–ด ๋‚ด์™ธ๋กœ ๊ธฐ์ˆ ํ•ด์•ผํ•จ

๋‹จ์ผ ์ฑ…์ž„ ์›์น™(SRP)

  • ํด๋ž˜์Šค๋‚˜ ๋ชจ๋“ˆ์„ ๋ณ€๊ฒฝํ•  ์ด์œ ๊ฐ€ ๋‹จ ํ•˜๋‚˜๋ฟ์ด์–ด์•ผ ํ•œ๋‹ค
public class SuperDashboard extends JFrame implements MetaDataUser public Component getLastFocusedComponent() {
    public void setLastFocused(Component lastFocused)
    public int getMajorVersionNumber()
    public int getMinorVersionNumber()
    public int getBuildNumber()
}

๋ฉ”์„œ๋“œ๊ฐ€ 5๊ฐœ๋ฟ์ด์ง€๋งŒ ์ฑ…์ž„์ด ํฐ SuperDashboard ๋ฅผ ๋ณ€๊ฒฝ

  1. getMajorVersion? โ†’ ๋ฒ„์ „ ์ •๋ณด๋Š” ์†Œํ”„ํŠธ์›จ์–ด ์ถœ์‹œ๋•Œ๋งˆ๋‹ค ๋‹ฌ๋ผ์ง„๋‹ค
  2. ์Šค์œ™ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค ๋ฒ„์ „ ๋ฒˆํ˜ธ๊ฐ€ ๋‹ฌ๋ผ์ง„๋‹ค?
  • ๋ฒ„์ „ ์ •๋ณด๋ฅผ ๋‹ค๋ฃจ๋ฅผ ๋ฉ”์„œ๋“œ๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฉด ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์›€
    public class Version {
        public int getMajorVersionNumber()
        public int getMinorVersionNumber()
        public int getBuildNumber()
    }
  • ์‹ค๋ฌด์—์„œ๋Š” ์ž์ž˜ํ•œ ๋‹จ์ผ ์ฑ…์ž„ ํด๋ž˜์Šค๊ฐ€ ๋งŽ์•„์ง€๋ฉด ํฐ ๊ทธ๋ฆผ์„ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์›Œ ์ง„๋‹ค๊ณ  ์šฐ๋ ค
  • ์ž‘์€ ์„œ๋ž์„ ๋งŽ์ด ๋‘๊ณ  ๊ธฐ๋Šฅ๊ณผ ์ด๋ฆ„์ด ๋ช…ํ™•ํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‚˜๋ˆ ๋„ฃ๊ธฐ vs ํฐ ์„œ๋ž ๋ช‡ ๊ฐœ์— ๋•Œ๋ ค๋„ฃ๊ธฐ

์‘์ง‘๋„

  • ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ ์ˆ˜๋Š” ์ž‘์•„์•ผํ•œ๋‹ค
  • ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ๋Š” ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜ ์ด์ƒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค
  • ๋ฉ”์„œ๋“œ๊ฐ€ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•  ์ˆ˜๋ก ๋ฉ”์„œ๋“œ์™€ ํด๋ž˜์Šค์˜ ์‘์ง‘๋„๊ฐ€ ๋†’๋‹ค
  • ํ•จ์ˆ˜๋ฅผ ์ž‘๊ฒŒ, ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ชฉ๋ก์„ ์งง๊ฒŒ ์ „๋žต์„ ๋”ฐ๋ฅด๋‹ค ๋ณด๋ฉด ์ผ๋ถ€ ๋ฉ”์„œ๋“œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๊ฐ€ ๋งŽ์•„์ง โ†’ ์‘์ง‘๋„๊ฐ€ ๋†’์•„์ง€๋„๋ก ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋กœ ๋ถ„๋ฆฌ

์‘์ง‘๋„๋ฅผ ์œ ์ง€ํ•˜๋ฉด ์ž‘์€ ํด๋ž˜์Šค ์—ฌ๋Ÿฟ์ด ๋‚˜์˜จ๋‹ค

  • ํฐ ํ•จ์ˆ˜๋ฅผ ์ž‘์€ ํ•จ์ˆ˜ ์—ฌ๋Ÿฟ์œผ๋กœ ๋‚˜๋ˆ„๊ธฐ๋งŒ ํ•ด๋„ ํด๋ž˜์Šค ์ˆ˜๊ฐ€ ๋งŽ์•„์ง„๋‹ค
    1. ํ•จ์ˆ˜๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ๋กœ ์ชผ๊ฐœ๋ ค๋‹ค ๋ณด๋‹ˆ ์—ฌ๋Ÿฌ๊ฐœ ์ธ์ˆ˜๊ฐ€ ์ค‘๋ณต ํ•„์š”
    2. ํ•„์š”ํ•œ ๋ณ€์ˆ˜๋ฅผ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋กœ ์Šน๊ฒฉํ•˜๋ฉด ํ•จ์ˆ˜๋Š” ์ธ์ˆ˜๊ฐ€ ํ•„์š” ์—†๋‹ค
    3. ํ•จ์ˆ˜ ์ชผ๊ฐœ๊ธฐ ์‰ฌ์›Œ์ง
    4. ์‘์ง‘๋„๊ฐ€ ๋‚ฎ์•„์ง?
    5. ํด๋ž˜์Šค ๋ถ„๋ฆฌ!
package literatePrimes;
public class PrintPrimes {
    public static void main(String[] args) {
        final int M = 1000;
        final int RR = 50;
        final int CC = 4;
        final int WW = 10;
        final int ORDMAX = 30;
        int P[] = new int[M + 1];
        int PAGENUMBER;
        int PAGEOFFSET;
        int ROWOFFSET;
        int C;
        int J;
        int K;
        boolean JPRIME;
        int ORD;
        int SQUARE;
        int N;
        int MULT[] = new int[ORDMAX + 1];
        J = 1;
        K = 1;
        P[1] = 2;
        ORD = 2;
        SQUARE = 9;
        while (K < M) {
            do {
                J = J + 2;
                if (J == SQUARE) {
                    ORD = ORD + 1;
                    SQUARE = P[ORD] * P[ORD];
                    MULT[ORD - 1] = J;
                }
                N = 2;
                JPRIME = true;
                while (N < ORD && JPRIME) {
                    while (MULT[N] < J)
                        MULT[N] = MULT[N] + P[N] + P[N];
                    if (MULT[N] == J) JPRIME = false;
                    N = N + 1;
                }
            } while (!JPRIME);
            K = K + 1;
            P[K] = J;
        } {
            PAGENUMBER = 1;
            PAGEOFFSET = 1;
            while (PAGEOFFSET <= M) {
                System.out.println("The First " + M +
                    " Prime Numbers --- Page " + PAGENUMBER);
                System.out.println("");
                for (ROWOFFSET = PAGEOFFSET; ROWOFFSET < PAGEOFFSET + RR; ROWOFFSET++) {
                    for (C = 0; C < CC; C++)
                        if (ROWOFFSET + C * RR <= M)
                            System.out.format("%10d", P[ROWOFFSET + C * RR]);
                    System.out.println("");
                }
                System.out.println("\f");
                PAGENUMBER = PAGENUMBER + 1;
                PAGEOFFSET = PAGEOFFSET + RR * CC;
            }
        }
    }
}
  • Refactoring๊ฒฐ๊ณผ
// PrimePrinter.java
package literatePrimes;
public class PrimePrinter {
    public static void main(String[] args) {
        final int NUMBER_OF_PRIMES = 1000;
        int[] primes = PrimeGenerator.generate(NUMBER_OF_PRIMES);
        final int ROWS_PER_PAGE = 50;
        final int COLUMNS_PER_PAGE = 4;
        RowColumnPagePrinter tablePrinter =
            new RowColumnPagePrinter(ROWS_PER_PAGE, COLUMNS_PER_PAGE,
                "The First " + NUMBER_OF_PRIMES + " Prime Numbers");
        tablePrinter.print(primes);
    }
}
// RowColumnPagePrinter.java
package literatePrimes;
import java.io.PrintStream;
public class RowColumnPagePrinter {
    private int rowsPerPage;
    private int columnsPerPage;
    private int numbersPerPage;
    private String pageHeader;
    private PrintStream printStream;
    public RowColumnPagePrinter(int rowsPerPage, int columnsPerPage,
        String pageHeader) {
        this.rowsPerPage = rowsPerPage;
        this.columnsPerPage = columnsPerPage;
        this.pageHeader = pageHeader;
        numbersPerPage = rowsPerPage * columnsPerPage;
        printStream = System.out;
    }
    public void print(int data[]) {
        int pageNumber = 1;
        for (int firstIndexOnPage = 0; firstIndexOnPage < data.length; firstIndexOnPage += numbersPerPage) {
            int lastIndexOnPage =
                Math.min(firstIndexOnPage + numbersPerPage - 1, data.length - 1);
            printPageHeader(pageHeader, pageNumber);
            printPage(firstIndexOnPage, lastIndexOnPage, data);
            printStream.println("\f");
            pageNumber++;
        }
    }
    private void printPage(int firstIndexOnPage, int lastIndexOnPage,
        int[] data) {
        int firstIndexOfLastRowOnPage =
            firstIndexOnPage + rowsPerPage - 1;
        for (int firstIndexInRow = firstIndexOnPage; firstIndexInRow <= firstIndexOfLastRowOnPage; firstIndexInRow++) {
            printRow(firstIndexInRow, lastIndexOnPage, data);
            printStream.println("");
        }
    }
    private void printRow(int firstIndexInRow, int lastIndexOnPage,
        int[] data) {
        for (int column = 0; column < columnsPerPage; column++) {
            int index = firstIndexInRow + column * rowsPerPage;
            if (index <= lastIndexOnPage) printStream.format("%10d", data[index]);
        }
    }
    private void printPageHeader(String pageHeader, int pageNumber) {
        printStream.println(pageHeader + " --- Page " + pageNumber);
        printStream.println("");
    }
    public void setOutput(PrintStream printStream) {
        this.printStream = printStream;
    }
}
// PrimeGenerator.java
package literatePrimes;
import java.util.ArrayList;
public class PrimeGenerator {
    private static int[] primes;
    private static ArrayList < Integer > multiplesOfPrimeFactors;
    protected static int[] generate(int n) {
        primes = new int[n];
        multiplesOfPrimeFactors = new ArrayList < Integer > ();
        set2AsFirstPrime();
        checkOddNumbersForSubsequentPrimes();
        return primes;
    }
    private static void set2AsFirstPrime() {
        primes[0] = 2;
        multiplesOfPrimeFactors.add(2);
    }
    private static void checkOddNumbersForSubsequentPrimes() {
        int primeIndex = 1;
        for (int candidate = 3; primeIndex < primes.length; candidate += 2) {
            if (isPrime(candidate)) primes[primeIndex++] = candidate;
        }
    }
    private static boolean isPrime(int candidate) {
        if (isLeastRelevantMultipleOfNextLargerPrimeFactor(candidate)) {
            multiplesOfPrimeFactors.add(candidate);
            return false;
        }
        return isNotMultipleOfAnyPreviousPrimeFactor(candidate);
    }
    private static boolean isLeastRelevantMultipleOfNextLargerPrimeFactor(int candidate) {
        int nextLargerPrimeFactor = primes[multiplesOfPrimeFactors.size()];
        int leastRelevantMultiple = nextLargerPrimeFactor * nextLargerPrimeFactor;
        return candidate == leastRelevantMultiple;
    }
    private static boolean isNotMultipleOfAnyPreviousPrimeFactor(int candidate) {
        for (int n = 1; n < multiplesOfPrimeFactors.size(); n++) {
            if (isMultipleOfNthPrimeFactor(candidate, n))
                return false;
        }
        return true;
    }
    private static boolean isMultipleOfNthPrimeFactor(int candidate, int n) {
        return
        candidate == smallestOddNthMultipleNotLessThanCandidate(candidate, n);
    }
    private static int
    smallestOddNthMultipleNotLessThanCandidate(int candidate, int n) {
        int multiple = multiplesOfPrimeFactors.get(n);
        while (multiple < candidate)
            multiple += 2 * primes[n];
        multiplesOfPrimeFactors.set(n, multiple);
        return multiple;
    }
}

๐Ÿค”ย ๋– ์˜ค๋ฅด๋Š” ์ƒ๊ฐ

  • ์‹ค์ƒํ™œ์—์„œ๋„ ์ •๋ฆฌ๋ฅผ ์ž˜ ๋ชปํ•˜๋Š” ํŽธ์ธ๋ฐ ๊ทธ๋ž˜์„œ ๋‚ด๊ฐ€ ํด๋ž˜์Šค ์‚ฌ์šฉ/๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์› ๋‚˜๋ณด๋‹ค
  • ๊ตณ์ด ์ž๋ฐ”๊ฐ€ ์•„๋‹ˆ์–ด๋„ ์˜คํ”ˆ์†Œ์Šค ๋ ˆํฌ๋“ค์„ ์„ ์ •ํ•˜์—ฌ ์ฑ…์˜ ์›์น™๋Œ€๋กœ ํด๋ž˜์Šค ๋ถ„๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•ด๋ณด์ž

๐Ÿ”Žย ์งˆ๋ฌธ

๐Ÿ“ย ์†Œ๊ฐ 3์ค„ ์š”์•ฝ

  • ํด๋ž˜์Šค ์ฑ…์ž„์˜ ๊ฐœ์ˆ˜๋Š” ์ž‘์•„์•ผ ํ•œ๋‹ค โ†’ ๊ฐ„๊ฒฐํ•œ 25๋‹จ์–ด ๋‚ด์™ธ
  • ์ž‘์€ ์„œ๋ž์„ ๋งŽ์ด ๋‘๊ณ  ๊ธฐ๋Šฅ๊ณผ ์ด๋ฆ„์ด ๋ช…ํ™•ํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‚˜๋ˆ ๋„ฃ๊ธฐ
  • ํด๋ž˜์Šค๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ์‘์ง‘๋„๋ฅผ ๋†’์—ฌ๋ผ
profile
Full stack tech visionary

0๊ฐœ์˜ ๋Œ“๊ธ€