728x90
반응형

공통으로 사용될 수 있는 특정한 기능들을 모듈화

  • 라이브러리: 폴더명, 파일명 등에 대한 규칙 X, 프레임워크에 비해 자유로움
    • ex. 무언가 자를 때 '도구'인 '가위' 사용해서 '내가' 직접 컨트롤
  • 프레임워크: 폴더명, 파일명 등에 대한 규칙 O, 라이브러리에 비해 엄격
    • ex. 다른 곳으로 이동할 때 '도구'인 비행기를 타고 이동 -> '비행기'가 컨트롤, 나는 앉아 있어야 함

 

SECTION 1 디자인 패턴

프로그램을 설계할 때 발생했던 문제점

-> 객체 간의 상호 관계 등 이용해 해결할 수 있도록 하나의 규약 형태로 만들어 놓은 것

 

1. 싱글톤 패턴(singleton pattern)

하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴

(하나의 클래스를 기반으로 여러 개의 개별적인 인스턴스를 만들 수 있음)

  • 데이터베이스 연결 모듈에 사용 

      
const URL = 'mongodb://localhost:27017/test'
const createConnection = url => ({"url" : url})
class DB {
constructor(url) {
if (!DB.instance) {
DB.instance = createConnection(url)
}
return DB.instance
}
connect() {
return this.instance
}
}
const a = new DB(URL)
const b = new DB(URL)
console.log(a === b) // true
  • (+) 인스턴스 생성할 때 드는 비용 ↓
  • (-) 의존성(종속성)
  • (-) TDD(Test Driven Development)
    • 단위 테스트를 주로 하는데 미리 생성된 하나의 인스턴스를 기반으로 구현하는 패턴
      -> 각 테스트마다 독립적인 인스턴스 만들기 어려움
      • 단위 테스트: 테스트 서로 독립적/ 테스트를 어떤 순서로든 실행할 수 있어야 함

 

<자바스크립트>

리터럴 {} or new Object로 객체 생성 -> 다른 어떤 객체와도 같지 X


      
class Singleton {
constructor() {
if (!Signleton.instance) {
Singletone.instance = this
}
return Signletone.instance
}
getInstance() {
return this.instance
}
}
const a = new Signleton()
const b = new Signleton()
console.log(a === b) // true

 

<자바>


      
class Singleton {
private static class singleInstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return singleInstanceHolder.INSTANCE;
}
}
public class HelloWorld {
public staticvoid main(String[] args) {
Singleton a = Signleton.getInstance();
Singleton b = Signleton.getInstance();
System.out.println(a.hashCode());
System.out.println(b.hashCode());
if (a == b) {
System.out.println(true); // true
}
}
}

 

의존성 주입(DI; Dependency Injection)

  • 의존성 ↑ 해결
  • 메인 모듈) 직접 다른 하위 모듈에 대한 의존성 주기 -> 의존성 주입자가 이 부분을 가로챔 
    => 메인 모듈) 간접적으로 의존성 주입
    • 메인 모듈(상위 모듈)은 하위 모듈에 대한 의존성 ↓: 디커플링이 된다
  • 원칙
    • 상위 모듈은 하위 모듈에서 어떤 것도 가져오지 않아야 함
    • 둘다 추상화에 의존, 추상화는 세부 사항에 의존 X
  • (+) 모듈을 쉽게 교체할 수 있는 구조가 됨 -> 테스팅 쉽고 마이그레이션하기 수월
  • (+) 구현할 때 추상화 레이어를 넣고 이를 기반으로 구현체를 넣어줌
    -> 애플리케이션 의존성 방향 일관, 애플리케이션 쉽게 추론, 모듈 간의 관계 명확
  • (-) 모듈이 더욱더 분리 -> 클래스 수 ↑ -> 복잡성 ↑, 약간의 런타임 페널티 생기기도 함

2. 팩토리 패턴(factory pattern)

