Skip to content

Latest commit

ย 

History

History
566 lines (404 loc) ยท 24.9 KB

File metadata and controls

566 lines (404 loc) ยท 24.9 KB

item 18 : ์ƒ์†๋ณด๋‹ค๋Š” ์ปดํฌ์ง€์…˜์„ ์‚ฌ์šฉํ•˜๋ผ

1. ๊ตฌํ˜„ ์ƒ์†

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

1) ์ƒ์†์ด๋ž€

  • ํ•œ ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ์†์„ฑ๊ณผ ๋ฉ”์„œ๋“œ๋ฅผ ํ™•์žฅ ํ˜น์€ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๋งค์ปค๋‹ˆ์ฆ˜

2) ์ƒ์†์˜ ๋ฌธ์ œ์ 

{% hint style="danger" %} ์ƒ์†์€ ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ์ˆ˜๋‹จ์ด์ง€๋งŒ, ํ•ญ์ƒ ์ตœ์„ ์€ ์•„๋‹ˆ๋‹ค {% endhint %}

  • ๊ฐ•ํ•œ ๊ฒฐํ•ฉ : ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๋ณ€๊ฒฝ์ด ์ž์‹ ํด๋ž˜์Šค์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์–ด ์œ ์—ฐ์„ฑ์ด ์ €ํ•˜๋œ๋‹ค.
  • ์บก์Аํ™” ์œ„๋ฐ˜ : ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์— ์˜์กดํ•˜๊ฒŒ๋˜๋ฉด, ์บก์Аํ™”๊ฐ€ ์•ฝํ™”๋œ๋‹ค.
  • ์žฌ์‚ฌ์šฉ์„ฑ ์ €ํ•˜ : ํŠน์ • ๊ตฌํ˜„์— ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋œ ์ƒ์† ๊ตฌ์กฐ๋Š” ์ƒˆ๋กœ์šด ์ƒํ™ฉ์— ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

3) ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ๊ณผ ๋‹ฌ๋ฆฌ ์ƒ์†์€ ์บก์Аํ™”๋ฅผ ๊นจ๋œจ๋ฆฐ๋‹ค.

๋‹ค๋ฅด๊ฒŒ ๋งํ•˜๋ฉด, ์ƒ์œ„ ํด๋ž˜์Šค๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„๋˜๋А๋ƒ์— ๋”ฐ๋ผ ํ•˜์œ„ ํด๋ž˜์Šค์˜ ๋™์ž‘์— ์ด์ƒ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

์ž˜๋ชป๋œ ์ƒ์†์˜ ์˜ˆ

public class InstrumentedHashSet<E> extends HashSet<E> {
    private int addCount = 0;

    public InstrumentedHashSet() { }

    @Override
    public boolean add(E e) {
        addCount++;
        return super.add(e);
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        addCount += c.size();
        return super.addAll(c);
    }

    public int getAddCount() {
        return addCount;
    }
}
InstrumentedHashSet<String> s = new InstrumentedHashSet<>();
s.addAll(Arrays.asList("ํ‹ฑ", "ํƒํƒ", "ํŽ‘"));

System.out.println(s.getAddCount()); // ์˜ˆ์ƒ: 3, ์‹ค์ œ: 6

์ผ๋ฐ˜์ ์œผ๋กœ ์œ„ ์ฝ”๋“œ ์‹คํ–‰ ํ›„ addCount๊ฐ€ 3์ด ๋  ๊ฒƒ์ด๋ผ ์˜ˆ์ƒํ•  ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” 6์ด๋‹ค. ์ด์œ ๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค์ธ HashSet์˜ addAll ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ add๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

addAll์„ ํ˜ธ์ถœํ•˜๋ฉด ๋‚ด๋ถ€์—์„œ add๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋ฐ add๊ฐ€ ์ƒ์œ„ ํด๋ž˜์Šค์˜ add๋ฅผ ํ˜ธ์ถœํ• ์ค„ ์•Œ์•˜์ง€๋งŒ InstrumentedHashSet์˜ add๋ฅผ ํ˜ธ์ถœํ–ˆ๋‹ค.

์œ„์—์„œ์˜ ๋ฌธ์ œ๋Š” ๋ฉ”์„œ๋“œ ์žฌ์ •์˜ ์‹œ ๋‹น์žฅ์€ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์œผ๋‚˜, HashSet์˜ addAll์ด add ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ๊ตฌํ˜„ํ–ˆ์Œ์„ ๊ฐ€์ •ํ•œ ํ•ด๋ฒ•์ด๋ผ๋Š” ํ•œ๊ณ„๋ฅผ ์ง€๋‹Œ๋‹ค. ์ด์ฒ˜๋Ÿผ ์ž์‹ ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์„ ์‚ฌ์šฉํ•˜๋Š” โ€˜์ž๊ธฐ์‚ฌ์šฉ(self-use)1โ€™ ์—ฌ๋ถ€๋Š” ํ•ด๋‹น ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„ ๋ฐฉ์‹ ์— ํ•ด๋‹นํ•˜๋ฉฐ, ์ž๋ฐ” ํ”Œ๋žซํผ ์ „๋ฐ˜์ ์ธ ์ •์ฑ…์ธ์ง€, ๊ทธ๋ž˜์„œ ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค์—์„œ๋„ ์œ ์ง€๋ ์ง€๋Š” ์•Œ ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฐ ๊ฐ€์ •์— ๊ธฐ๋Œ„ InstrumentedHashSet2๋„ ๊นจ์ง€๊ธฐ ์‰ฝ๋‹ค.

