Clean Code Function

Function

ํ•จ์ˆ˜๋Š” ํ•œ๊ฐ€์ง€์ผ๋งŒ ํ•ด์•ผํ•œ๋‹ค.

ํ•จ์ˆ˜๋Š” ์ž˜์ง€์–ด์ง„, ์„œ์ˆ ์ ์ธ, ๊ธด ์ด๋ฆ„์„ ๊ฐ–๋Š” ๋งŽ์€/์ž‘์€ ํ•จ์ˆ˜๋“ค๋กœ ์œ ์ง€ ํ•ด์•ผํ•œ๋‹ค.

ํฐ ํ•จ์ˆ˜๋Š” ํด๋ž˜์Šค๋กœ ์ถ”์ถœํ•ด์•ผํ•œ๋‹ค.

ํ•จ์ˆ˜๋Š” ๋”์ด์ƒ ์ž‘์•„์งˆ ์ˆ˜ ์—†์„ ๋งŒํผ ์ž‘์•„์•ผํ•œ๋‹ค.

ํ•จ์ˆ˜๋กœ ์ถ”์ถœํ•˜๋Š” ๊ณผ์ •์ค‘์— ์•ฝ๊ฐ„์˜ ๊ทœ์น™์ด ์žˆ๋‹ค

  • ํ•จ์ˆ˜๋Š” ์ž‘์•„์งˆ ์ˆ˜ ์žˆ๋Š”ํ•œ ์ตœ๋Œ€ํ•œ ์ž‘์•„์•ผํ•จ

    • ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ์— ๋“ค์–ด๊ฐ€์ง€ ์•Š๊ณ ๋„ ์–ด๋–คํ•จ์ˆ˜์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ์ž‘์„ฑ
  • if, else, while ๋ฌธ์žฅ๋“ฑ์˜ ๋‚ด๋ถ€ ๋ธ”๋ก์€ ํ•œ ์ค„

    • ๊ด„ํ˜ธ๊ฐ€ ์—†์–ด์•ผ ํ•จ
  • ๋“ค์—ฌ์“ฐ๊ธฐ๊ฐ€ ์ ์–ด์•ผํ•จ

    • ํ•จ์ˆ˜๋Š” ์ค‘์ฒฉ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์งˆ ๋งŒํผ ํฌ๋ฉด ์•ˆ๋จ
  • ํ•จ์ˆ˜๋Š” 1๊ฐ€์ง€์ผ๋งŒ ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๋…์ž ์ž…์žฅ์ด ์•„๋‹Œ caller์ž…์žฅ์—์„œ ํ•œ๊ฐ€์ง€

๊ฒฐ๊ตญ ํ•จ์ˆ˜ ์ถ”์ƒํ™”๊ฐ€ ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•ด์•ผํ•  ์ผ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ถ”์ƒํ™”๋ผ๋Š” ๊ฐœ๋…์€ ์ •๋ง ์‰ฝ์ง€ ์•Š๋‹ค. ๋”๋”์šฑ ๊ฐœ๋ฐœ ๊ฒฝํ—˜์ด ๋ถ€์กฑํ•˜๊ฑฐ๋‚˜, ์†Œํ”„ํŠธ์›จ์–ด๊ณตํ•™์— ๋Œ€ํ•œ ์ „๋ฐ˜์ ์ธ ์ง€์‹์ด ๋ถ€์กฑํ•˜๋ฉด ๋ง์ด๋‹คโ€ฆ

์œ ๋ช…ํ•œ ์ฑ…์„ ์“ด ์ €์ž๋„, ๊ฐ•์˜์ž๋„ ์ถ”์ƒํ™”๋Š” ๋‚ด๊ฐ€ ํฌ๊ธฐ ํ•  ๋•Œ๊นŒ์ง€ ํ•ด์•ผํ•œ๋‹ค๊ณ  ๋งํ•œ๋‹ค.

ํŠนํžˆ if, while์ด ๋ณด์ด๋ฉด, extractํ•  ๋Œ€์ƒ์ด๋ผ๊ณ  ์˜์‹ฌ์„ ํ•ด์•ผํ•œ๋‹ค.

