Clean Code Oop
[TOC]
OOP
์ฝ๋ 1๊ฐ์ ๋ผ์ธ์ ๊ณ ์น๋ฉด 3๊ฐ์ ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ๋ค.
ํ๋ก๊ทธ๋๋ฐ์ ์งค ๋ ๊ณํํ๊ณ ์์ฑํ๋ ์ฝ๋์ ๊ทธ๋ ์ง ์๊ณ ์์ฑํ๋ ์ฝ๋๋ ์์ ์๊ฐ์ ๋ค๋ก ๊ฐ์๋ก ์ฐจ์ด๊ฐ ๋๋ค.
SW๋ ์์ฑํ๊ฒ ๋๋ฉด ์ต์ 10๋ฒ ์ด์ ์ฝํ๋ค.
์ฐ๋ฆฌ๋ ์ด๋ฅผ ํตํด ์ ์ ์๋ฏ์ด, ํ๋ก๊ทธ๋จ์ด ๋์๊ฐ๋ ๊ฒ์ ์ด์ ์ ๋ง์ถ์ง ๋ง๊ณ ์ด๋ป๊ฒ ํ๋ฉด โ์ฝ๊ธฐโ ์ข์ ์ฝ๋๋ฅผ ์ง๋์ง์ ์๊ฐ์ ํฌ์ํ๊ณ ๊ณํํด์ผํ๋ค.
์ OOP์ผ๊น?
๋ฐ์ดํฐ๊ฐ ํ๊ณณ์ ๋ชจ์ฌ์ ธ์๋, ๊ฒฐํฉ๋๊ฐ ๋ฎ๊ณ ์์ง๋๊ฐ ๋์ ์ฝ๋์ด๋ค. (์ค๊ณX)
์ด๋ฐ ์ฝ๋๋ ๋ฐ์ดํฐ๊ฐ ํ์ํด์ ๊ธฐ์กด๊ฒ์ ๋ณต์ฌ, ๋ถ์ฌ ๋ฃ์๋ ์ค๋ฅ๊ฐ ๋ฐ์์ ์ด๋์์ ์ค๋ฅ๊ฐ ๋๊ณ ์๋์ง ์ ์ง, ๋ณด์๊ฐ ํ๋ค๋ค
๊ฐ ๊ฐ์ฒด๋ง๋ค ์์กด์ฑ ์ฆ ๋ค๋ฅธ ๊ฐ์ฒด์ ๋ํด์ ์กด์ฌ๋ ๋ชจ๋ฅด๊ฒ ์ฝ๋๋ฅผ ์ง๊ฒ ๋ ๊ฒฝ์ฐ ์์ ์ด ํ์ํ๊ฑฐ๋ ์ถ๊ฐ๊ฐ ํ์ํ ๊ฒฝ์ฐ ์์ค๋ฅผ ์ ์ฒด์ ์ผ๋ก ์์ ํด์ผํ๋ ๊ธฐ์กฑ์ ๋ฐฉ์๊ณผ๋ ๋ค๋ฅด๊ฒ ํ์ํ ๋ถ๋ถ๋ง ์์ ์ด ๊ฐ๋ฅํ๋ค.
๊ฐ์ฅ ์ด์์ ์ธ ๊ฒฐํฉ๋๋ ๋๋, ์์ง๋๋ ๋ฎ์ ํ๋ก๊ทธ๋จ์ด๋ค.
์ด์์ ์ธ ๊ฐ์ฒด์งํฅ ์ค๊ณ๊ณผ์
์ฐ๋ฆฌ๊ฐ ์ถ๊ตฌํด์ผ ํ๋ ์ค๊ณ ๋ฐฉํฅ์ ๋ชจ๋ ๊ธฐ๋ฅ์ ํ ๊ณณ์ ์ ๋ถ ๋ฃ์ด์ ๊ฐ๋ฐํ๋ ์์ ๋ง์ฝ๋ฉ์ด ์๋๋ผ, ๊ฐ ๊ธฐ๋ฅ๋ง๋ค ์ถ์ถ์ ํด์ ๊ฒฐํฉ๋๋ฅผ ๋์ถฐ์ฃผ๋ ๊ณผ์ ์ ๊ฑฐ์ณ ๊ฐ๋ฉด์ ๋ฆฌํํ ๋ง์ ํด์ผํ๋ค.
๋ฌผ๋ก ์ฒ์๋ถํฐ, ์๋ฒฝํ ์ค๊ณ๋ฅผ ํ๋ฉด ์ข์ง๋ง, ๋ฐฑ์ง์์ ์๋ฒฝํ ํ๋ก๊ทธ๋จ ์ค๊ณ๋ฅผ ๋ง๋ค์ด๋ด๋ ๊ฒ์ ๋๋ฌด ์ด๋ ค์ด ์ผ์ด๋ค.
- ๊ธฐ๋ฅ์ ์ ๊ณตํ ๊ฐ์ฒด ํ๋ณด ์ ๋ณ
- ๋ด๋ถ์์ ํ์ํ ๋ฐ์ดํฐ์ ๋ณ
- ํด๋์ค ๋ค์ด์ด๊ทธ๋จ
- ์ ์ ์ค๊ณ
- ์์์ ๋ง๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ ํด๋์ค๊ฐ์ ๋ฉ์์ง ํ๋ฆ ์ฐ๊ฒฐ
- ์ปค๋ฎค๋์ผ์ด์ ๋ค์ด์ด๊ทธ๋จ
- ์ํ์ค ๋ค์ด์ด๊ทธ๋จ
- ๋์ ์ค๊ณ
์ ๊ทธ๋ฆผ์ฒ๋ผ FlowController์ ๋ชจ๋ ์ญํ์ ์ง์ด ๋ฃ์ง ์๊ณ ๋ชจ๋ ๊ฐ ์ญํ๋ง๋ค ํด๋์ค๋ฅผ ๋ง๋ ๋ค.
์์ ๊ทธ๋ฆผ์ด ์์ฑ ๋์ผ๋ฉด, ์๋ ๊ทธ๋ฆผ์ฒ๋ผ ๋ฐ์ดํฐ์ ํ๋ฆ์ ๊ณํํ๋ค.
์์์ฒ๋ผ FlowController๋ ๊ฐ ์ญํ ๋ณ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด์ฃผ๋ ์ญํ์ด๋ค.
Encapsulation(์บก์ํ)
๊ฐ์ฒด์งํฅ์์ ๋ํ์ ์ธ ํน์ฑ์ค์ ํ๋์ธ ์บก์ํ๋ ๋ด๋ถ์ ์ผ๋ก ์ด๋ป๊ฒ ๊ตฌํํ๋์ง๋ฅผ ๊ฐ์ถฐ์ ๋ด๋ถ์ ๋ณ๊ฒฝ(๋ฐ์ดํฐ, ์ฝ๋)์ด Client๊ฐ ๋ณ๊ฒฝ ๋์ง ์๋๋กํ๋ค.
์ด๋ ์ฝ๋ ๋ณ๊ฒฝ์ ๋ฐ๋ฅธ ๋น์ฉ์ ์ต์ํ ์์ผ์ค๋ค.
์ ์ฐจ์งํฅ์ ์๊ตฌ์ฌํญ์ด ๋ณ๊ฒฝ ๋ ๋๋ง๋ค ๋ฐ์ดํฐ์ ๊ตฌ์กฐ๊ฐ ๋ณ๊ฒฝ ๋์ด์ผํ๊ณ ์ด๋ ๋ชจ๋ Client, Test์ ์์ ์ด ํ์ํด ์ง๊ธฐ ๋๋ฌธ์ ์ ์ง๋ณด์์ฑ์ด ๋จ์ด์ง๋ค.
How? Tell! Donโt ask!!
์บก์ํ๊ฐ ์๋์๋ค๋ ๊ฒ์ ๋ฐ์ดํฐ๋ฅผ ์์๊ณ ์๋ ๊ฐ์ฒด๊ฐ ์๋ค๋ ๊ฑฐ๊ณ ๊ทธ ๊ฐ์ฒด์๊ฒ ๊ธฐ๋ฅ์ ์ํํ๊ฒ ํด์ผ ํ๋ค. ์ง์ ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ฒญํด์ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๋ฌด์์ด ์๋ ์ด๋ป๊ฒ ์ ์ํ๋ คํ๋ ๊ฒ์ด๋ค.
ex. If(member.getExpiredData().getTime() < System.currentTimeMillis){โฆ}
if(member.isExpired()){โฆ}
์ด๋ฐ ์์ผ๋ก ๋ช ๋ น๋ง ๋ด๋ฆฌ๊ฒ ๊ฐ์ฒด๋ฅผ ์ ์ ํด์ผํ๋ค.
์์
package procedural;
import org.junit.Assert;
import org.junit.Test;
public class ProceduralStopWatchTest {
private long expectedElapsedTime = 100l;
@Test
public void
should_return_elapsed_milli_second() {
ProceduralStopWatch stopWatch = new ProceduralStopWatch();
stopWatch.startTime = System.currentTimeMillis(); // start time in millis
doSomething();
stopWatch.stopTime = System.currentTimeMillis(); // stop time in millis
long elapsedTime = stopWatch.getElapsedTime();
Assert.assertEquals(elapsedTime, expectedElapsedTime);
}
private void doSomething() {
try {
Thread.sleep(expectedElapsedTime);
} catch (InterruptedException e) {
}
}
}
package procedural;
public class ProceduralStopWatch {
public long startTime;
public long stopTime;
public long getElapsedTime() {
return stopTime - startTime;
}
}
์ ์ฝ๋๋ ์์ ์๊ฐ๋ถํฐ ๊ฒฝ๊ณผ๋ ์๊ฐ์ ๊ตฌํ๋ ์ ์ฐจ์งํฅ์ ์ธ ํ๋ก๊ทธ๋จ์ด๋ค.
์ฌ๊ธฐ์ ๋๋ ธ์ธ์ปจ๋๋ฅผ ์ถ๊ฐํด๋ฌ๋ผ๋ ์๊ตฌ์ฌํญ์ด ๋ค์ด์๋ค. ๊ฐ๋ฐ์๋ ์ด ์ ์ฐจ์งํฅ์ ์ธ ์ฝ๋์์ ๊ธฐ๋ฅ์ ์ถ๊ฐ๋ฅผ ํด์ผํ๋ค.
package procedural;
import org.junit.Assert;
import org.junit.Test;
public class ProceduralStopWatchTest {
private long expectedElapsedTime = 100l;
@Test
public void
should_return_elapsed_nano_seconds() {
ProceduralStopWatch stopWatch = new ProceduralStopWatch();
stopWatch.startNanoTime = System.nanoTime(); // start time in nanos
doSomething();
stopWatch.stopNanoTime = System.nanoTime(); // stop time in nanos
long elapsedTime = stopWatch.getElapsedNanoTime();
Assert.assertEquals(elapsedTime, expectedElapsedTime);
}
private void doSomething() {
try {
Thread.sleep(expectedElapsedTime);
} catch (InterruptedException e) {
}
}
}
package procedural;
public class ProceduralStopWatch {
public long startTime;
public long stopTime;
public long startNanoTime;
public long stopNanoTime;
public long getElapsedTime() {
return stopTime - startTime;
}
public long getElapsedNanoTime() {
return stopNanoTime - startNanoTime;
}
}
์ฐ๋ฆฌ๊ฐ ์๋ก์ด ํ๋ก๊ทธ๋จ ์ฝ๋์์ ๋ด์ผํ ๋ถ๋ถ์ ์ ์ฐจ์งํฅ์์ ์๋ก์ด ์๊ตฌ์ฌํญ์ด ์๊ธฐ๋ฉด, ๊ฐ๋ฐ์๋ ํ๋ก๊ทธ๋จ์ ์๊ตฌ์ฌํญ์ ๋ง๊ฒ ์ฌ์์ ํ๋ค. ์ด๋ ๊ฒ ๋๋ฉด ๊ธฐ์กด์ ์๋ ํ๋ก๊ทธ๋จ์ ์ฌ๋ผ์ง๊ณ ์๋ก์ด ํ๋ก๊ทธ๋จ์ด ์๊ฒผ๋ค. ์๊ตฌ์ฌํญ์ ๋ง๊ฒ ํ๋ก๊ทธ๋จ์ ์ฌ์ฌ์ฉ ์๊ณ ํ๋ก๊ทธ๋จ์ ์๋ก ๋ง๋ค๊ฒ ๋๋ ๊ฒ์ด๋ค.
package objective;
import org.junit.Assert;
import org.junit.Test;
public class ObjectiveStopWatchTest {
private long expectedElapsedTime = 100l;
@Test
public void
should_return_elapsed_millis() {
ObjectiveStopWatch stopWatch = new ObjectiveStopWatch();
stopWatch.start();
doSomething();
stopWatch.stop();
Time time = stopWatch.getElapseTime();
Assert.assertEquals(time.getMilliTime(), expectedElapsedTime);
}
private void doSomething() {
try {
Thread.sleep(expectedElapsedTime);
} catch (InterruptedException e) {
}
}
}
package objective;
public class ObjectiveStopWatch {
private long startTime;
private long stopTime;
public void start() {
startTime = System.nanoTime();
}
public void stop() {
stopTime = System.nanoTime();
}
public Time getElapseTime() {
return new Time(stopTime - startTime);
}
}
package objective;
public class Time {
private long nano;
public Time(long nano) {
this.nano = nano;
}
public long getMilliTime() {
return (long) (nano / Math.pow(10, 6));
}
}
์ ์ฝ๋๋ ๊ฐ์ฒด์งํฅ์ ์ธ ์ค๊ณ๋ก ๋ง๋ค์ด์ง ๊ฒฝ๊ณผ์๊ฐ ๊ตฌํ๋ ํ๋ก๊ทธ๋จ์ด๋ค. ์ด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํด์ฃผ๋ Time์ด๋ผ๋ ํด๋์ค๋ฅผ ๋ฐ๋ก ๋บ๋ค.
package objective;
import org.junit.Assert;
import org.junit.Test;
public class ObjectiveStopWatchTest {
private long expectedElapsedTime = 100l;
@Test
public void
should_return_elapsed_millis() {
ObjectiveStopWatch stopWatch = new ObjectiveStopWatch();
stopWatch.start();
doSomething();
stopWatch.stop();
Time time = stopWatch.getElapseTime();
Assert.assertEquals(time.getNanoTime(), expectedElapsedTime);
}
private void doSomething() {
try {
Thread.sleep(expectedElapsedTime);
} catch (InterruptedException e) {
}
}
}
package objective;
public class Time {
private long nano;
public Time(long nano) {
this.nano = nano;
}
public long getMilliTime() {
return (long) (nano / Math.pow(10, 6));
}
public long getNanoTime() {
return nano;
}
}
๊ธฐ์กด ์ฝ๋์์ ๋๋ ธ์ธ์ปจ๋ ๋จ์๋ก ๊ฒฝ๊ณผ๋ ์๊ฐ์ ๋ณผ ์์๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ค. ์ ์ฐจ์งํฅ์์๋ ๋๋ ธ์ธ์ปจ๋๋ฅผ ๋ฐ๋ ๋ณ์๋ ์๋ก ์ถ๊ฐํ๊ณ , ์ด์ ๋ง๋ ํจ์๋ ์๋ก ๋ง๋ค๊ณ , ๋๋ ธ์ธ์ปจ๋์ ๋ง๊ฒ ํ ์คํธ ํ๋ก๊ทธ๋จ์ฝ๋๋ ์์ ํด์ผ ํ๋ค. ์์๋ ์์ฃผ ๊ฐ๋จํ ํ๋ก๊ทธ๋จ์ด์์ง๋ง, ๊ท๋ชจ๊ฐ ํฌ๊ฑฐ๋, ๋ณต์กํ ํ๋ก๊ทธ๋จ์ผ ๊ฒฝ์ฐ์๋ ํ, ๋์ค์ด ์๋๋ผ ์ ๋ฐ์ ์ธ ๋ถ๋ถ์ ๊ณ ์น๊ณ , ๋ง์ ๋ฒ๊ทธ๋ฅผ ์ก๋๋ผ ์๊ฐ์ ํ๋นํด์ผํ๋ค.
๊ฐ์ฒด / ํด๋์ค
์ข์ ์ฝ๋๋ ๊ฐ ์ญํ์ ๋ง๊ฒ ์๋ง์ ์ด๋ฆ๊ณผ ์ด๋ฆ์ ๋ง๋ ๊ธฐ๋ฅ์ด๋ค.
๊ทธ๋ผ ์ฐ๋ฆฌ๋ ์ด๋ฆ์ ์ด๋ป๊ฒ ์ง๋๋์ ๋ง์ ์๊ฐ์ ํฌ์ ํด์ผํ๋ค. ๊ฐ์ฒด, ํด๋์ค๋ ์ด๋ป๊ฒ(How)๋ก ์ ์ํ์ง ์๊ณ , ๋ฌด์(What)์ผ๋ก ์ ์ํด์ผ ํ๋ค. ๊ฐ์ฒด์ ํด๋์ค๋ ์ฑ ์์ ๊ฐ์ง๋ ์ญํ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
์๋ฅผ ๋ค์ด SamsungSmartPhone์ด ์๋ SmartPhone์ด ๋์ด์ผ ํ๊ณ , ๋์๊ด ์ฌ์๋ผ๋ ๊ฐ์ฒด๋ฅผ ๋ง๋ ๋ค๋ฉด, ์ฑ ๊ด๋ฆฌ, ๋์๊ด ๊ด๋ฆฌํ๋ ์ฑ ์์ด ์ฌ์๋ผ๋ ์ญํ์ ์ํด ์๋ค.
- Object
- Role
- Responsibility
Polymorphism(๋คํ์ฑ)
ํ ๊ฐ์ฒด๋ ์ฌ๋ฌ๊ฐ์ง(poly) ๋ชจ์ต(morph)์ ๊ฐ์ง ์ ์๋ค.
ZetMotorcycle zm = new ZetMotorcycle();
Motorcycle mc = zm;
ZetEngine ze = zm;
Zetmotorcycle ๊ฐ์ฒด๋ Motorcycle, ZetEngine ํด๋์ค ์ด๋ ๋ชจ์ต์ด๋ ์ง ๊ฐ์ง์๊ฐ ์๊ณ , Motorcycle์์๋ start(), ZetEngine์์๋ zetOn()๋ฅผ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
๋ณธ ๊ฐ์ข๋ ๊ฐ์ฒด์งํฅ์์ ๊ฐ์ฅ ํฐ ํน์ฑ์ธ ์ฌ์ฌ์ฉ์ ์ํผํด๋์์์ ์์์ ๋ฐ์ ์ฌ์ฌ์ฉ ํ๋ ๊ฒ์ด์๋ ์ธํฐํ์ด์ค๋ฅผ ์ด์ฉํด์ ํด์ผํ๋ค๊ณ ๊ฐ์กฐ ํ๋ค.
์ฌ์ฌ์ฉ์ด๋ผ๋ ๊ฒ์ ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐ ํ ๋ ๊ธฐ์กด์ ์ง๋์ ๋ก์ง์ด ์๋ก์ด ๊ธฐ๋ฅ์ผ๋ก ์ธํด ๊ตฌํ์ฒด์์๋ ๋ณ๊ฒฝ์ด ๋ผ๋, ๋ณ๊ฒฝ์ด ๋์ด์๋ ์๋๋ค.
์ด๋ ๊ฐ์ฒด์์๋ ์ง Interface์ ๋ก์ง์ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์์ด์ผํ๋ค.
๊ฐ๋ฐ์๋ ์์ธํ ๊ธฐ๋ฅ ๊ตฌํ์ ๋น ์ง๋ค ๋ณด๋ฉด ์์ ์์ค์์์ ์ค๊ณ๋ฅผ ๋์น๊ธฐ ์ฝ์ง๋ง, ์ถ์ํ๋ฅผ ํตํด์ ์์ ์์ค์์์ ์ค๊ณ๋ฅผ ํ๋๋ฐ ๋์์ ์ป์ ์ ์๋ค.
Abstract(์์)
์์์ ๋ฐ์์ ์ฌ์ฉํ๊ณ ์๋ ๋ค์์ ์๋ธ ํด๋์ค๊ฐ ์๋ค๊ณ ๊ฐ์ ํ์, ๋ง์ฝ ์ํผ ํด๋์ค์์ ๋ณ๊ฒฝ์ด ์ผ์ด๋ ๊ฒฝ์ฐ ์ํผ ํด๋์ค์์ ์์๋ฐ์ ๋ค์์ ์๋ธ ํด๋์ค์ ํฐ ์ํฅ์ ๋ฏธ์น๋ค.
์๋ฐ์์๋ ๋ค์ค ์์ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง ์๊ธฐ ๋๋ฌธ์ ์ํผ ํด๋์ค์ ์๋ ์๋ง์ ๊ธฐ๋ฅ ์ค์์ ๋จ 1๊ฐ์ง๋ง ์ฌ์ฉ ํ ์ ์๋ค. ์ ํ์ง๋ 1๊ฐ์ง ๊ธฐ๋ฅ๋ง ์์์ ๋ฐ๊ณ ๋ค๋ฅธ ํ๊ฐ๋ ๊ตฌํํ๋ ์๋ฐ์ ์๋ค. ์ ์ํฉ์์์ ๋ฌธ์ ์ ์ ์ด๋ฏธ ๋ง๋ค์ด๋์ ํด๋์ค๋ฅผ ์ฌ์ฉํ์ง ๋ชปํ๊ณ ์๋ก ๋ง๋ค์๊ธฐ ๋๋ฌธ์ ํด๋์ค์ ๊ฐ์๊ฐ ๋ถํ์ํ๊ฒ ๋์ด๋๋ค.
package inheritance;
import java.util.ArrayList;
public class LuggageCompartment extends ArrayList<Luggage> {
private int restSpace;
public LuggageCompartment(int restSpace) {
this.restSpace = restSpace;
}
@Override
public boolean add(Luggage luggage) {
this.restSpace -= luggage.getSize();
super.add(luggage);
return false;
}
public boolean canContain(Luggage luggage) {
return this.restSpace > luggage.getSize();
}
public void extract(Luggage luggage) {
this.restSpace += luggage.getSize();
super.remove(luggage);
}
}
์ ํ๋ก๊ทธ๋จ์ ์ํ๋ฌผ์ ์ ์ฌํ ๋ ์ฌ์ ๊ณต๊ฐ์ ์๋ ค์ฃผ๋ ํ๋ก๊ทธ๋จ์ด๋ค.
๊ฐ๋ฐ์์ ์๋๋ ์ํ๋ฌผ์ ์ ์ฌํ๋ฉด, ์ฌ์ ๊ณต๊ฐ์ ์ค์ด๋ค๊ณ ์ถํํ๋ฉด, ์ฌ์ ๊ณต๊ฐ์ ํฌ๊ธฐ๋ฅผ ๋๋ฆฌ๋ ์์ด๋ค.
package inheritance;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class LuggageCompartmentTest {
private LuggageCompartment lc;
@Before
public void setUp() {
lc = new LuggageCompartment(11);
}
@Test
public void
should_update_restSpace() {
Luggage luggage = new Luggage(11, 10);
if(lc.canContain(luggage)) {
lc.add(luggage);
Assert.assertEquals(lc.canContain(luggage), false);
}
lc.remove(luggage);
Assert.assertEquals(lc.canContain(luggage), true);
}
}
ํ์ง๋ง, ์ ๊ฐ๋ฐ์์ ์๋์๋ ๋ค๋ฅด๊ฒ, extractํจ์๋ฅผ ์ฌ์ฉ์ง ์๊ณ ArrayList ํด๋์ค์ ์๋ removeํจ์์ ๋ฐ๋ก ์ ๊ทผํ์ฌ ์ถํ๋ฅผ ํ๋ ๋ฐ๋์ ๋น์ง๋์ค ๋ก์ง์ด ๊นจ์ ธ๋ฒ๋ฆฌ๋ ์ํฉ์ด ๋ฐ์ํ๋ค.
๊ฐ๋จํ ํด๊ฒฐ ์ฑ ์ ArrayList๋ฅผ ์์ ๋ฐ์ง ์๊ณ , ํจ์๋ฅผ ๋ง๋ค๋ฉด ์ฌ์ฉ์๋ ArrayList removeํจ์๋ฅผ ์ ๊ทผํ์ง ๋ชปํ๋ค.
์ด๋ฐ์์ผ๋ก ๋ฌด์กฐ๊ฑด ์์์ ์ฐ๋ฉด ์ข์ ๊ฒ์ด ์๋ composition์ ๋จผ์ ํ๊ณ delegation์ ํ๋ ํ์์ ํ๋ก๊ทธ๋จ์ ์ง๋ฉด ์ ์ฐ์ฑ์ด ์ฆ๋ ๋๊ธฐ ๋๋ฌธ์ ์ ์ง๋ณด์์ ์ ํฉํ ํ๋ก๊ทธ๋จ์ด ๋๋ค.
์ฐธ์กฐ
- ๋ฐฑ๋ช ์์ ํด๋ฆฐ์ฝ๋ Youtube ๊ฐ์ข