addAll ๋ฉ”์„œ๋“œ๋ฅผ ๋‹ค๋ฅธ ์‹์œผ๋กœ ์žฌ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ฃผ์–ด์ง„ ์ปฌ๋ ‰์…˜์„ ์ˆœํšŒํ•˜๋ฉฐ ์›์†Œ ํ•˜๋‚˜๋‹น add ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜๋‚˜๋งŒ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์กฐ๊ธˆ ๋‚˜์€ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ ์ƒ์œ„ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ ๋™์ž‘์„ ๋‹ค์‹œ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ต๊ณ , ๋น„์šฉ์ด ๋“ ๋‹ค. ๋˜ํ•œ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋Š” private ํ•„๋“œ๋ฅผ ์จ์•ผ ํ•œ๋‹ค๋ฉด ์ด ๋ฐฉ์‹์œผ๋กœ๋Š” ๊ตฌํ˜„ ์ž์ฒด๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

  • ์ƒ์œ„ ํด๋ž˜์Šค์˜ ๊ตฌํ˜„์— ์˜์กด: HashSet์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์ด addAll()์—์„œ add()๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์— ์˜์กดํ•˜๊ณ  ์žˆ๋‹ค.
  • ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์˜ ์œ„ํ—˜์„ฑ: ์ƒ์œ„ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜๋ฉด, ์ƒ์œ„ ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์ด ๋ณ€๊ฒฝ๋  ๋•Œ ํ•˜์œ„ ํด๋ž˜์Šค์˜ ๋™์ž‘์ด ์˜ˆ๊ธฐ์น˜ ์•Š๊ฒŒ ๋ณ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

{% hint style="info" %} ๊ทธ๋ ‡๋‹ค๋ฉด ์œ„์—์„œ์˜ ๋ฌธ์ œ๋Š” ๋‹ค ๋ฉ”์„œ๋“œ ์žฌ์ •์˜ ์‹œ๋‹ˆ๊นŒ ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค๋ฉด? {% endhint %}

์ด ๋ฐฉ์‹์ด ํ›จ์”ฌ ์•ˆ์ „ํ•œ ๊ฒƒ์€ ๋งž์ง€๋งŒ, ์œ„ํ—˜์ด ์ „ํ˜€ ์—†๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค์—์„œ ์ƒ์œ„ ํด๋ž˜์Šค์— ์ƒˆ ๋ฉ”์„œ๋“œ๊ฐ€ ์ถ”๊ฐ€๋๋Š”๋ฐ, ํ•˜ํ•„ ํ•˜์œ„ ํด๋ž˜์Šค์— ์ถ”๊ฐ€ํ•œ ๋ฉ”์„œ๋“œ์™€ ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ ๊ฐ™๊ณ  ๋ฐ˜ํ™˜ ํƒ€์ž…์€ ๋‹ค๋ฅด ๋‹ค๋ฉด ์—ฌ๋Ÿฌ๋ถ„์˜ ํด๋ž˜์Šค๋Š” ์ปดํŒŒ์ผ์กฐ์ฐจ ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

2. ์ปดํฌ์ง€์…˜(composition)

{% hint style="warning" %} ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ํฌํ•จํ•˜์—ฌ, ๊ทธ ์ธ์Šคํ„ด์Šค์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ์‹ {% endhint %}

๊ธฐ์กด ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๋Š” ๋Œ€์‹ , ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ  private ํ•„๋“œ๋กœ ๊ธฐ์กด ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ํ•˜์ž. ์ƒ์†์˜ ๋ฌธ์ œ์˜ ๋Œ€์•ˆ๋ฒ•์ธ ์ปดํฌ์ง€์…˜์€ ๊ธฐ์กด ํด๋ž˜์Šค๊ฐ€ ์ƒˆ๋กœ์šด ํด๋ž˜์Šค์˜ ๊ตฌ์„ฑ์š”์†Œ๋กœ ์“ฐ์ธ๋‹ค๋Š” ๋œป์ด๋‹ค.

์ƒˆ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ๋ฉ” ์„œ๋“œ๋“ค์€ (private ํ•„๋“œ๋กœ ์ฐธ์กฐํ•˜๋Š”) ๊ธฐ์กด ํด๋ž˜์Šค์˜ ๋Œ€์‘ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ ํ•ด ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด ๋ฐฉ์‹์„ ์ „๋‹ฌ(forwarding)์ด๋ผ ํ•˜๋ฉฐ, ์ƒˆ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ๋“ค์„ ์ „๋‹ฌ ๋ฉ”์„œ๋“œ(forwarding method)๋ผ ๋ถ€๋ฅธ๋‹ค.

๊ทธ ๊ฒฐ๊ณผ ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋Š” ๊ธฐ์กด ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„ ๋ฐฉ์‹์˜ ์˜ํ–ฅ์—์„œ ๋ฒ—์–ด๋‚˜๋ฉฐ, ์‹ฌ์ง€์–ด ๊ธฐ์กด ํด๋ž˜์Šค์— ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜๋”๋ผ๋„ ์ „ํ˜€ ์˜ํ–ฅ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.

์ƒ์† ๋Œ€์‹  ์ปดํฌ์ง€์…˜(Composition)์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์กด Set ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ์‹ธ๋Š” ๋ž˜ํผ ํด๋ž˜์Šค(Wrapper Class)๋ฅผ ๋งŒ๋“ค์–ด๊ธฐ

public class InstrumentedSet<E> implements Set<E> {
    private final Set<E> set;
    private int addCount = 0;

    public InstrumentedSet(Set<E> set) {
        this.set = set;
    }

    @Override
    public boolean add(E e) {
        addCount++;
        return set.add(e);
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        addCount += c.size();
        return set.addAll(c);
    }

    public int getAddCount() {
        return addCount;
    }

    // ๋‚˜๋จธ์ง€ Set ์ธํ„ฐํŽ˜์ด์Šค ๋ฉ”์„œ๋“œ๋“ค์€ set ์ธ์Šคํ„ด์Šค์— ์œ„์ž„
    @Override
    public int size() {
        return set.size();
    }

    @Override
    public boolean isEmpty() {
        return set.isEmpty();
    }