ํฌ์ธํŠธ

  1. ํ•จ์ˆ˜์˜ ๊ทœ๋ชจ๋Š” ์ž‘์•„์•ผํ•œ๋‹ค.
  2. ์œ„ ํ•จ์ˆ˜๋ณด๋‹ค ์ž‘์•„์•ผํ•œ๋‹ค.
  3. ์ด๋ฆ„์„ ์ž˜์ง€์–ด์•ผํ•œ๋‹ค.
  4. ํ•จ์ˆ˜๋Š” ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ํ•ด์•ผํ•œ๋‹ค.
  5. ๋”์ด์ƒ ์ถ”์ถœ ํ•  ์ˆ˜ ์—†์„ ๋•Œ๊นŒ์ง€(๋ฐ”๊ฟ€๊ฒŒ ์ด๋ฆ„ ๋ง๊ณ  ์—†์„ ๋•Œ๊นŒ์ง€) ํ•ด์•ผํ•œ๋‹ค.

Function Structure

1. Arguments

  1. ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” 3๊ฐœ ์ดํ•˜๋ฅผ ์ง€ํ–ฅํ•œ๋‹ค.(๊ทธ ์ด์ƒ๊ฐ€๋ฉด ์ž‘์„ฑ์ž ์กฐ์ฐจ๋„ ๋ญ์˜€๋Š”์ง€ ์•Œ ์ˆ˜๊ฐ€ ์—†๋‹ค.)

    ๋งŒ์ผ ์‹œ์ž‘, ๋์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์•„ ์˜จ๋‹ค๋ฉด ๋ฒ”์œ„ ๊ฐ’์„ ์ค˜์„œ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์ˆซ์ž๋ฅผ ์ค„์ผ ์ˆ˜๊ฐ€์žˆ๋‹ค.

    ex) amountInvoicedIn(start: Data, end: Data) => amountInvoicedIn(DataRange)

    ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ๊ฐ€๋…์„ฑ๋„ ์ข‹์•„์ง€๊ณ  ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์ด ์ •ํ™•ํžˆ ์–ด๋–ค๊ฑด์ง€ ์•Œ๊ธฐ๋„ ์‰ฝ๋‹ค.

package function_structure;

public class NutritionFacts {
    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;

    public NutritionFacts(int servingSize, int servings) {
        this.servingSize = servingSize;
        this.servings = servings;
    }

    public NutritionFacts(int servingSize, int servings, int calories) {
        this.servingSize = servingSize;
        this.servings = servings;
        this.calories = calories;
    }

    public NutritionFacts(int servingSize, int servings, int calories, int fat) {
        this.servingSize = servingSize;
        this.servings = servings;
        this.calories = calories;
        this.fat = fat;
    }

    public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium) {
        this.servingSize = servingSize;
        this.servings = servings;
        this.calories = calories;
        this.fat = fat;
        this.sodium = sodium;
    }

    public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium, int carbohydrate) {
        this.servingSize = servingSize;
        this.servings = servings;
        this.calories = calories;
        this.fat = fat;
        this.sodium = sodium;
        this.carbohydrate = carbohydrate;
    }

}

์‹ํ’ˆ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” Class๊ฐ€ ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋งˆ์ง€๋ง‰ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ด์„œ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๊ฐ’๋“ค์„ ๋„˜๊ฒจ ์ค„๋•Œ

package function_structure;

import org.junit.Test;

public class NutritionFactsTest {
    @Test
    public void canCreate() {
        NutritionFacts cocacola =
                new NutritionFacts(240, 8, 100, 0, 35, 27);
    }
}

์ด๋Ÿฐ์‹์œผ๋กœ ์ˆซ์ž๋งŒ ๋„˜๊ฒจ์ฃผ๊ฒŒ ๋˜๋Š”๋ฐ ์ž‘์„ฑ์ž ์กฐ์ฐจ๋„ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ์–ด๋–ค ๊ฐ’์„ ๋„˜๊ธฐ๋Š”์ง€ ์–ด๋ ค์›Œ ์ง„๋‹ค.

์—ฌ๊ธฐ์„œ Java Bean Pattern์„ ์‚ฌ์šฉํ•ด์„œ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

package function_structure;

public class NutritionFacts {
    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;

    public static class Builder {
        // Required parameters
        private final int servingSize;
        private final int servings;
        // Optional parameters
        private final int calories = 0;
        private final int fat = 0;
        private final int sodium = 0;
        private final int carbohydrate = 0;

        public Builder(int servingSize, int servings) {
            this.servingSize = servingSize;
            this.servings = servings;
        }

        public Builder calories(int val) {
            calories = val;
            return this;
        }

        public Builder fat(int val) {
            fat = val;
            return this;
        }

        public Builder sodium(int val) {
            sodium = val;
            return this;
        }