객체를 사용하는 코드에서 객체 생성 부분을 떼어내 추상화한 패턴

  • 상속 관계에 있는 두 클래스 -> 상위 클래스: 중요한 뼈대 결정/ 하위 클래스: 객체 생성에 관한 구체적인 내용 결정
    • 상위/하위 클래스 분리 => 느슨한 결합
    • 상위 클래스: 인스턴스 생성 방식에 대해 알 필요 X -> 유연성 ↑
    • 코드 리팩터링해도 한 곳만 수정 -> 유지 보수성 ↑
  • ex. 상위 클래스: 바리스타 공장에서 생산/ 하위 클래스: 라떼 레시피, 아메리카노 레시피, 우유 레시피

 

<자바스크립트>

new Object()로 구현, 전달받은 값에 따라 다른 객체 생성, 인스턴스의 타입 등 정함

static 정적 메서드 -> 클래스의 인스턴스 X 호출 가능 => 메모리 절약, 개별 인스턴스에 묶이지 않으며 클래스 내의 함수 정의 O


      
class Latte {
constructor() {
this.name = "latte"
}
}
class Espresso {
constructor() {
this.name = "Espresso"
}
}
clas LatteFactory {
static createCoffe() {
return new Latte()
}
}
class EspressoFactory {
static createCoffe() {
return new Espresso()
}
}
const factoryList = { LatteFactory, EspressoFactory }
class CoffeFactory {
static createCoffe(type) {
const factory = factoryList[type]
return factory.createCoffee()
}
}
const main = () => {
// 라떼 커피 주문
const coffee = CoffeFactory.createCoffee("LatteFactory")
// 커피 이름
console.log(coffee.name) // true
}
main()
상위 클래스: CoffeeFactory가 중요한 뼈대 결정/ 하위 클래스: LatteFactory가 구체적인 내용 결정
CoffeeFactory에서 LatteFactory의 인스턴스 생성 X,
LatteFactory에서 생성한 인스턴스 -> CoffeeFactory에 주입
=> 의존성 주입

 

<자바>


      
abstract class Coffee {
public abstract int getPrice();
@Override
public String toString() {
return "Hi this coffee is " + this.getPrice();
}
}
class CoffeeFactory {
public static Coffee getCoffee(String type, int price) {
if ("Latte".equalsIgnoreCase(type)) return new Latte(price);
else return DefaultCoffee();
}
}
class DefaultCoffee extends Coffee {
private int price;
public DefaultCoffee() {
this.price = -1;
}
@Override
public int getPrice() {
return this.price;
}
}
class Latte extends Coffee {
private int price;
public Latte(int price) {
this.price = price;
}
@Override
public int getPrice() {
return this.price
}
}
public class HelloWorld {
public static void main(String[] args) {
Coffee latte = CoffeeFactory.getCoffee("Latte", 4000);
System.out.println("Factory latte :: " + latte);
// Factory latte :: Hi this coffee is 4000
}
}

3. 전략 패턴(strategy pattern) = 정책 패턴(policy pattern)

객체의 행위를 바꾸고 싶은 경우 직접 수정 X

전략이라고 부르는 캡슐화한 알고리즘 -> 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴

 

ex. 결제 방식의 전략 바꿔서 결제(네이버페이, 카카오페이)


      
import java.text.*;
import java.util.*;
interface PaymentStrategy {
public void pay(int amount);
}
class KAKAOStrategy implements PaymentStrategy {
private String name;
private String cardNumber;
private String cvv;
private String dateOfExpiry;
public KAKAOStrategy(String nm, String ccNum, String cvv, String expiryDate) {
this.name = nm;
this.cardNumber = ccNum;
this.cvv = cvv;
this.dateOfExpiry = expiryDate;
}
@Override
public void pay(int amount) {
System.out.println(amount + " payid using Kakao");
}
}
class Item {
private String name;
private int price;
public Item(String name, int cost) {
this.name = name;
this.price = cost;
}
public String getName() {
return name;
}
public int getPrice() {
return price;
}
}
class ShoppingCart {
List<Item> items;
public ShoppingCart() {
this.items = new ArrayList<>();
}
public void addItem(Item item) {
this.items.add(item);
}
public int calculateTotal() {
int sum = 0;
for (Item item : items) {
sum += item.getPrice();
}
return sum;
}
public void pay(PaymentStrategy paymentMethod) {
int amount = calculateTotal();
paymentMethod.pay(amount);
}
}
public class HelloWorld {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
Item A = new Item("item1", 100);
Item B = new Item("item2", 300);
cart.addItem(A);
cart.addItem(B);
cart.pay(new KAKAOStrategy("asdfasd", "123456789", "123", "05/05"));
// 400 paid using Kakao
}
}

 