    // ... ๊ธฐํƒ€ ๋ฉ”์„œ๋“œ๋“ค๋„ ๋™์ผํ•˜๊ฒŒ ์œ„์ž„
}

์„ค๋ช…:

  • InstrumentedSet์€ Set ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ , ๋‚ด๋ถ€์— ์‹ค์ œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  Set ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ง„๋‹ค.
  • ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋Š” ๋‚ด๋ถ€ set ๊ฐ์ฒด์— ์ž‘์—…์„ ์œ„์ž„ํ•œ๋‹ค.
  • add()์™€ addAll() ๋ฉ”์„œ๋“œ์—์„œ addCount๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ์ฆ๊ฐ€์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
  • ์ƒ์†์ด ์•„๋‹Œ ์ปดํฌ์ง€์…˜์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์ƒ์œ„ ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์— ์˜์กดํ•˜์ง€ ์•Š๋Š”๋‹ค.

์‚ฌ์šฉ ์˜ˆ์‹œ:

Set<String> s = new InstrumentedSet<>(new HashSet<>());
s.addAll(Arrays.asList("ํ‹ฑ", "ํƒํƒ", "ํŽ‘"));

System.out.println(((InstrumentedSet<String>) s).getAddCount()); // ์ถœ๋ ฅ: 3
  • ์•ˆ์ „์„ฑ: ์ƒ์œ„ ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„ ๋ณ€ํ™”์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.
  • ์œ ์—ฐ์„ฑ: ๊ธฐ์กด ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ๋•Œ ๋” ์•ˆ์ „ํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์žฌ์‚ฌ์šฉ์„ฑ: ๋‹ค์–‘ํ•œ ํด๋ž˜์Šค์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•˜๊ธฐ ์‰ฝ๋‹ค.

์œ„์ž„ ๋ฉ”์„œ๋“œ๋ฅผ ์ผ์ผ์ด ์ž‘์„ฑํ•˜๋Š” ๋Œ€์‹ , ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํฌ์›Œ๋”ฉ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

public class ForwardingSet<E> implements Set<E> {
    protected final Set<E> s;

    public ForwardingSet(Set<E> s) {
        this.s = s;
    }

    @Override
    public boolean add(E e) { return s.add(e); }

    @Override
    public boolean addAll(Collection<? extends E> c) { return s.addAll(c); }

    // ๋‚˜๋จธ์ง€ ๋ฉ”์„œ๋“œ๋“ค๋„ ๋™์ผํ•˜๊ฒŒ s์— ์œ„์ž„
    @Override
    public int size() { return s.size(); }

    @Override
    public boolean isEmpty() { return s.isEmpty(); }

    // ... ๊ธฐํƒ€ ๋ฉ”์„œ๋“œ๋“ค๋„ ๋™์ผํ•˜๊ฒŒ ์œ„์ž„
}

์ด์ œ InstrumentedSet์€ ForwardingSet์„ ์ƒ์†๋ฐ›์•„ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ๋จ

public class InstrumentedSet<E> extends ForwardingSet<E> {
    private int addCount = 0;

    public InstrumentedSet(Set<E> s) {
        super(s);
    }

    @Override
    public boolean add(E e) {
        addCount++;
        return super.add(e);
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        addCount += c.size();
        return super.addAll(c);
    }

    public int getAddCount() {
        return addCount;
    }
}

InstrumentedSet์€ HashSet์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์ •์˜ํ•œ Set ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™œ์šฉํ•ด ์„ค๊ณ„๋˜์–ด ๊ฒฌ๊ณ ํ•˜๊ณ  ์•„์ฃผ ์œ ์—ฐํ•˜๋‹ค. ๊ตฌ์ฒด์ ์œผ๋กœ๋Š” Set ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ–ˆ๊ณ , Set์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š” ์ƒ์„ฑ์ž๋ฅผ ํ•˜๋‚˜ ์ œ๊ณตํ•œ๋‹ค. ์ž„์˜์˜ Set์— ๊ณ„์ธก ๊ธฐ๋Šฅ์„ ๋ง์”Œ์–ด ์ƒˆ๋กœ์šด Set์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ด ํด๋ž˜์Šค์˜ ํ•ต์‹ฌ์ด๋‹ค. ์ด ์ปดํฌ์ง€์…˜ ๋ฐฉ์‹์€ ํ•œ ๋ฒˆ๋งŒ ๊ตฌํ˜„ํ•ด๋‘๋ฉด ์–ด๋– ํ•œ Set ๊ตฌํ˜„์ฒด๋ผ๋„ ๊ณ„์ธกํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ์กด ์ƒ์„ฑ์ž๋“ค๋„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

Set<Instant> times = new InstrumentedSet<>(new TreeSet<>(cmp));
Set<E> s = new InstrumentedSet<>(new HashSet<>(INIT_CAPACITY));

๋‹ค๋ฅธ Set ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ์‹ธ๊ณ  ์žˆ๋‹ค๋Š” ๋œป์—์„œ InstrumentedSet ๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ๋ž˜ํผ ํด๋ž˜์Šค๋ผ ํ•˜๋ฉฐ, ๋‹ค๋ฅธ Set์— ๊ณ„์ธก ๊ธฐ๋Šฅ์„ ๋ง์”Œ์šด๋‹ค๋Š” ๋œป์—์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์ด๋ผ๊ณ  ํ•œ๋‹ค. ์ปดํฌ์ง€์…˜๊ณผ ์ „๋‹ฌ์˜ ์กฐํ•ฉ์€ ๋„“์€ ์˜๋ฏธ๋กœ ์œ„์ž„(delegation)์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

