๊ฐ๋ฐ ๋ฉค๋ฒ, ํนํ ์ ๊ท ์ฐธ๊ฐ์๊ฐ ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ ์ฝ๊ฒ ์ง๋ ๊ฒ์ด ์ค์ํ๊ณ , ๋ณต์ก์ฑ์ด ์ค์ด๋ค์ด ๋ฒ๊ทธ๋ฅผ ์ค์ด๋ ํจ๊ณผ๋ ์์ด ์์ฐ์ฑ์ผ๋ก ์ง๊ฒฐ๋๋ค. ์ดํดํ๊ธฐ ์ฌ์ด ์ฝ๋๋ ์ฅ๊ธฐ์ ์ผ๋ก ๋ณด๊ณ ์ ์งํ๊ธฐ ์ฌ์ ๊ธฐ์ ์ ๋ถ์ฑ๋ฅผ ์ค์ฌ ์ค๋ค. ๊ทธ๋์ ๊ฐ๋ฐ์๋ ๊ฐ๋ ์ฑ ์๋ ์ฝ๋๋ฅผ ์ง๋ ๊ฒ์ด ๋งค์ฐ ์ค์ํ ์ผ์ด๋ผ๊ณ ์๊ฐํด์ผ ํ๋ค.
ํ๋ก๊ทธ๋๋ฐ ๊ด์
1. ๋ถํ์ํ ์ฝ๋๋ ๋ง๋ค์ง ์๋๋ค.
์ฝ๋๋ฅผ ์ฝ๋ ์์ ์ค์ด๋ ๊ฒ ์ ์ผ ์ข๋ค. The XP 2002 Conference์์ Standish Group์ ํ์ฅ์ธ Jim Johnson์ ๊ธฐ์กฐ ๊ฐ์ฐ "ROI, It's Your Job"์์ ์๊ฐ์ฒ๋ผ ์ ํ์ ์ํ ๋ง๋ค์ด์ง ๊ธฐ๋ฅ์ 64%๊ฐ ๊ฑฐ์ ์ฌ์ฉ๋์ง ์๋๋ค๊ณ ํ๋ค. Feature๋ฅผ ํ์ํ ๊ฒ๋ง ์ค๊ณํ๋ ๊ฒ๋ ์ฝ๋์์ ์ค์ด๋ ์ผ์ด๊ณ , ์ฝ๋๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฏธ๋์ ํ์ํ๋ค๊ณ ๋ฏธ๋ฆฌ ๋ง๋ค ํ์๋ ์๋ค. ๊ธฐ๋ฅ, ์ฝ๋๋ ํ์ํ๊ฒ ๋์์ ๋์ ๊ตฌํ๋์ด์ผ ํ๊ณ , ์ฅ๋ ํ์ํ๊ฒ ๋๋ ์ด์ ๋ก ๊ตฌํ๋์ด์๋ ์๋๋ค.
์ข์ ํ๋ก๊ทธ๋๋จธ๋ ์ข์ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค. ํ๋ฅญํ ํ๋ก๊ทธ๋๋จธ๋ ์ฝ๋๋ฅผ ์์ฑํ์ง ์์ต๋๋ค.
2. ์ด์คํ ์ต์ ํ๋ ํ์ง ์๋๊ฒ ๋ซ๋ค.
Knuth๊ฐ ์์ฑํ "Computer programming as an art" ๋ ผ๋ฌธ์ ๋ณด๋ฉด "Premature optimization is the root of all evil"์ด๋ ๋ง์ด ๋์ค๋๋ฐ, ํจ๊ณผ๊ฐ ์ ์ ์ต์ ํ๋ ํด์๋ ์๋๋ค๊ณ ์ฃผ์ฅํ๊ณ ์๋ค. ์ฌ๋ฐ๋ฅด๊ฒ ๋์ํ๊ณ ์๋ ํจ๊ณผ๊ฐ ์ ์ ์ฝ๋์ ์ต์ ํ๋ฅผ ํ ๊ฒฝ์ฐ, ์์คํ ์ ๋์์ ์ ํ ๋ณํ์ง ์์ง๋ง, ๊ฐ๋ฐ ๋น์ฉ์ด ๋ค์ด๊ฐ๋ ๋ฌธ์ ์ ๋ํด์๋ ๊ณ ๋ฏผ์ ํด๋ด์ผ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ์ ๋์์ ๋ ๋ค๋ฅธ ์ฝ๋๋ฅผ ๋ง๋ค์ด ๋ค๋ฅธ ์ฌ๋๋ค์ด ๊ทธ ์ฝ๋๋ฅผ ์ฐธ์กฐํ๋ค๋ฉด ๋ ์ฝ๋ ๋น์ฉ์ ๋ฐ์์ํจ๋ค.
3. SOLID(๋จ์ผ ์ฑ ์์ ์์น)
ํด๋์ค๋ ๋จ์ผ ์ฑ ์์ ๊ฐ์ ธ์ผ ํ๋ค. ์๋ ๊ทธ๋ฆผ ์ผ์ชฝ์ฒ๋ผ ํด๋์ค์ ๋ง์ ์ฑ ์์ด ์์ผ๋ฉด ๋ฒ๊ทธ ๋ฐ์๋ฅ ์ ์ฌ๋ผ๊ฐ๊ณ ๊ฐ๋ ์ฑ์ ๋จ์ด๋จ๋ฆฌ๋ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ๋ค. ํ๋์ ๋ณ๊ฒฝ์ด ๋ค๋ฅธ ๊ธฐ๋ฅ์ ์ํฅ์ด ์๋ค๋ ๊ฒ์ ๋ณด์ฆํ ์ ์๊ฒ ๋๋ฏ๋ก ํ ํด๋์ค์ ์ฑ ์ยท๊ด์ฌ ๋ฒ์๋ ํ๋๋ก ์ขํ์ผ ํ๋ค. ๊ทธ๋์ผ ๋ชจ๋ ์ํฅ๋ฒ์๋ฅผ ํ์ ํ๊ธฐ๋ณด๋ค ํ๋์ ์ํฅ๋ฒ์๋ง ํ์ ํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ๋ฒ๊ทธ๋ ์ค๊ณ ๊ฐ๋ ์ฑ๋ ์ฌ๋ผ๊ฐ๋ค. ์ฝ๋ ๋ณต์ก๋๋ ์ค์ด๋ ๋ค.
๊ฐ๋ ์ฑ ์๋ ์ฝ๋ ์์ฑ
๊ตฌํํด์ผ ํ ๊ธฐ๋ฅ์ ๋จผ์ ์ดํดํ ๋ค์ ์ฝ๋ฉ์ ํ๊ฒ ๋๋๋ฐ ์ฝ๋ฉ์ ๋ค๋ฅธ ์ฝ๋๋ค์ ์ฐธ์กฐํ๊ฒ ๋๋ฉด ๊ทธ ์ฝ๋๋ฅผ ์ฝ๊ธฐ ํธํด์ผ ๋นจ๋ฆฌ ํ์ ํด ์ฝ๋ฉ ์๋๋ฅผ ๋๋ฆฌ๊ฒ ํ์ง ์๊ฒ ๋๊ณ , ์ฝ๋ ๋ฆฌ๋ทฐ์์ ์์ ์ ์ฝ๋๋ฅผ ๋จ๋ค์๊ฒ ์ค๋ช ํ๊ฑฐ๋ ๋จ๋ค์ด ๋ด ์ฝ๋๋ฅผ ์ดํดํ๋๋ฐ ๋๋ ๋น์ฉ๋ ๊ณ ๋ คํด์ผ ํ๋ค. ์์ ์ ์ฝ๋๋ฅผ ์ฐ๋ ์๊ฐ๊ณผ ์ฝ๋ ๋ฆฌ๋ทฐ์ ๋๋ ์๊ฐ์ ์ค์ผ ํ์๊ฐ ์๋ค๋ ์ ์ด๋ค. ๋ฌผ๋ก ์๋ก์ด ์ฌ๋์ด ์์๋ ๊ทธ ์ฌ๋์ด ๋งก์ ๋ถ๋ถ์ ์ฝ๋๋ ์ฝ๊ธฐ๊ฐ ์ฌ์์ผ ๋ถ์ํ๋๋ฐ ์๊ฐ์ ์ค์ผ ์ ์๋ค.
1. ๋ค์ด๋ฐ
์ฐ์ Type(ํด๋์ค, ์ธํฐํ์ด์ค ๋ฑ), Value(๋ณ์, ํ๋, ๋งค๊ฐ ๋ณ์ ๋ฑ) ๋ฐ ์ ์ฐจ(ํจ์, ๋ฉ์๋, ์๋ธ ๋ฃจํด ๋ฑ)๋ฑ์ "What"์ ํํํ๋๊ฒ ์ค์ํ๋ค. ๋ฌด์์ ๋ํ๋ด๋์ง๋ฅผ ๋ค์ด๋ฐ์ ํตํด ์๋ ค์ค์ผ ํ๋ค. ์๋ฅผ ๋ค์ด์ flag๋ฅผ ๋ํ๋ด๋ ๊ฒฝ์ฐ๋ is, was, should, can, may, will ๋ฑ์ผ๋ก ์์ํ๊ณ check์ ์๋ฏธ์ธ ๊ฒฝ์ฐ is, query, verify, mesaure, filter, notify, update, valid, complated๋ก ์์ํ๋๊ฒ ์ข๊ณ ๊ณผ๊ฑฐ๋ฅผ ๋ํ๋ผ ๊ฒฝ์ฐ previous, stored, expired, invalidated, deprecated ๋ฑ์ผ๋ก ์์ํ๋๊ฒ ์ข๋ค. ๊ทธ๋ฆฌ๊ณ ๋จ์ด์ ์ ํ์ ๋ชจํธ์ฑ์ด ์ ์, ํผ๋์ ์ผ๊ธฐํ์ง ์๋ ๋จ์ด๋ฅผ ์ ํํ๋ค. processData, cleanData, normalizeData, sortData, mergeData ๋ฑ์ฒ๋ผ ๋ชจํธํ ๋ค์ด๋ฐ์ ์ฐ์ง ๋ง๊ณ ๊ตฌ์ฒด์ ์ธ ์ด๋ฆ์ผ๋ก ๋ฐ๊ฟ์ผ ํ๋ค.
2. ์ฝ๋ฉํธ
๋ณต์กํ ์ฝ๋๋ ํฐ ์ฝ๋, ์ง๊ด์ ์ผ๋ก ์ดํดํ๊ธฐ ์ด๋ ค์ด ์ฝ๋์๋ ์ฝ๋ฉํธ๋ฅผ ์ฐ๋ ๊ฒ์ผ๋ก ๋ ์์ ์ดํด๋ฅผ ๋์ธ ์ ์๋ค. ์๋จ ์์ฝ๋ถ๋ถ์ "What, Why not"์ ๊ด์ ์ผ๋ก ๋ฌด์์ ํ๊ณ ์๊ณ ๋ถ์์ฉ์ ๋ฌด์์ธ์ง ๋ด์ฉ์ ๋ค์ด๊ฐ๋ฉด ์ข๋ค. ์ธ๋ผ์ธ ์ฝ๋ฉํธ๋ ๋ ์์์ผ๋ฉด ์์ฐ๋๊ฒ ์ข์๋ฐ ์จ์ผํ ๊ฒฝ์ฐ๋ ์ฝ๋ ๋ธ๋ก์ด ํฌ๊ฑฐ๋ ์ง๊ด์ ์ด์ง ์๋ ์ฝ๋, ์ฃผ์๋ฅผ ์ํ๋ ๊ฒฝ์ฐ์ ํํด ์ธ๋ผ์ธ ์ฝ๋ฉํธ๋ฅผ ๋ค๋๊ฒ ์ข๋ค.
3. ๋ก์ง์ ๋ณต์ก์ฑ ์ค์ด๊ธฐ
3.1 Type(ํด๋์ค, ์ธํฐํ์ด์ค, ๋ชจ๋ ๋ฑ)
SOLID(๋จ์ผ ์ฑ ์์ ์์น) ๊ด์ ์์ ์ค๊ณ๋ฅผ ํ๊ณ ๊ธด ๋งค๊ฐ๋ณ์๋ ๊ฐ์ฒดํํด์ ๊ณตํตํํ๊ณ ํ์์ ๋ฐ๋ผ ํน์ฑ์ด ์๋ ํ๋ผ๋ฏธํฐ๋ ์์ ํํ๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ก ๋ถ๋ฆฌํ๋ค. ์์กด์ฑ์ ์ค์ด๊ธฐ ์ํ ๋ ธ๋ ฅ์ ํด์ผํ๋ค. ์์กด์ฑ ์ค์ด๋๋ฐ์๋ ์ฃผ๋ก ๊ฒฐํฉ๋(coupling) ๊ด์ ์์ ๋ณผ ํ์๊ฐ ์๋ค. ํนํ ํผํด์ผ ํ ๊ฒฐํฉ๋๋ Content coupling, Common coupling, Control Coupling ์ ๋์ด๋ค. External Coupling์ Content์ Common coupling์ด ๋์ง ์๋ ์ด์ ์ธ๋ถ ๋ชจ๋์ ๋ง์ด ์ฌ์ฉํ๋ ์ถ์ธ์ฌ์ ์ ์ธํ๋ค.
- Content coupling์ ๋์์ ๋ด๋ถ ๊ตฌํ(์ํ, ์ ์ด ํ๋ฆ)์ ์ง์ ์์กดํ๋ ๊ฒ์ด๋ค. ์๋ ์ฝ๋๋ ์ ์ฒ๋ฆฌ, ํ์ฒ๋ฆฌ ๋ฑ ์์ ์ํ๊ฐ ์์ด์ ์์๋ฅผ ์๋ชป ํธ์ถํ๊ฑฐ๋ ๋นผ๋จน์ผ๋ฉด ๋ฌธ์ ๋ฅผ ๋ง๋ค ์ ์๋ค. Content coupling์ ๋ด๋ถ ์ํ๋ฅผ ์ํํ๊ฑฐ๋, ๊ฐ์ ์ ๋ฌ์ ์ธ์๋ ๋ฐํ๊ฐ์ ์ฌ์ฉํ๋ ๊ฒ์ผ๋ก ํด๊ฒฐํ ์ ์๋ค.
public class TabakoCalculator {
public calculatorTotal() {
calculator.parameter = 5000;
calculator.prepareProcess();
calculator.calculate();
calculator.postProcess();
Bigdecimal totalAmount = calculator.result;
}
}
๊ฐ์ ๋ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
public class TabakoCalculator {
public calculatorTotal() {
Bigdecimal totalAmount = calculator.calculatorTotal(5000);
}
}
- Common coupling์ ์ ์ญ ์ํ๋ฅผ ์ฌ์ฉํ๋ ์ข ์์ฑ์ด๋ค. ๋ํ์ ์ธ ๊ฒ ๊ฐ๋ณ์ ๊ธ๋ก๋ฒ ๋ณ์๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ์ ํด๋น๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ์ ์ญ ๋ณ์๋ฅผ ์ฌ์ฉํ์ง ์๊ณ , ์์ฑ์ ์ธ์๋ก์ ๋์์ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ฉด ํด๊ฒฐํ ์ ์๋ค. ์์ฆ์ ๋๋ถ๋ถ ๋ฉํฐ ์ฐ๋ ๋ ํ๊ฒฝ์์ ์ด๋ก๋์ด ๋ฐ๋ก ๋ฌธ์ ๊ฐ ๋๊ธฐ ๋๋ฏ์ ๋๋ถ๋ถ ์ฌ์ฉ์ ์ํ๋ค.
public class MessageUserCase {
public MessageRepository messasgeRepository;
public MessageUserCase() {
}
public List<Message> getMessage() {
List<Message> messages = messasgeRepository.getMessages();
return messages;
}
}
๊ฐ์ ๋ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
public class MessageUserCase {
private final MessageRepository messasgeRepository;
@Autowired
public MessageUserCase(MessageRepository messasgeRepository) {
this.messasgeRepository = messasgeRepository;
}
public List<Message> getMessage() {
List<Message> messages = messasgeRepository.getMessages();
return messages;
}
}
- Control coupling์ ์ธ์์ ๋ฐ๋ผ ๋์์ ๋ถ๊ธฐ์ํค๋ ์ข ์์ฑ์ ๋งํ๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ์ ์ฐจ ์์ฒด๋ฅผ ๋ถ๋ฆฌํ๊ณ ์กฐ๊ฑด ๋ถ๊ธฐ๋ฅผ ์ญ์ ํ๊ฑฐ๋ ๋ก์ง์ ์กฐ๊ฑด์ผ๋ก ๋๋์ง ์๊ณ ๋์์ผ๋ก ๋๋๋ ๋ฐฉ๋ฒ, ์ ๋ต ํจํด์ ํ์ฉํ๋ฉด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
public class ReportGenerator {
public void generateReport(boolean isDetailed) {
if (isDetailed) {
generateDetailedReport(); // Generate a detailed report
} else {
generateSummaryReport(); // Generate a summary report
}
}
private void generateDetailedReport() {
System.out.println("Generating detailed report...");
// Detailed report logic
}
private void generateSummaryReport() {
System.out.println("Generating summary report...");
// Summary report logic
}
}
๊ฐ์ ๋ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
interface Reportable {
public void generate();
}
// Detailed report class
class DetailedReport implements Reportable {
@Override
public void generate() {
System.out.println("Generating detailed report...");
// Detailed report logic
}
}
// Summary report class
class SummaryReport implements Reportable {
@Override
public void generate() {
System.out.println("Generating summary report...");
// Summary report logic
}
}
public class ReportGenerator {
private Reportable report;
public ReportGenerator(Reportable report) {
this.report = report;
}
public void generateReport() {
report.generate(); // The specific report type handles the logic
}
}
3.2 Value(๋ณ์, ํ๋, ๋งค๊ฐ ๋ณ์ ๋ฑ)
์ฃผ๋ก ๋งค์ง ๋๋ฒ ์ฌ์ฉ์ ํ์ง ๋ง๊ณ ํด๋์ค์ ๋ง์ฐฌ๊ฐ์ง๋ก ๊ธด ๋งค๊ฐ๋ณ์๋ ๊ฐ์ฒดํํด์ ๊ณตํตํํ๊ณ ํ์์ ๋ฐ๋ผ ํน์ฑ์ด ์๋ ํ๋ผ๋ฏธํฐ๋ ์์ ํํ๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ก ๋ถ๋ฆฌํ๋ค.
- ๋งค์ง ๋๋ฒ ์ฌ์ฉ์ ํ์ง ๋ง์.
public double calculateTotalFee(long price) {
return price * 1.10;
}
๊ฐ์ ๋ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
public static final double TAX_RATE = 0.10;
public double calculateTotalFee(long price) {
return price * (1 + TAX_RATE);
}
- ๋ณ์๋ช ์ ๊ตฌ์ฒด์ฑ์ ๋ถ์ฌํ๋ค,
a = 10;
b = 20;
c = a + b;
๊ฐ์ ๋ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
int applePrice = 10;
int bananPrice = 20;
int totalPrice = applePrice + bananPrice;
3.3 ์ ์ฐจ(ํจ์, ๋ฉ์๋, ์๋ธ ๋ฃจํด ๋ฑ)
3.3.1 ํจ์๋ ๋ ์ ์์ผ๋ฉด ์์ ํจ์๋ก ์์ฑํ๋ค.
์์ํ ํจ์๋ ์ธ์๊ฐ ๊ฐ์ผ๋ฉด ๋งค๋ฒ ๊ฐ์ ๊ฐ์ ๋ฐํํด ํจ์ ๋ฐ์ ์ธ๊ณ์ ์ํฅ์ ๋ฏธ์น์ง ์๋ ํจ์๋ฅผ ๋งํ๋ค.
private int fee = 10;
public int calculateTotalPrice(int tabacoPrice) {
return fee * tabacoPrice;
}
์๋๋ ์์ํจ์๋ผ ํ ์ ์๋ค. ์ด๋ ๊ฒ ํจ์ผ๋ก์จ ํธ์ถํ๋ ์ชฝ์์ ์ํฅ์ ๋ฐ์ง ์๋๋ค. DB๊ฐ, ์๊ฐ, ๋์ ๋ฑ์ ๋ด๋ถ์์ ์ฒ๋ฆฌํ๋ฉด ์์ํจ์๊ฐ ๋์ง ์๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์๋ ์ธ์๋ก ๋ฒ์์ ์์ํจ์๋ก ์ฒ๋ฆฌ๋ฅผ ํด์ค๋ค.
public int calculateTotalPrice(int tabacoPrice, int fee) {
return fee * tabacoPrice;
}
3.3.2 if์ ์กฐ๊ฑด์์ ์ด๋ฆ์ ๋ถ์ด์
if(aaa == bbb && aaa == 1 && bbb == 2) {
}
์ ์กฐ๊ฑด์์ ์ฌ๋์ด ์๊ธฐ ์ด๋ ต๋ค. ๊ทธ๋์ ์๋์ฒ๋ผ ์กฐ๊ฑด์ ๋ํ ๋ค์ด๋ฐ์ ํด์ฃผ๋ฉด ๊ฐ๋ ์ฑ์ด ์ฌ๋ผ๊ฐ๋ค. ๋ฐ๋ณต๋๋ ์์์ด๋ฉด ํจ์ํํ๋ค.
boolean available = (aaa == bbb);
if (available && company.isOwner(aaa, bbb)) {
...
}
3.3.3 ์ฒ๋ฆฌ ์์๋ฅผ ๊ณ ๋ คํ๋ค.
์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋์ด๋ ค๋ฉด ๋ ผ๋ฆฌ์ ์ด๊ณ ์์ฐ์ค๋ฌ์ด ํ๋ฆ์ผ๋ก ์ฒ๋ฆฌ ์์๋ฅผ ๋ฐฐ์นํ๋ ๊ฒ์ด ์ค์ํ๋ค.
public String sendMailForSignUpUser(User user) {
// 1. ์
๋ ฅ ๋ฐ์ดํฐ ๊ฒ์ฆ
if !validateignUpUser(user) {
return "Invalid user";
}
// 2. ๋ฉ์ผ ๋ฐ์ก ์ ๋ณด DB ์ ์ฅ
insertSignupUserMail(user);
// 3. ์ฌ์ฉ์์๊ฒ ๊ฐ์
ํ์ ๋ฉ์ผ ๋ณด๋ด๊ธฐ
sendWelcomeMail(user);
return "Mail sent successfully";
}
3.3.4 ์ฝ๋์ ์ค์ฒฉ์ ์๊ฒ ์ ์งํ๋ค.
์ผ๋ฆฌ ๋ฆฌํด ๋ฐฉ์์ด ์ ์ฉํ๋ค.
public String getGrade(int score) {
if (90 < score) {
return "A";
} else {
if (60 < score) {
return "B";
} else {
return "C";
}
}
}
๊ฐ์ ๋ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
public String getGrade(int score) {
if (90 < score) {
return "A";
}
if (60 < score) {
return "B";
}
return "C";
}
3.3.5 ์ต๋ช ํจ์๋ ์ค์ธ์, ๋ฆฌ์๋ฒ, ์ฝ ๋ฐฑ ์ฒด์ธ ๋ฑ์ ์ด๋ฆ์ด ์๋ ๋ก์ปฌ ๋ณ์๋ ํ๋ผ์ด๋น ํจ์๋ก ์ฎ๊ฒจ๋์ ํ๋ก๊ทธ๋๋ฐ ์คํ์ผ์ ์งํฅํ๋ค.
์๋ ์ฝ๋๋ ์ด๋ฏธ์ง๋ฅผ ์ํ์ผ๋ก ์๋ฅด๊ณ PNG๋ก ๋ณํํ๊ณ ํ์ํ๋ ์ฝ๋์ธ๋ฐ, ์ด ์ฝ๋๋ ๋๊ฐ์ง ๋ฌธ์ ๊ฐ ์๋ค. ํ์ค๋ก ์ฝ๋๋ ๊น๋ํ ์ง ๋ชจ๋ฅด๋ ์ ์ฒด ๋ด์ฉ์ ์์ธํ ๋ค์ฌ๋ค๋ด์ผํ๊ณ ํจ์๋ณ๋ก ํน์ ๊ฐ์ ๊ฒ์ฌํ๊ฑฐ๋ ๋ณ๊ฒฝํ ๋ ์ ์ฒด๋ฅผ ํ์ ํด์ผ ํ๋ค.
showImage(convertImage(cropImage(loadImage(imageUri), Shape.CIRCLE), ImageFormat.PNG));
๊ฐ์ ๋ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
File originalBitmap = loadImage(imageUri);
File croppedBitmap = cropImage(originalBitmap, Shape.CIRCLE);
File croppedPng = convertImage(croppedBitmap, ImageFormat.PNG);
showImage(croppedPng);
3.4 ๋ด๋ถ ๊ตฌ์กฐ ๊ฐ์
์๊ณ ๋ฆฌ์ฆ์ ์ฝ๋์ ์ฑ๋ฅ๊ณผ ์ฝ๋์ ์ง์ ํธ๊ธฐ์ฌ ์ถฉ์กฑ ๋ฑ ๋๊ฐ์ง๋ฅผ ๋ง์กฑํ ์ ์๋ค. ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ด ๋๋ ์๊ณ ๋ฆฌ์ฆ์ ๋ณด๋ค ํจ์จ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๋์ฒดํ๊ณ , ๊ณ์ฐ ๊ฒฐ๊ณผ ์บ์์ ๊ฐ์ ์ต์ ํ๋ฅผ ํตํด ๋ถํ์ํ ์ฌ๊ณ์ฐ์ ์ค์ฌ ์ฑ๋ฅ์ ํฅ์์ํค๊ณ ๋ฆฌ์์ค๋ฅผ ์ ์ฝํ ์ ์๋ค.
3.4.1 ํจ์จ์ ์ธ ์๊ณ ๋ฆฌ์ฆ ๊ฐ์
์ ๋ ฌ๋์ง ์์ ๋ชฉ๋ก์์ ํน์ ๊ฐ์ ์ ํ ๊ฒ์ํ๋ค๊ณ ๊ฐ์ ํ์๋ ์๋ ์ฝ๋๋ ์ผ๋ฐ์ ์ธ ์ฝ๋์ด๋ค. ๊ณ์ฐ๋์ O(n)์ด๋ค.
def find_number(numbers, target):
for number in numbers:
if number == target:
return True
return False
numbers = [5, 3, 8, 4, 2, 7, 1, 6]
print(find_number(numbers, 4))
๋ชฉ๋ก์ ๋ฏธ๋ฆฌ ์ ๋ ฌํ๊ณ ์ด์ง ๊ฒ์ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ๊ฒ์ ํจ์จ์ฑ์ ๋์๋ค. ๊ณ์ฐ๋์ O(n)์์ O(log n)์ผ๋ก ๊ฐ์ ๋์๋ค.
def find_number(numbers, target):
# ์ ๋ ฌ
numbers.sort()
# ์ด์ง ํ์
left = 0
right = len(numbers) - 1
while left <= right:
mid = (left + right) // 2
if numbers[mid] == target:
return True
elif numbers[mid] < target:
left = mid + 1
else:
right = mid - 1
return False
numbers = [5, 3, 8, 4, 2, 7, 1, 6]
print(find_number(numbers, 4))
3.4.2 ๋ถํ์ํ ๊ณ์ฐ ๊ฐ์
ํผ๋ณด๋์น ์์ด์ ๊ฐ์ ์ฌ๊ท์ ์ผ๋ก ๊ณ์ฐํ์ง๋ง ๋์ผํ ๊ณ์ฐ์ ์ฌ๋ฌ ๋ฒ ๋ฐ๋ณตํ๋ค. ๊ณ์ฐ๋์ O(2^n)์๋ค.
def fibonacci(n):
if n <= 1:
return n
else:
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(35))
๋ฉ๋ชจํ(์บ์)๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฏธ ๊ณ์ฐ๋ ๊ฐ์ ์ฌ์ฌ์ฉํ๋ฉด ๊ณ์ฐ๋์ O(n)์ผ๋ก ๊ฐ์ ํ ์ ์๋ค.
def fibonacci(n, memo={}):
if n in memo:
return memo[n]
if n <= 1:
memo[n] = n
else:
memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo)
return memo[n]
print(fibonacci(35))
3.4.3 ์ ์ ํ ๋ฐ์ดํฐ ๊ตฌ์กฐ ์ฌ์ฉ
๋ชฉ๋ก์์ ์ค๋ณต์ฌ๋ถ๋ฅผ ํ์ธํ๋ ํจ์๋ฅผ ๋ง๋ ๋ค๋ฉด ์๋๋ ๊ณ์ฐ๋์ด O(n^2)์ด ๋๋ค.
def has_duplicate(elements):
for i in range(len(elements)):
for j in range(i + 1, len(elements)):
if elements[i] == elements[j]:
return True
return False
elements = [1, 2, 3, 4, 5, 2]
print(has_duplicate(elements))
set๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ณต์ ํจ์จ์ ์ผ๋ก ๊ฐ์งํ ์ ์๋ค. ๊ณ์ฐ๋์ O(n)์ผ๋ก ๊ฐ์ ๋์๋ค.
def has_duplicate(elements):
return len(elements) != len(set(elements))
elements = [1, 2, 3, 4, 5, 2]
print(has_duplicate(elements))
4. ์ฝ๋์ ์ต์ ํ
์ํ(state), ๊ฒฐํฉ(coupling), ๋ณต์ก์ฑ(complexity), ์ฝ๋๋(code) ์์ผ๋ก ์ค์์ผ๋ก์จ ์ฝ๋๋ฅผ ์ต์ ํํ๋ฉด ์ข๋ค. ์ํ๋ฅผ ๊ด๋ฆฌํ์ง ์๋ ๋ก์ง์ ์ฝ๋ ์คํ, ๋ณ๋ ฌ ์ฒ๋ฆฌ ๋๋ ๋ถ์ฐ ์ฒ๋ฆฌ์์ ๋์ผํ๊ฒ ์๋ํด ํ์ฅ์ฑ์ด ์ข๊ณ , ์ํ ์ฌํ ์ฝ๋๊ฐ ํ์์์ด ํ ์คํธ๊ฐ ํธํ๊ณ ์ฝ๋์ ๋ณต์ก์ฑ์ด ์ค์ด๋ ๋ค.
5. ์์กด ๋ฐฉํฅ
- ์์กด ๊ด๊ณ๋ ๋จ๋ฐฉํฅ์ด์ด์ผ ํ๊ณ ์ํ ์์กด์ฑ์ด ๋ฐ์ํ๋ฉด ์๋๋ค
- ๋ฐ๋์งํ ์์กด ๊ด๊ณ๋ ํธ์ถํ๋ ์ธก์ด ํธ์ถ๋๋ ์ธก์ ์์กดํ๋ ๊ฒ์ด ์ข๋ค
- ๊ตฌํ(์์ธ) ํด๋์ค๋ ์ถ์ ํด๋์ค์ ์์กดํ๋ค
- ๋ณต์กํ ๊ฒ์ด ๋จ์ํ ๊ฒ์ ์์กดํ๋ ๊ฒ์ด ์ข๋ค
ํด๊ณผ ๊ฐ์ด๋ ํ์ฉ
1. Code Style Guide
- Google JavaScript Style Guide
- Airbnb JavaScript Style Guide
- Google Python Style Guide
- PEP 8 โ Python Style Guide
- Google C++ Style Guide
- Google Java Style Guide
- Google HTML/CSS Style Guide
- Google Go Style Guide
- Effective Go
- Google Swift Style Guide
- Airbnb Swift Style Guide
- Ruby Style Guide
- Airbnb Ruby Style Guide
- Rust Style Guide
- Kotlin Style Guide
2. Code Formatter
- Google Java formatter
- Facebook Kotlin formatter
- Python code formatter
- Google Python formatter
- Go Format
- Ruby Code formatter
- Rust Code formatter
์ฝ๋ ๊ฐ๋ ์ฑ ํฅ์์ ์ํ ์ถ์ฒ ๋์
- The Art of Readable Code: Simple and Practical Techniques for Writing Better Code(by Dustin Boswell)
- Code Complete: A Practical Handbook of Software Construction(by Steve McConnell)
- Clean Code: A Handbook of Agile Software Craftsmanship(by Robert C. Martin)
- Refactoring: Improving the Design of Existing Code