        public Builder carbohydrate(int val) {
            carbohydrate = val;
            return this;
        }

        public NutritionFacts build() {
            return new NutritionFacts(this);
        }
    }

    private NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        calories = builder.calories;
        fat = builder.fat;
        sodium = builder.sodium;
        carbohydrate = builder.carbohydrate;
    }
}

์ด๋Ÿฐ์‹์œผ๋กœ Builder class๋ฅผ ๋งŒ๋“ค์–ด์„œ getter๋ฅผ ๋งŒ๋“ค์–ด ์ž๊ธฐ ์ž์‹ ์„ returnํ•œ๋‹ค.

์ด๋ ‡๊ฒŒ ๋งŒ๋“ค๋ฉด

package function_structure;

import org.junit.Test;

public class NutritionFactsTest {
    @Test
    public void canCreate() {
        NutritionFacts cocacola =
                new NutritionFacts.Builder(240, 8).
                        calories(100).
                        sodium(35).
                        carbohydrate(27).
                        build();
    }
}

์ด๋ ‡๊ฒŒ ๊ฐ€๋…์„ฑ์ด ์˜ฌ๋ผ๊ฐ„๋‹ค.

๊ฐ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์ด ์–ด๋–ค๊ฒƒ์„ ์˜๋ฏธํ•˜๋Š”์ง€ ํ•œ๋ˆˆ์— ์•Œ์•„๋ณด๊ธฐ ์‰ฝ๋‹ค.

  1. Boolean ์ธ์ž๋Š” ๊ฐ€๊ธ‰์  ์‚ฌ์šฉํ•˜์ง€ ๋ง์ž

ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ๋•Œ ํ•ด์•ผํ•  ๊ฒƒ์€ ์ตœ๋Œ€ํ•œ์„ ์ชผ๊ฐค์ˆ˜ ์žˆ์„ ๋•Œ๊นŒ์ง€ ์ชผ๊ฐœ๋Š” ๊ฒƒ์ด๋‹ค.

๊ฐ’์ด ๋“ค์–ด์™€์„œ true์ผ ๊ฒฝ์šฐ์™€ false์ผ ๊ฒฝ์šฐ๋ผ๋Š” 2๊ฐ€์ง€ ๋™์ž‘์ด ํ•จ์ˆ˜์— ๋“ค์–ด๊ฐ€ ์žˆ์œผ๋ฉด extract๋ฅผ ํ•ด์„œ ํ–‰์œ„์„ ๋‚˜๋ˆ„๊ณ  ๋˜ ๊ณตํ†ต๋œ ์ ์ด ์žˆ๋‹ค๋ฉด ๋‹ค์‹œ ์ชผ๊ฐœ๋Š” ์ด๋Ÿฐ์‹์œผ๋กœ ํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๋‹จ์ˆœํ•ด์ง€๊ณ  ๋ณต์žก๋„๋Š” ์ค„์–ด๋“ค๊ฒŒ ๋œ๋‹ค.

  1. output์ธ์ž๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ง์ž

์ธ์ž ๊ฐ’์„ ๋ฐ›์•„์„œ ๊ทธ ๋ณ€์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋„ ์žˆ๋‹ค.

์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ ์ž‘์„ฑ์ž๋Š” ์ดํ•ดํ• ์ง€ ๋ชฐ๋ผ๋„ ๋‹ค๋ฅธ ํŒ€์›๋“ค์ด๋‚˜ ์œ ์ง€๋ณด์ˆ˜๋ฅผ ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋Š” ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šด ์ฝ”๋“œ๊ฐ€๋œ๋‹ค. ์ด๋Ÿด ๊ฒฝ์šฐ๋Š” ๋กœ์ปฌ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํšจ์œจ์ ์ด๋‹ค.

  1. null๊ฐ’์„ ํ•จ์ˆ˜์˜ return ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ๋ง์ž

null๊ฐ’๋„ ๊ฒฐ๊ตญ null์ธ๊ฐ’๊ณผ ์•„๋‹Œ ๊ฐ’์œผ๋กœ ๋‚˜๋‰˜์–ด์ง„๋‹ค. ์ด๋Ÿฌ๋ฉด ์•ž์—์„œ ๋งํ–ˆ๋˜ boolean๊ฐ’๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ 2๊ฐ€์ง€์˜ ํ–‰์œ„๊ฐ€ ์ƒ๊ธฐ๋Š” ๊ฒƒ์ด๋‹ค.

  1. ์ฝ”๋“œ์— null์ฒดํฌ, ์—๋Ÿฌ์ฒดํฌ๋กœ ๋”๋Ÿฝํžˆ์ง€ ๋ง์ž