{% hint style="success" %} ์ƒ์†์€ ๋ฐ˜๋“œ์‹œ ํ•˜์œ„ ํด๋ž˜์Šค๊ฐ€ ์ƒ์œ„ ํด๋ž˜์Šค์˜ '์ง„์งœ' ํ•˜์œ„ ํƒ€์ž…์ธ ์ƒํ™ฉ์—์„œ๋งŒ ์“ฐ์—ฌ์•ผ ํ•œ๋‹ค. ๋‹ค๋ฅด๊ฒŒ ๋งํ•˜๋ฉด, ํด๋ž˜์Šค B๊ฐ€ ํด๋ž˜์Šค A์™€ is-a ๊ด€๊ณ„์ผ ๋•Œ๋งŒ ํด๋ž˜์Šค A๋ฅผ ์ƒ์†ํ•ด์•ผ ํ•œ๋‹ค. {% endhint %}

์ปดํฌ์ง€์…˜์„ ์จ์•ผ ํ•  ์ƒํ™ฉ์—์„œ ์ƒ์†์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฑด ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋…ธ์ถœํ•˜๋Š” ๊ผด์ด๋‹ค. ๊ทธ ๊ฒฐ๊ณผ API๊ฐ€ ๋‚ด๋ถ€ ๊ตฌํ˜„์— ๋ฌถ์ด๊ณ  ๊ทธ ํด๋ž˜์Šค์˜ ์„ฑ๋Šฅ๋„ ์˜์›ํžˆ ์ œํ•œ๋œ๋‹ค. ๋” ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋…ธ์ถœ๋œ ๋‚ด๋ถ€์— ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.

{% hint style="info" %} ๋ž˜ํผ ํด๋ž˜์Šค๋Š” ๋‹จ์ ์ด ๊ฑฐ์˜ ์—†๋‹ค. ํ•œ ๊ฐ€์ง€, ๋ž˜ํผ ํด๋ž˜์Šค๊ฐ€ ์ฝœ๋ฐฑ(callback) ํ”„๋ ˆ์ž„์›Œํฌ์™€๋Š” ์–ด์šธ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ๋งŒ ์ฃผ์˜ํ•˜๋ฉด ๋œ๋‹ค. {% endhint %}

์ฝœ๋ฐฑ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋Š” ์ž๊ธฐ ์ž์‹ ์˜ ์ฐธ์กฐ๋ฅผ ๋‹ค๋ฅธ ๊ฐ์ฒด์— ๋„˜๊ฒจ์„œ ๋‹ค์Œ ํ˜ธ์ถœ(์ฝœ๋ฐฑ) ๋•Œ ์‚ฌ์šฉํ•˜๋„๋ก ํ•œ๋‹ค. ๋‚ด๋ถ€ ๊ฐ์ฒด๋Š” ์ž์‹ ์„ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” ๋ž˜ํผ์˜ ์กด์žฌ๋ฅผ ๋ชจ๋ฅด๋‹ˆ ๋Œ€์‹  ์ž์‹ (this)์˜ ์ฐธ์กฐ๋ฅผ ๋„˜๊ธฐ๊ณ , ์ฝœ๋ฐฑ ๋•Œ๋Š” ๋ž˜ํผ๊ฐ€ ์•„๋‹Œ ๋‚ด๋ถ€ ๊ฐ์ฒด๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๋ฅผ SELF ๋ฌธ์ œ๋ผ๊ณ  ํ•œ๋‹ค.

์ „๋‹ฌ ๋ฉ”์„œ๋“œ๊ฐ€ ์„ฑ๋Šฅ์— ์ฃผ๋Š” ์˜ํ–ฅ์ด๋‚˜ ๋ž˜ํผ ๊ฐ์ฒด๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์— ์ฃผ๋Š” ์˜ํ–ฅ์„ ๊ฑฑ์ •ํ•˜๋Š” ์‚ฌ๋žŒ๋„ ์žˆ์ง€๋งŒ, ์‹ค์ „์—์„œ๋Š” ๋‘˜ ๋‹ค ๋ณ„๋‹ค๋ฅธ ์˜ํ–ฅ์ด ์—†๋‹ค๊ณ  ๋ฐํ˜€์กŒ๋‹ค. ์ „๋‹ฌ ๋ฉ”์„œ๋“œ๋“ค์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒŒ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ „๋‹ฌ ํด๋ž˜์Šค๋ฅผ ์ธํ„ฐ ํŽ˜์ด์Šค๋‹น ํ•˜๋‚˜์”ฉ๋งŒ ๋งŒ๋“ค์–ด๋‘ ๋ฉด ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋ง์”Œ์šฐ๋Š” ์ „๋‹ฌ ํด๋ž˜์Šค๋“ค์„ ์•„์ฃผ ์†์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

3. ์ƒ์†๊ณผ ์ปดํฌ์ง€์…˜์˜ ๋น„๊ต

1) ์ƒ์†(Inheritance)์˜ ์˜ˆ์‹œ

์˜ˆ์ œ: ์ „์ž๊ธฐ๊ธฐ(ElectronicDevice)์™€ ์Šค๋งˆํŠธํฐ(Smartphone)

๋ถ€๋ชจ ํด๋ž˜์Šค: ElectronicDevice

class ElectronicDevice {
    public void powerOn() {
        System.out.println("์ „์ž๊ธฐ๊ธฐ๊ฐ€ ์ผœ์กŒ์Šต๋‹ˆ๋‹ค.");
    }

    public void powerOff() {
        System.out.println("์ „์ž๊ธฐ๊ธฐ๊ฐ€ ๊บผ์กŒ์Šต๋‹ˆ๋‹ค.");
    }
}
  • ์„ค๋ช…: ElectronicDevice ํด๋ž˜์Šค๋Š” ์ „์ž๊ธฐ๊ธฐ์˜ ์ผ๋ฐ˜์ ์ธ ๋™์ž‘์ธ powerOn()๊ณผ powerOff() ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

์ž์‹ ํด๋ž˜์Šค: Smartphone