passport 전략 패턴

  • 전략 패턴을 활용한 라이브러리
  • Node.js에서 인증 모듈을 구현할 때 쓰는 미들웨어 라이브러리
  • LocalStrategy 전략: 서비스 내의 회원가입된 아이디, 비밀번호 기반으로 인증
  • OAuth 전략: 페이스북, 네이버 등 다른 서비스를 기반으로 인증

      
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({ username: username }, function (err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
passport.use(new LocalStrategy( ...처럼 `passport.use()라는 메서드에 '전략'을 매개변수로 넣어서 로직 수행

4. 옵저버 패턴(observer pattern)

  • 주체가 어떤 객체(subject)의 상태 변화를 관찰하다가 상태 변화 O
    -> 메서드 ~> 옵저버 목록에 있는 옵저버들에게 변화를 알려주는 디자인 패턴
    • 주체: 객체의 상태를 변화를 보고 있는 관찰자
    • 옵저버들: 객체의 상태 변화에 따라 전달되는 메서드 등을 기반으로 추가 변화 사항이 생기는 객체들
  • 주체와 객체를 따로 두지 않고 상태가 변경되는 객체를 기반으로 구축하기도 함
  • ex. 트위터: 어떤 사람인 주체 '팔로우' -> 주체가 포스팅 올리게 되면 알림이 '팔로워'에게 감
  • 이벤트 기반 시스템, MVC 패턴에 사용
    • ex. 모델(주체) 변경 사항 -> update() 메서드로 뷰(옵저버)에 알려줌-> 이를 기반으로 컨트롤러 작동

 

<자바스크립트>

프록시(proxy) 객체 ~> 구현

  • 어떠한 대상의 기본적인 동작(속성 접근, 할당, 순회, 열거, 함수 호출 등)의 작업을 가로챌 수 있는 객체
  • 2개의 매개변수
    • target: 프록시할 대상
    • handler: 프록시 객체의 target 동작을 가로채서 정의할 동작들이 정해져 있는 함수

      
function createReactiveObject(target, callback) {
const proxy = new Proxy(target, {
set(obj, prop, value) {
if (value !== obj[prop]) {
const prev = obj[prop]
obj[prop] = value
callback(`${prop}rk [${prev}] >> [${value}] 로 변경되었습니다. `)
}
return true
}
})
return proxy
}
const b = createReactiveObject(a, console.log)
b.형규 = "솔로"
b.형규 = "커플"
// 형규가 [솔로] >> [커플] 로 변경되었습니다

 

<자바> 


      
import java.util.*;
interface Subject {
public void register(Observer obj);
public void unregister(Observer obj);
public void notifyObservers);
public Object getUpdate(Observer obj);
}
interface Observer {
public void update();
}
class Topic implements Subject {
private List<Observer> observers;
private String message;
public Topic() {
this.observers = new ArrayList<>();
this.message = "";
}
@Override
public void register(Observer obj) {
if (lobservers.contains(obj)) observers.add(obj);
}
@Override
public void unregister(Observer obj) {
observers. remove(obj);
}
@override
public Object getUpdate(Observer obj) {
return this.message;
}
public void postMessage(String msg) {
System.out.println("Message sended to Topic: " + msg);
this.message = msg;
notifyObservers();
}
}
class TopicSubscriber implements Observer {
private String name;
private Subject topic;
public TopicSubscriber(String name, Subject topic) {
this. name = name;
this. topic = topic;
}
@Override
public void update() {
String msg = (String) topic.getUpdate(this);
System.out.println(name +":: got message > " + msg) ;
}
}
public class HelloWorld {
public static void main(String[] args) {
Topic topic = new Topic();
Observer a = new TopicSubscriber ("a", topic);
Observer b = new TopicSubscriber ("b", topic);
Observer c = new TopicSubscriber("c", topic);
topic.register(a);
topic.register(b);
topic.register (c);
topic.postMessage("amumu is op champion!!");
}
}
/*
Message sended to Topic: amumu is op champion!!
a:: got message >> amumu is op champion!!
b:: got message > amumu is op champion!!
c:: got message >> amumu is op champion!!
*/
topic 기반으로 옵저버 패턴 구현/ topic: 주체이자 객체
Subject interface 구현: class Topic implements Subject
옵저버 선언할 때 해당 이름과 어떠한 토픽의 옵저버가 될 것인지 정함
Observer a = new TopicSubscriber("a", topic);

 

  •  상속(extends)
    • 자식 클래스가 부모 클래스의 메서드 등을 상속받아 사용, 자식 클래스에서 추가/확장 할 수 있는 것
    • 재사용성, 중복성의 최소화
    • 일반 클래스, abstract 클래스 기반으로 구현
  • 구현(implements)
    • 부모 인터페이스 -> 자식 클래스에서 재정의하여 구현하는 것
    • 반드시 부모 클래스의 메서드를 재정의하여 구현해야 함
    • 인터페이스 기반으로 구현

 

Vue.js 3.0: ref or reactive로 정의 -> 해당 값이 변경되었을 때 자동으로 DOM에 있는 값 변경

=> 프록시 객체를 이용한 옵저버 패턴을 이용하여 구현한 것

 

DOM(Document Object Model): 문서 객체 모델, 웹 브라우저상의 화면을 이루고 있는 요소


5. 프록시 패턴과 프록시 서버

프록시 패턴(proxy pattern)

  • 대상 객체(subject)에 접근하기 전 그 접근에 대한 흐름을 가로채 대상 객체 앞단의 인터페이스 역할 하는 디자인 패턴
  • 객체의 속성, 변환 등 보완
  • 보안, 데이터 검증, 캐싱, 로깅에 사용
  • 프록시 객체로 쓰이기도 하지만 프록시 서버로도 활용

 

프록시 서버(proxy server)

  • 서버와 클라이언트 사이, 클라이언트가 자신 ~> 다른 네트워크 서비스에 간접적으로 접속 O 컴퓨터 시스템/응용 프로그램
  • nginx: 비동기 이벤트 기반의 구조, 다수의 연결을 효과적으로 처리 가능한 웹 서버
    • Node.js의 버퍼 오버플로우 취약점 예방 -> nginx를 프록시 서버로 활용
      버퍼: 데이터가 저장되는 메모리 공간/ 버퍼 오버플로우: 메모리 공간을 벗어나는 경우
      , 사용되지 않아야 할 영역에 데이터가 덮어씌워져 주소, 값을 바꾸는 공격이 발생하기도 함
      • => 익명의 사용자의 직접적인 서버로의 접근 차단, 간접적으로 한 단계 더 거침 -> 보안성 강화
      • 실제 포트 숨김/ 정적 자원 gzip 압축/ 메인 서버 앞단에서의 로깅
        LZ77과 Huffman 코딩 조합인 DEFLATE 알고리즘을 기반으로 한 압축 기술
  • CloudFlare: 전 세계적으로 분산된 서버가 있고 이를 통해 어떠한 시스템의 콘텐츠 전달을 빠르게 할 수 있는 CDN 서비스
    CDN(Content Delivery Network): 각 사용자가 인터넷에 접속하는 곳과 가까운 곳에서 콘텐츠를 캐싱/배포하는 서버 네트워크
    ~> 사용자가 웹 서버로부터 콘텐츠를 다운로드하는 시간 ↓
    • DDOS 공격 방어, HTTPS 구축(별도의 인증서 설치 X)
      • DDOS: 짧은 기간 동안 네트워크에 많은 요청 -> 네트워크 마비 => 웹 사이트의 가용성 방해하는 사이버 공격 유형
      • 의심스로운 트래픽, 특히 사용자 접속 X 시스템 통해 오는 트래픽 자동 차단 

 

<CORS와 프론트엔드의 프록시 서버>

  • CORS(Cross-Origin Resource Sharing): 서버가 웹 브라우저에서 리소스를 로드할 때 다른 오리진 통해 로드 X
    오리진: 프로토콜과 호스트 이름, 포트의 조합 
    • HTTP 헤더 기반 메커니즘
    • 프론트엔드 개발 -> 프론트엔드 서버를 만들어서 백엔드 서버와 통신할 때 CORS 에러
      • (해결) 프론트엔드에서 프록시서버 만들기도 함

6. 이터레이터 패턴(iterator pattern)

이터레이터 사용 -> 컬렉션(collection)의 요소들에 접근하는 디자인 패턴

순회할 수 있는 여러 가지 자료형의 구조와 상관 X 이터레이터라는 하나의 인터페이스로 순회 O

 

<자바스크립트>


      
const mp = new Map()
mp.set('a', 1)
mp.set('b', 2)
mp.set('c', 3)
const st = new Set()
st.add(1)
st.add(2)
st.add(3)
for (let a of mp) console.log(a)
/*
[ 'a', 1 ]
[ 'b', 2 ]
[ 'c', 3 ]
*/
for (let a of st) console.log(a)
/*
1
2
3
*/
다른 자료 구조인 set, map But, for a of b라는 이터레이터 프로토콜 ~> 순회
이터레이터 프로토콜: 이터러블한 객체들을 순회할 때 쓰이는 규칙
이터러블한 객체: 반복 가능한 객체로 배열을 일반화한 객체

7. 노출모듈 패턴(revealing module pattern)

즉시 실행 함수 ~> private, public 같은 접근 제어자를 만드는 패턴

 

<자바스크립트>

접근 제어자 X 전역 범위에서 스크립트 실행

-> 노출모듈 패턴 ~> private, public 접근 제어자 구현하기도 함: CJS(CommonJS) 모듈 방식


      
const pukuba = (() => {
const a = 1
const b = () => 2
const public = {
c : 2
d : () => 3
}
return public
})()
console.log(pukuba) // { c: 2, d: [Function: d] }
console.log(pukuba.a) // undefined
a와 b: private 범위 / c와 d: public범위

8. MVC 패턴

  • 모델(Model), 뷰(View), 컨트롤러(Controller)로 이뤄진 디자인 패턴
  • 애플리케이션의 구성 요소 -> 3가지 역할로 구분 => 개발 프로세스에서 각각의 구성 요소에만 집중해서 개발 
  • (+) 재사용성, 확장성 용이
  • (-) 애플리케이션 복잡 -> 모델과 뷰의 관계 복잡

 

  • 모델: 애플리케이션의 데이터인 데이터베이스, 상수, 변수 등
    • ex. 사각형 모양의 박스 안에 글자 -> 사각형 모양의 박스 위치 정보, 글자 내용, 글자 위치, 글자 포맷(utf-8 등)에 관한 정보를 모두 가지고 있어야 함
    • 뷰에서 데이터 생성/수정 -> 컨트롤러 ~> 모델 생성/갱신
  • 뷰: inputbox, checkbox, textarea 등 사용자 인터페이스 요소 나타냄
    • 모델을 기반으로 사용자가 볼 수 있는 화면
    • 모델이 가지고 있는 정보는 따로 저장 X, 단순히 사각형 모양 등 화면에 표시하는 정보만 가지고 있어야 함
    • 변경 발생 -> 컨트롤러에 전달
  • 컨트롤러: 하나 이상의 모델과 하나 이상의 뷰를 잇는 다리 역할/ 이벤트 등 메인 로직 담당
    • 모델과 뷰의 생명주기 관리
    • 모델 or 뷰의 변경 통지 -> 해석 => 각각의 구성 요소에 해당 내용에 대해 알려줌

 

리액트(React.js)

  • 유저 인터페이스를 구축하기 위한 라이브러리
  • 가상 DOM ~> 실제 DOM을 조작하는 것을 추상화 => 성능 ↑
    DOM(Document Object Model): 문서 객체 모델/ 웹 브라우저상의 화면을 이루고 있는 요소들
  • 불변성(immutable)
    • state: setState 통해서만 수정 가능
    • props를 기반으로 해서 만들어지는 컴포넌트: pureComponent
  • 단방향 바인딩 적용, 자유도 ↑

9. MVP 패턴

  • MVC 패턴으로부터 파생
  • MVC에서 C에 해당하는 컨트롤러 -> 프레젠더(presenter)
  • 뷰와 프레젠터: 일대일 관계 => MVC 패턴보다 더 강한 결합을 지닌 디자인 패턴

10. MVVM 패턴

  • MVC에서 C에 해당하는 컨트롤러 -> 뷰모델(view model)
    • 뷰모델: 뷰를 더 추상화한 계층
  • 커맨드데이터 바인딩을 가짐(<-> MVC 패턴)
    커맨드: 여러 가지 요소에 대한 처리 -> 하나의 액션으로 처리할 수 있게 하는 기법
    / 데이터 바인딩: 화면에 보이는 데이터와 웹 브라우저의 메모리 데이터 일치시키는 기법, 뷰모델 변경 -> 뷰 변경
    • 뷰와 뷰모델 사이의 양방향 데이터 바인딩 지원
  • (+) UI를 별도의 코드 수정 X 재사용 O, 단위 테스팅하기 쉬움

 

뷰(Vue.js)

  • 반응형(reactivity)
    • watchcomputed 등으로 쉽게 반응형적인 값 구축
  • 함수 사용하지 않고 값 대입만으로도 변수 변경 O
  • 양방향 바인딩, html 토대로 컴포넌트를 구축 O
    • 재사용 가능한 컴포넌트 기반으로 UI 구축 O

SECTION 2 프로그래밍 패러다임(programming paradigm)

프로그래머에게 프로그래밍의 관점을 갖게 해주는 역할을 하는 개발 방법론

  • 선언형
    • 함수형: 상태 값을 지니지 않는 함수 값들의 연속으로 생각할 수 있게 함
  • 명령어
    • 객체지향형: 프로그램을 상호 작용하는 개체들의 집합으로 볼 수 있게 함
    • 절차지향형

 

1. 선언형과 함수형 프로그래밍

  • 선언형 프로그래밍(declarative programming)
    • 무엇을 풀어내는가에 집중하는 패러다임
    • '프로그램은 함수로 이뤄진 것이다'라는 명제가 담겨 있음
  • 함수형 프로그래밍(functional programming): 선언형 패러다임의 일종
    • 순수 함수 -> 블록처럼 쌓아 로직 구현/ 고차 함수 ~> 재사용성 ↑
      • 순수 함수: 출력이 입력에만 의존하는 것
      • 고차 함수: 함수가 함수를 값처럼 매개변수로 받아 로직을 생성할 수 있는 것
        • 일급 객체라는 특징을 가져야 함
          • 변수 or 메서드에 함수를 할당 O
          • 함수 안에 함수를 매개변수로 담을 수 O
          • 함수가 함수를 반환 O

      
const ret = [1, 2, 3, 4, 5, 11, 12]
.reduce((max, num) => num > max > num : max, 0)
console.log(ret) // 12

=> 자바스크립트: 단순, 유연, 함수가 일급 객체 -> 함수형 프로그래밍 방식 선호


2. 객체지향 프로그래밍(OOP; Object-Oriented Programming)

  • 객체들의 집합으로 프로그램의 상호 작용을 표현
  • 데이터를 객체로 취급 -> 객체 내부에 선언된 메서드를 활용하는 방식
  • 설계에 시간 소요 ↑, 처리 속도가 다른 프로그래밍 패러다임에 비해 상대적으로 ↓

 

특징

  • 추상화(abstraction): 복잡한 시스템으로부터 핵심적인 개념 or 기능 간추려내는 것
  • 캡슐화(encapsulation): 객체의 속서오가 메서드 하나로 묶고 일부를 외부에 감추어 은닉하는 것
  • 상속성(inheritance): 상위 클래스 특성 -> 하위 클래스가 이어받아서 재사용/추가/확장
    • 코드의 재사용 측명, 계측적인 관계 생성, 유지 보수성 측면에서 중요
  • 다형성(polymorphism): 하나의 메서드 or 클래스가 다양한 방법으로 동작하는 것
    • 오버로딩(overrloading)
      • 같은 이름 가진 메서드 여러 개/ 메서드 타입, 매개변수의 유형, 개수 등으로 여러 개 O
      • 컴파일 중에 발생하는 정적 다형성
    • 오버라이딩(overriding)
      • 메서드 오버라이딩(method overriding)
      • 상위 클래스로부터 상속받은 메서드 -> 하위 클래스가 재정의
      • 런타임 중에 발생하는 동적 다형성

      
// 오버로딩
class Person {
public void eat(String a) {
System.out.println("I eat" + a);
}
public void eat(String a, String b) {
System.out.println("I eat" + a + " and " + b);
}
}
public class CalculateArea {
publc static void main(String[] args){
Person a = new Person();
a.eat("apple"); // I eat apple
a.eat("tomato", "phodo"); I eat tomato and phodo
}
}

      
// 오버라이딩
class Animal {
public void bark() {
System.out.println("mumu!");
}
}
class Dog extends Aniaml {
@Override
public void bark() {
System.out.println("wal!!!");
}
}
public class Main {
public static void main(String[] args){
Dog d = new Dog();
d.bark(); // wal!!!
}
}

 

설계 원칙

  • 단일 책임 원칙(SRP, Single Responsibility Principle)
    • 모든 클래스는 각각 하나의 책임만 가져야 함
    • ex. A라는 로직 존재 -> 어떠한 클래스는 A에 관한 클래스, 수정해도 A와 관련된 수정이어야 함
  • 개방-폐쇄 원칙(OCP; Open Closed Principle)
    • 유지 보수 사항 생긴다면 코드 쉽게 확장할 수 있도록 함/ 수정할 때는 닫혀 있어야 하는 원칙
    • 기존의 코드 잘 변경 X 확장 쉽게 할 수 있어야 함
  • 리스코프 치환 원칙(LSP; Liskov Substitution Principle)
    • 프로그램의 정확성 깨뜨리지 X 하위 타입의 인스턴스로 바꿀 수 있는 것
    • 클래스는 상속, 부모-자식 계층 관계 만들어짐 
    • 부모 객체에 자식 객체를 넣어도 시스템 문제 X
  • 인터페이스 분리 원칙(ISP; Interface Segregation Principle)
    • 하나의 일반적인 인터페이스 < 구체적인 여러 개의 인터페이스 
  • 의존 역전 원칙(DIP; Dependency Inversion Principle)
    • 자신보다 변하기 쉬운 것에 의존하던 것 -> 추상화된 인터페이스 or 상위 클래스 
      -> 변하기 쉬운 것의 변화에 영향 X 
    • ex. 타이어를 갈아끼울 수 있는 틀 -> 다양한 타이어 교체 O
    • 상위 계층은 하위 계층의 변화에 대한 구현으로부터 독립해야 함

3. 절차형 프로그래밍 

  • 로직이 수행되어야 할 연속적인 계산 과정으로 이뤄짐
  • ex. 포트란(fortran)을 이용한 대기 과학 관련 연산 작업, 머신 러닝의 배치 작업
  • (+) 코드 가독성 좋음, 실행 속도 ↑
  • (-) 모듈화하기 어려움, 유지 보수성 ↓

      
const ret = [1, 2, 3, 4, 5, 11, 12]
let a = 0
for (let i = 0; i < ret.legnth; i++) {
a = Math.max(ret[i], a)
}
console.log(a) // 12
728x90
반응형
kimmeoww