์ฝ”๋“œ์— null์ฒดํฌ, ์—๋Ÿฌ์ฒดํฌ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ๊ฐœ์„ ์˜ ์—ฌ์ง€๊ฐ€ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ด๊ธฐ๋„ํ•˜๋‹ค.

๋˜ ์œ„ ์˜๋ฏธ๋Š” ํŒ€์›๋“ค์ด๋‚˜, ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๋ชป๋ฏฟ์–ด์„œ ์ž‘์„ฑํ•œ ๊ฒƒ์ด๋ผ๋Š” ์˜๋ฏธ๋„ ์žˆ๋‹ค.

null์—ฌ๋ถ€์— ๋Œ€ํ•ด์„œ๋Š” ์ง€์†์ ์œผ๋กœ ์ฒดํฌํ•˜์ง€ ๋ง๊ณ , TDD ์ฆ‰, ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด์„œ ๊ฒ€์ฆ์„ ํ•ด์•ผํ•œ๋‹ค.

2. The Stepdown Rule

๋ชจ๋“  public์€ ์œ„์—, ๋ชจ๋“  private๋Š” ์•„๋ž˜์—

์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ ์œ„๋กœ, ์ƒ์„ธํ•œ ๋ถ€๋ถ„์€ ๋ฐ‘์œผ๋กœ ํ•ด์„œ public part๋งŒ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌํ•˜๋ฉด ๋œ๋‹ค.

์žก์ง€๋ฅผ ์˜ˆ์‹œ๋กœ ๋“ค๋ฉด, ํ—ค๋“œ๋ผ์ธ์„ ๋จผ์ € ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ๊ณผ ๊ฐ™๋‹ค.

์œ„ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ด์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ํŽธ์ง‘์ž๋“ค์€ ์˜คํ•ด๊ฐ€ ์—†์ด ๋””ํ…Œ์ผํ•œ ๋ถ€๋ถ„์„ ์ œ๊ฑฐํ•˜๊ณ  ํ•„์ˆ˜ ์ ์ธ ์š”์†Œ๋“ค๋งŒ ์ „๋‹ฌ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋…์ž๋“ค์€ ์œ„์—์„œ ๋ถ€ํ„ฐ ์ฝ๊ธฐ ์‹œ์ž‘ํ•˜๊ณ , ์ดํ•ด๋ฅผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค๋ฉด ๊ทธ๋งŒ ์ฝ์œผ๋ฉด ๋œ๋‹ค.
public void serve(socket s) {
    try {
        tryProcessInsertructions(s);
    } catch(Throwable e) {
        slimFactory.stop();
        close();
        closeEnclosingServiceInseperateThread();
    }
}

private void tryProcessInsertructions(socket s) throws Exception {...}

์ด๋Ÿฐ์‹์œผ๋กœ ํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค๋ฉด ๋ฐ”๋กœ ์•„๋ž˜์— ์žˆ์–ด์•ผ ๊ฐ€๋…์„ฑ์ด ์ฆ๊ฐ€ํ•œ๋‹ค.

3.Switches And Cases

Switch๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด case๋ฌธ์—์„œ ์˜์กด์„ฑ๋ฌธ์ œ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋˜๋„๋ก์ด๋ฉด ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

์˜์กด์„ฑ์„ ์ตœ๋Œ€ํ•œ ์ค„์—ฌ์•ผ ๋…๋ฆฝ์ ์œผ๋กœ ๋ถ„๋ฆฌ๊ฐ€ ๋˜๋Š” ๊ฐ์ฒด์ง€ํ–ฅ์ ์ธ ์ฝ”๋“œ๊ฐ€ ๋œ๋‹ค.

switch๋ฌธ์˜ ๋ฌธ์ œ์ ์€ case๋ฌธ์—์„œ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜๋ฉด switch๋ฅผ ์ˆ˜์ •ํ•ด์•ผํ•œ๋‹ค.

4.Temporal Coupling

ํ•จ์ˆ˜๋“ค์ด ์ˆœ์„œ๋ฅผ ์ง€ํ‚ค๋ฉฐ ํ˜ธ์ถœ๋˜์–ด์•ผํ•œ๋‹ค.