class Smartphone extends ElectronicDevice {
    public void makeCall(String number) {
        System.out.println(number + "๋กœ ์ „ํ™”๋ฅผ ๊ฒ๋‹ˆ๋‹ค.");
    }

    public void browseInternet() {
        System.out.println("์ธํ„ฐ๋„ท์„ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.");
    }
}
  • ์„ค๋ช…: Smartphone ํด๋ž˜์Šค๋Š” ElectronicDevice๋ฅผ ์ƒ์†๋ฐ›์•„ ์ „์ž๊ธฐ๊ธฐ์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•œ๋‹ค.
  • ๊ด€๊ณ„: Smartphone์€ ElectronicDevice์ด๋‹ค๋ผ๋Š” Is-a ๊ด€๊ณ„๋ฅผ ํ˜•์„ฑํ•œ๋‹ค.

์‚ฌ์šฉ ์˜ˆ์‹œ

public class Main {
    public static void main(String[] args) {
        Smartphone myPhone = new Smartphone();
        myPhone.powerOn();            // ์ „์ž๊ธฐ๊ธฐ๊ฐ€ ์ผœ์กŒ์Šต๋‹ˆ๋‹ค.
        myPhone.makeCall("010-1234-5678"); // 010-1234-5678๋กœ ์ „ํ™”๋ฅผ ๊ฒ๋‹ˆ๋‹ค.
        myPhone.browseInternet();     // ์ธํ„ฐ๋„ท์„ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.
        myPhone.powerOff();           // ์ „์ž๊ธฐ๊ธฐ๊ฐ€ ๊บผ์กŒ์Šต๋‹ˆ๋‹ค.
    }
}
  • ๊ฒฐ๊ณผ: Smartphone ๊ฐ์ฒด๋Š” ElectronicDevice์˜ ๋ฉ”์„œ๋“œ์ธ powerOn()๊ณผ powerOff()๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

2) ์ปดํฌ์ง€์…˜(Composition)์˜ ์˜ˆ์‹œ

์˜ˆ์ œ: Battery ํด๋ž˜์Šค์™€ Laptop ํด๋ž˜์Šค

๋…๋ฆฝ๋œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ ํด๋ž˜์Šค: Battery

class Battery {
    private int capacity; // ๋ฐฐํ„ฐ๋ฆฌ ์šฉ๋Ÿ‰ (๋‹จ์œ„: mAh)

    public Battery(int capacity) {
        this.capacity = capacity;
    }

    public void supplyPower() {
        System.out.println("๋ฐฐํ„ฐ๋ฆฌ์—์„œ ์ „์›์„ ๊ณต๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ์šฉ๋Ÿ‰: " + capacity + "mAh");
    }

    public void charge() {
        System.out.println("๋ฐฐํ„ฐ๋ฆฌ๋ฅผ ์ถฉ์ „ํ•ฉ๋‹ˆ๋‹ค.");
    }
}
  • ์„ค๋ช…: Battery ํด๋ž˜์Šค๋Š” ๋ฐฐํ„ฐ๋ฆฌ์˜ ๋™์ž‘์„ ์ •์˜ํ•œ๋‹ค.

์ปดํฌ์ง€์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค: Laptop

class Laptop {
    private Battery battery;

    public Laptop(int batteryCapacity) {
        this.battery = new Battery(batteryCapacity);
    }

    public void powerOn() {
        battery.supplyPower(); // ์œ„์ž„: Laptop์€ Battery์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
        System.out.println("๋…ธํŠธ๋ถ์ด ์ผœ์กŒ์Šต๋‹ˆ๋‹ค.");
    }

    public void powerOff() {
        System.out.println("๋…ธํŠธ๋ถ์ด ๊บผ์กŒ์Šต๋‹ˆ๋‹ค.");
    }

    public void chargeLaptop() {
        battery.charge(); // Battery์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ
    }
}
  • ์„ค๋ช…: Laptop ํด๋ž˜์Šค๋Š” Battery ๊ฐ์ฒด๋ฅผ ๊ตฌ์„ฑ์š”์†Œ๋กœ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค.
  • ๊ด€๊ณ„: Laptop์€ Battery๋ฅผ ๊ฐ€์ง„๋‹ค๋ผ๋Š” Has-a ๊ด€๊ณ„๋ฅผ ํ˜•์„ฑํ•œ๋‹ค.

์‚ฌ์šฉ ์˜ˆ์‹œ

public class Main {
    public static void main(String[] args) {
        Laptop myLaptop = new Laptop(5000);
        myLaptop.powerOn();      // ๋ฐฐํ„ฐ๋ฆฌ์—์„œ ์ „์›์„ ๊ณต๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ์šฉ๋Ÿ‰: 5000mAh
                                  // ๋…ธํŠธ๋ถ์ด ์ผœ์กŒ์Šต๋‹ˆ๋‹ค.
        myLaptop.chargeLaptop(); // ๋ฐฐํ„ฐ๋ฆฌ๋ฅผ ์ถฉ์ „ํ•ฉ๋‹ˆ๋‹ค.
        myLaptop.powerOff();     // ๋…ธํŠธ๋ถ์ด ๊บผ์กŒ์Šต๋‹ˆ๋‹ค.
    }
}
  • ๊ฒฐ๊ณผ: Laptop ๊ฐ์ฒด๋Š” Battery ๊ฐ์ฒด์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•œ3๋‹ค.

3) ์ƒ์†๊ณผ ์ปดํฌ์ง€์…˜์˜ ๋น„๊ต

1. ๊ด€๊ณ„์˜ ์ฐจ์ด

  • ์ƒ์†(Inheritance): Is-a ๊ด€๊ณ„๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค
  • ์ปดํฌ์ง€์…˜(Composition):
    • Has-a ๊ด€๊ณ„๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
    • ํ•œ ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ๊ตฌ์„ฑ์š”์†Œ๋กœ ํฌํ•จํ•˜๊ณ , ๊ทธ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ์‹œ: Laptop์€ Battery๋ฅผ ๊ฐ€์ง„๋‹ค.

2. ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ ์ธก๋ฉด

  • ์ƒ์†:
    • ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๋ชจ๋“  public ๋ฐ protected ๋ฉค๋ฒ„๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค.
    • ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์ด ์‰ฝ์ง€๋งŒ, ๋ถ€๋ชจ ํด๋ž˜์Šค์™€ ๊ฐ•ํ•œ ๊ฒฐํ•ฉ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  • ์ปดํฌ์ง€์…˜:
    • ํ•„์š”ํ•œ ๊ธฐ๋Šฅ๋งŒ ์„ ํƒ์ ์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    • ๊ตฌ์„ฑ์š”์†Œ ํด๋ž˜์Šค์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์ ‘๊ทผํ•˜๋ฏ€๋กœ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์Šต๋‹ˆ๋‹ค.

3. ์œ ์—ฐ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ

  • ์ƒ์†:
    • ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๋ณ€๊ฒฝ์ด ์ž์‹ ํด๋ž˜์Šค์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.
    • ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์— ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ์˜์กดํ•˜๊ฒŒ ๋˜๋ฉด, ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ปดํฌ์ง€์…˜:
    • ๊ตฌ์„ฑ์š”์†Œ์˜ ๋ณ€๊ฒฝ์ด ์ƒ๋Œ€์ ์œผ๋กœ ๋œ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.
    • ํด๋ž˜์Šค ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์•„ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค.

4. ๋‹คํ˜•์„ฑ ํ™œ์šฉ

  • ์ƒ์†:
    • ์ž์‹ ํด๋ž˜์Šค๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค ํƒ€์ž…์œผ๋กœ ์ทจ๊ธ‰๋  ์ˆ˜ ์žˆ์–ด ๋‹คํ˜•์„ฑ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ์˜ˆ์‹œ:

      ElectronicDevice device = new Smartphone();
      device.powerOn(); // ์ „์ž๊ธฐ๊ธฐ๊ฐ€ ์ผœ์กŒ์Šต๋‹ˆ๋‹ค.
  • ์ปดํฌ์ง€์…˜:
    • ๋‹คํ˜•์„ฑ๋ณด๋‹ค๋Š” ๊ธฐ๋Šฅ ํ™•์žฅ์ด๋‚˜ ์กฐํ•ฉ์— ์ค‘์ ์„ ๋‘ก๋‹ˆ๋‹ค.

4) ๐Ÿค” ์–ธ์ œ ์ƒ์†๊ณผ ์ปดํฌ์ง€์…˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ• ๊นŒ?

์ƒ์†์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ

  • ํด๋ž˜์Šค ๊ฐ„์— Is-a ๊ด€๊ณ„๊ฐ€ ๋ช…ํ™•ํ•  ๋•Œ.
  • ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๋™์ž‘์„ ๊ทธ๋Œ€๋กœ ๋ฌผ๋ ค๋ฐ›์•„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ๋™์ž‘์„ ํ™•์žฅํ•ด์•ผ ํ•  ๋•Œ.
  • ๋‹คํ˜•์„ฑ์„ ์ ๊ทน์ ์œผ๋กœ ํ™œ์šฉํ•˜์—ฌ ์ฝ”๋“œ์˜ ์œ ์—ฐ์„ฑ์„ ๋†’์ด๊ณ ์ž ํ•  ๋•Œ.

์ปดํฌ์ง€์…˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ

  • ํด๋ž˜์Šค ๊ฐ„์— Has-a ๊ด€๊ณ„๊ฐ€ ์žˆ์„ ๋•Œ.
  • ๊ธฐ๋Šฅ์„ ์žฌ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€๋งŒ, ๋ถ€๋ชจ ํด๋ž˜์Šค์™€ ๊ฐ•ํ•œ ๊ฒฐํ•ฉ์„ ํ”ผํ•˜๊ณ ์ž ํ•  ๋•Œ.
  • ๊ธฐ์กด ํด๋ž˜์Šค์˜ ์ผ๋ถ€ ๊ธฐ๋Šฅ๋งŒ ํ™œ์šฉํ•˜๊ฑฐ๋‚˜, ๋‚ด๋ถ€ ๊ตฌํ˜„์— ์˜์กดํ•˜์ง€ ์•Š๊ณ  ์•ˆ์ •์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ ์ž ํ•  ๋•Œ.

5) ์ƒ์†๊ณผ ์ปดํฌ์ง€์…˜์˜ ์žฅ๋‹จ์ 

์ƒ์†์˜ ์žฅ์ 

  • ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์ด ์‰ฝ์Šต๋‹ˆ๋‹ค.
  • ๋‹คํ˜•์„ฑ์„ ํ™œ์šฉํ•˜์—ฌ ์œ ์—ฐํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์žฌ์ •์˜ํ•˜์—ฌ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒ์†์˜ ๋‹จ์ 

  • ๋ถ€๋ชจ ํด๋ž˜์Šค์™€ ๊ฐ•ํ•œ ๊ฒฐํ•ฉ์ด ๋ฐœ์ƒํ•˜์—ฌ, ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๋ณ€๊ฒฝ์ด ์ž์‹ ํด๋ž˜์Šค์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.
  • ์ž˜๋ชป๋œ ์ƒ์† ๊ตฌ์กฐ๋Š” ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋–จ์–ด๋œจ๋ฆฌ๊ณ , ์ฝ”๋“œ์˜ ์•ˆ์ •์„ฑ์„ ํ•ด์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๋ถˆํ•„์š”ํ•œ ๊ธฐ๋Šฅ๊นŒ์ง€ ์ƒ์†๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ปดํฌ์ง€์…˜์˜ ์žฅ์ 

  • ํด๋ž˜์Šค ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์•„ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค.
  • ํ•„์š”ํ•œ ๊ธฐ๋Šฅ๋งŒ ์„ ํƒ์ ์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.
  • ๋‚ด๋ถ€ ๊ตฌํ˜„์— ์˜์กดํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ๊ตฌ์„ฑ์š”์†Œ ํด๋ž˜์Šค์˜ ๋ณ€๊ฒฝ์—๋„ ์•ˆ์ •์ ์ž…๋‹ˆ๋‹ค.