์˜ˆ์‹œ๋ฅผ ๋“ค๋ฉด,

//file should be opend before processing
fileCommand.process(file);
//file should be closed after processing

์ด๋Ÿฐ์‹์œผ๋กœ ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์ „์— ํŒŒ์ผ์€ ์—ด๋ ค์žˆ์–ด์•ผ ํ•˜๊ณ , ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•œ ํ›„์— ํŒŒ์ผ์ด ๋‹ซํ˜€ ์žˆ์–ดํ–ํ•œ๋‹ค.

๋งŒ์•ฝ, ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋Ÿฐํ˜•์‹์„ ์ง€ํ‚ค์ง€ ์•Š๊ณ  ์‹คํ–‰ํ•  ๊ฒฝ์šฐ ์—๋Ÿฌ๋Š” ๋‚ ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.

fileCommandTemplate.process(myfile, new FileCommand() {
    public void process(File f) {
        // file processing codes here
    }
});

class FileCommandTemplate{
    public void process(File file, FileComand command) {
        file.open();
        command.process(file);
        file.close();
    }
}

๊ฐœ๋ฐœ์ž๋Š” ์ด๋Ÿฐ์‹์œผ๋กœ ์‹คํ–‰ํ•˜๋Š” ๋ถ€๋ถ„์ด ๋ณต์žกํ•˜๋ฉด ๋”ฐ๋กœ ๋นผ๊ฑฐ๋‚˜ ํ•ด์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์—๋Ÿฌ๋ฅผ ๋‚ผ์ˆ˜ ์žˆ๋Š” ์—ฌ์ง€๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.

5.CQS

Command(๋ช…๋ น)ํ•จ์ˆ˜์™€ Query(์งˆ์˜)ํ•จ์ˆ˜๋ฅผ ๊ฐ๊ฐ ํ•จ์ˆ˜๋ช…๋Œ€๋กœ ๋™์ž‘, ๊ธฐ๋Šฅ ํ•ด์•ผํ•œ๋‹ค. ๋งŒ์ผ Queryํ•จ์ˆ˜์ธ๋ฐ, ๋‚ด๋ถ€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•˜๊ฑฐ๋‚˜, Commandํ•จ์ˆ˜์ธ๋ฐ return๊ฐ’์ด ์žˆ๊ฑฐ๋‚˜ํ•˜๋ฉด, ๊ฐœ๋ฐœ์ž์— ๋Œ€ํ•œ ์‹ ๋ขฐ๊ฐ€ ๋–จ์–ด์ ธ์„œ ์ฝ”๋“œ๋ฅผ ์ฝ์„ ๋•Œ ๋‚ด์šฉ์„ ์ „๋ถ€ ๋ด์•ผ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๊ฐ€์žฅ ์ด์ƒ์ ์ธ Side effect(์˜ˆ์ƒ์™ธ์˜ ๋ฐ˜์‘)๊ด€๋ฆฌ ๋ฐฉ๋ฒ•

  1. ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์‚ผ์ˆ˜๋Š” ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์•ˆ๋จ
  2. ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋Š” ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์•ˆ๋จ
  • Command
    • ์‹œ์Šคํ…œ์˜ ์ƒํƒœ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ
    • return๊ฐ’ X
    • side effect๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Œ(๋ณ€ํ™”)
  • Query
    • ๊ณ„์‚ฐ๊ฐ’์ด๋‚˜, ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜
    • side effect๊ฐ€ ์—†์Œ
User u = authorizer.login(userName, password);

๋กœ๊ทธ์ธ์„ ํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ’์„ ๋ฐ˜ํ™˜ ๋ฐ›๋Š”๋‹ค. ๋กœ๊ทธ์ธํ•œ ์œ ์ € ์ •๋ณด๋ฅผ ๋ฐ›๊ณ  ์‹ถ์ง€ ์•Š๋Š”๋ฐ๋„ ๋ฐ›์•„์•ผํ•œ๋‹ค.

authorizer.login(userName, password);
User u = authorizer.getUser(userName);

์ด๋Ÿฐ์‹์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์˜ˆ์ƒ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ๋ฅผ ์งœ์•ผ ๋‹ค๋ฅธ ๋™๋ฃŒ ๊ฐœ๋ฐœ์ž๋‚˜, ๋…์ž์—๊ฒŒ ๊ฐœ๋ฐœ์ž์— ๋Œ€ํ•œ ์‹ ๋ขฐ์„ฑ ์ƒ๊ธด๋‹ค.