์ปดํฌ์ง€์…˜์˜ ๋‹จ์ 

  • ์ƒ์†์— ๋น„ํ•ด ๊ตฌํ˜„ํ•ด์•ผ ํ•  ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋‹คํ˜•์„ฑ์„ ํ™œ์šฉํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฉ”์„œ๋“œ ์œ„์ž„์ด ํ•„์š”ํ•˜์—ฌ ์ฝ”๋“œ๊ฐ€ ์žฅํ™ฉํ•ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€ ์˜ˆ์‹œ: ๋„ํ˜•(Drawing) ํ”„๋กœ๊ทธ๋žจ์—์„œ์˜ ์ƒ์†๊ณผ ์ปดํฌ์ง€์…˜

์ƒ์†์˜ ์˜ˆ์‹œ: Shape ํด๋ž˜์Šค์™€ Circle ํด๋ž˜์Šค

// ๋ถ€๋ชจ ํด๋ž˜์Šค: ๋„ํ˜•
abstract class Shape {
    public abstract void draw();
}

// ์ž์‹ ํด๋ž˜์Šค: ์›
class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("์›์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.");
    }
}
  • ์„ค๋ช…: Circle์€ Shape์˜ ์ผ์ข…์ด๋ฏ€๋กœ ์ƒ์†์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ปดํฌ์ง€์…˜์˜ ์˜ˆ์‹œ: Canvas ํด๋ž˜์Šค์™€ Pen ํด๋ž˜์Šค

// ๋…๋ฆฝ๋œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ ํด๋ž˜์Šค: ํŽœ
class Pen {
    public void setColor(String color) {
        System.out.println(color + " ์ƒ‰์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.");
    }

    public void drawLine() {
        System.out.println("์„ ์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.");
    }
}

// ์ปดํฌ์ง€์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค: ์บ”๋ฒ„์Šค
class Canvas {
    private Pen pen;

    public Canvas() {
        this.pen = new Pen();
    }

    public void drawShape(Shape shape) {
        pen.setColor("๊ฒ€์€์ƒ‰");
        shape.draw();
        pen.drawLine();
    }
}
  • ์„ค๋ช…: Canvas ํด๋ž˜์Šค๋Š” Pen ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋„ํ˜•์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
  • ๊ด€๊ณ„: Canvas๋Š” Pen์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, Shape ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.

โœจ ์ •๋ฆฌ

  • ์ƒ์†์€ is-a ๊ด€๊ณ„์ผ ๋•Œ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ํด๋ž˜์Šค ๊ฐ„์˜ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ํ˜•์„ฑํ•  ๋•Œ ๋ง์ด๋‹ค. ์ฆ‰, ํ•˜์œ„ ํด๋ž˜์Šค๊ฐ€ ์ƒ์œ„ ํด๋ž˜์Šค์˜ ์ง„์งœ ํ•˜์œ„ ํƒ€์ž…์ธ ๊ฒฝ์šฐ์—๋งŒ ์ƒ์†์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ๋‚ด๋ถ€ ๊ตฌํ˜„์— ์˜์กดํ•˜๊ฑฐ๋‚˜ ๊ฐ•ํ•œ ๊ฒฐํ•ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค.
  • ์ปดํฌ์ง€์…˜์€ Has-a ๊ด€๊ณ„๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ์„ ์œ ์—ฐํ•˜๊ฒŒ ํ™•์žฅํ•˜๊ณ  ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ปดํฌ์ง€์…˜๊ณผ ์œ„์ž„์„ ์‚ฌ์šฉํ•˜๋ฉด ์ƒ์†์˜ ๋‹จ์ ์„ ํ”ผํ•˜๋ฉด์„œ ์œ ์—ฐํ•˜๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์•„ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•˜์ง€๋งŒ, ๋‹คํ˜•์„ฑ ํ™œ์šฉ์ด ์ œํ•œ์ ์ผ ์ˆ˜ ์žˆ๋‹ค.
  • ๋ž˜ํผ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ์กด ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์— ์˜์กดํ•˜์ง€ ์•Š๊ณ ๋„ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํŠนํžˆ, ์ƒ์œ„ ํด๋ž˜์Šค์— ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜๋”๋ผ๋„ ํ•˜์œ„ ํด๋ž˜์Šค์˜ ๋™์ž‘์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.

์ฐธ๊ณ  ๊ธ€

Footnotes

  1. ์ž๊ธฐ์‚ฌ์šฉ(self-use)์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

    ์ž๊ธฐ์‚ฌ์šฉ(self-use)์€ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ํด๋ž˜์Šค ๋‚ด์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ๊ฐ™์€ ํด๋ž˜์Šค์˜ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ๋“ค์ด ์„œ๋กœ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

    ์˜ˆ์‹œ๋กœ ์ดํ•ดํ•˜๊ธฐ

    ์˜ˆ๋ฅผ ๋“ค์–ด, HashSet ํด๋ž˜์Šค์—์„œ addAll() ๋ฉ”์„œ๋“œ๊ฐ€ add() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค๋ฉด, ์ด๋Š” addAll() ๋ฉ”์„œ๋“œ๊ฐ€ add() ๋ฉ”์„œ๋“œ๋ฅผ ์ž๊ธฐ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    java์ฝ”๋“œ ๋ณต์‚ฌpublic class HashSet<E> implements Set<E> {
        // ...
    
        public boolean addAll(Collection<? extends E> c) {
            boolean modified = false;
            for (E e : c) {
                if (add(e)) { // ์—ฌ๊ธฐ์„œ add() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
                    modified = true;
                }
            }
            return modified;
        }
    
        public boolean add(E e) {
            // ์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋กœ์ง
        }
    
        // ...
    }
    

    ์œ„ ์ฝ”๋“œ์—์„œ ๋ณด๋“ฏ์ด, addAll() ๋ฉ”์„œ๋“œ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ add() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ปฌ๋ ‰์…˜์˜ ๊ฐ ์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” addAll()์ด add()๋ฅผ ์ž๊ธฐ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    ์™œ ์ž๊ธฐ์‚ฌ์šฉ์ด ๋ฌธ์ œ๊ฐ€ ๋ ๊นŒ์š”?

    ์ž๊ธฐ์‚ฌ์šฉ์€ ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„ ๋ฐฉ์‹์— ํ•ด๋‹นํ•˜๋ฉฐ, ์™ธ๋ถ€์— ๊ณต๊ฐœ๋˜์ง€ ์•Š์€ ๊ตฌํ˜„ ์„ธ๋ถ€์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ์ž๊ธฐ์‚ฌ์šฉ ์—ฌ๋ถ€์— ์˜์กดํ•˜์—ฌ ๋™์ž‘์„ ๊ตฌํ˜„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    1. ๋‚ด๋ถ€ ๊ตฌํ˜„ ๋ณ€๊ฒฝ ์‹œ ๋ฌธ์ œ ๋ฐœ์ƒ:
      • ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์ด ๋ณ€๊ฒฝ๋˜๋ฉด ์ž์‹ ํด๋ž˜์Šค์˜ ๋™์ž‘์ด ์˜๋„์น˜ ์•Š๊ฒŒ ๋ณ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      • ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ๋ฒ„์ „์—์„œ HashSet์˜ addAll()์ด ๋” ์ด์ƒ add()๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ง์ ‘ ์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋„๋ก ๊ตฌํ˜„์ด ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด, ์ž์‹ ํด๋ž˜์Šค์—์„œ add()๋ฅผ ์žฌ์ •์˜ํ•˜์—ฌ ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ ๋ถ€๋ถ„์ด ๋” ์ด์ƒ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    2. ์ƒ์œ„ ํด๋ž˜์Šค์˜ ์‚ฌ์–‘์— ์—†๋Š” ๋™์ž‘์— ์˜์กด:
      • HashSet์˜ ๊ณต์‹ ๋ฌธ์„œ๋‚˜ API ์‚ฌ์–‘์—๋Š” addAll()์ด add()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋œ๋‹ค๋Š” ๋‚ด์šฉ์ด ์—†์Šต๋‹ˆ๋‹ค.
      • ์ฆ‰, ์ด๋Š” ๊ตฌํ˜„ ์„ธ๋ถ€์‚ฌํ•ญ์ด๋ฉฐ, ์™ธ๋ถ€์—์„œ ์•Œ ์ˆ˜ ์—†๊ณ  ์˜์กดํ•ด์„œ๋„ ์•ˆ ๋˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.
    3. ์ฝ”๋“œ์˜ ์œ ์ง€๋ณด์ˆ˜์„ฑ ๋ฐ ์•ˆ์ •์„ฑ ์ €ํ•˜:
      • ์ƒ์œ„ ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์— ์˜์กดํ•˜๋ฉด, ์ƒ์œ„ ํด๋ž˜์Šค์˜ ์—…๋ฐ์ดํŠธ๋‚˜ ์ˆ˜์ •์— ์ทจ์•ฝํ•ด์ง‘๋‹ˆ๋‹ค.
      • ์ด๋Š” ์ฝ”๋“œ์˜ ์•ˆ์ •์„ฑ์„ ์ €ํ•ดํ•˜๊ณ , ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋ฒ„๊ทธ๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    โ†ฉ
  2. InstrumentedHashSet์€ ์ž๋ฐ”์—์„œ HashSet ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜์—ฌ ์ถ”๊ฐ€๋œ ์›์†Œ์˜ ์ˆ˜๋ฅผ ์„ธ๊ธฐ ์œ„ํ•œ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค๋Š” ์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋™์ž‘์„ ๊ณ„์ธก(instrument)ํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค.

    ์™œ InstrumentedHashSet์„ ๋งŒ๋“ค์—ˆ์„๊นŒ?

    HashSet์€ ์ง‘ํ•ฉ(Set) ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์ด๋ฉฐ, ์›์†Œ์˜ ์ถ”๊ฐ€, ์‚ญ์ œ ๋“ฑ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ HashSet ์ž์ฒด๋Š” ๋ช‡ ๊ฐœ์˜ ์›์†Œ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๋Š”์ง€ ์ถ”์ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

    ์–ด๋–ค ์ƒํ™ฉ์—์„œ๋Š” ์ง‘ํ•ฉ์— ์›์†Œ๊ฐ€ ๋ช‡ ๋ฒˆ ์ถ”๊ฐ€๋˜์—ˆ๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ค‘๋ณต๋œ ์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•œ ํšŸ์ˆ˜๊นŒ์ง€ ํฌํ•จํ•˜์—ฌ ์ด ๋ช‡ ๋ฒˆ์˜ ์ถ”๊ฐ€ ์—ฐ์‚ฐ์ด ์žˆ์—ˆ๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์ด๋ฅผ ์œ„ํ•ด HashSet์„ ์ƒ์†ํ•˜์—ฌ InstrumentedHashSet์„ ๋งŒ๋“ค๊ณ , add()์™€ addAll() ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜์—ฌ ์›์†Œ๊ฐ€ ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ์นด์šดํ„ฐ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ๋ฐฉ์‹์„ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. โ†ฉ