6.Tell, Donโ€™t ask

ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ๋•Œ ์ค‘์š”ํ•œ๊ฒƒ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋งํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๋ฌด์–ธ๊ฐ€์—๊ฒŒ ๋ฌผ์–ด๋ณด๊ฒŒ ๋˜๋ฉด, ํ•จ์ˆ˜๋Š” ์—ฎ์€ ๊ทธ๋ฌผ์ด๋‚˜, ์ฒด์ธ๊ฐ™์€ ๊ตฌ์กฐ๊ฐ€ ๋œ๋‹ค.

o.getX()
    .getY()
	    .getZ()
    		.doSomething();

์ด๋Ÿฌ์‹์œผ๋กœโ€ฆ

์–ด๋–ค ์‚ฌ๋žŒ์ด ๋ด๋„ ์ด๋Ÿฐ๊ฒƒ์€ ์ดํ•ดํ•˜๊ธฐ ํž˜๋“ค๊ณ , ๊ฒฐ๊ตญ ์˜์กด์„ฑ๋งŒ ๋†’์•„์ง€๊ฒŒ ๋œ๋‹ค.

o.doSomething();

์ด๋ ‡๊ฒŒ ๋ฐ”๊ฟ”์„œ doSomething์ด ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ๋˜ ๋ถ€๋ฅด๋Š” ์‹์œผ๋กœ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ•œ๋‹ค.

7.Law of Demeter

์œ„์˜ ์‚ฌํƒœ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด Tell, Donโ€™t ask์˜ ๋ช‡๊ฐ€์ง€ ๊ทœ์น™์ด ์žˆ๋‹ค.

๊ฐ์ฒด๋Š” ์•„๋ž˜์˜ ๋ฉ”์†Œ๋“œ๋งŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์ธ์ž๋กœ ์ „๋‹ฌ๋œ ๊ฐ์ฒด
  • localy ์ƒ์„ฑํ•œ ๊ฐ์ฒด
  • ํ•„๋“œ๋กœ ์„ ์–ธ๋œ ๊ฐ์ฒด
  • ์ „์—ญ ๊ฐ์ฒด

์œ„ ๊ทœ์น™์„ ์ž˜ ์ง€ํ‚ค๋ฉด, ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์•„์ง€๊ณ  ๋ณต์žกํ•œ ์˜์กด์„ฑ์€ ๋Š์–ด ์งˆ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.

๊ฐ์ฒด๋Š” ์ตœ์ข… ๋ชฉ์ ์ง€๊นŒ์ง€ ์•Œํ•„์š” ์—†์ด ์ตœ์ข… ๋ชฉ์ ์ง€๊นŒ์ง€ ๊ฐ€๋Š” ๊ณผ์ •์ค‘ ๋‹ค์Œ ๋ชฉ์ ์ง€๋งŒ ์•Œ๋ฉด ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋ฅผ ์งœ๋Š” ๊ฒƒ๋„ ๊ฐ„๋‹จํ•ด ์ง„๋‹ค.

8.early returns

private boolean nameIsValxxxx () {
    if(name.euqls(""))
        return true;
    if(!wikiWordWidget.xxx)
        return true;
    return false;
}

early return์ด๋‚˜, guarded return์€ ํ—ˆ์šฉ๋˜๋งŒ ๊ฐ€๊ธ‰์  ์ฝ๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฌด์—‡์ด ๋…์ž์—๊ฒŒ ๋” ๋‚˜์€ ์ฝ”๋“œ์ธ์ง€๋ฅผ ์ƒ๊ฐํ•˜๋ฉฐ ์งœ์•ผํ•œ๋‹ค.

ํ•˜์ง€๋งŒ early return์ด ๋ฌธ์ œ์ธ ๊ฒƒ์€ loop์—์„œ ๋ฐœ์ƒํ•œ๋‹ค.

loop์—์„œ return์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ ๋…์ž๋„ ์ฝ๊ธฐ ์–ด๋ ค์›Œ์ง€๊ณ  ํ…Œ์ŠคํŠธ๋„ ํ•˜๊ธฐ ์–ด๋ ค์›Œ ์ง„๋‹ค. ๋™์ž‘ < ์ดํ•ด

์•ฝ์–ด

  • CQS : Command Query Separation

์ฐธ์กฐ

  • ๋ฐฑ๋ช…์„์˜ ํด๋ฆฐ์ฝ”๋“œ Youtube ๊ฐ•์ขŒ