1) 개념
2) axios 라이브러리 사례
axios.get('/user?ID=12345')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
<script>
export default {
data() {
return {
count: 0
}
}
}
</script>
<template>
<button @click="count++">Count is: {{ count }}</button>
// count 변수 ++하기 위해서는 date(){ 메서드 안에 변수 선언해야 하는 규칙
</template>
<style scoped> // scoped라는 것을 통해 해당 컴포넌트기반에서만 작동되는 style
button {
font-weight: bold;
}
</style>
📖 참고 📖 디자인 패턴
- ✏️ 개념
- 프로그램을 설계할 때 발생했던 문제점들을 객체 간의 상호관계를 이용하여 해결할 수 있도록 규약 형태로 만들어 놓은 것
- 라이브러리, 프레임워크가 어떠한 디자인패턴을 기반으로 만들어짐
- 🗒️ 예시 : 전략패턴이 들어간 Passport.js 라이브러리
- ✏️ 생성 패턴
- 객체 생성 방법이 들어간 디자인 패턴
- 싱글톤, 팩토리, 추상팩토리, 빌더, 프로토타입 패턴이 있음
- ✏️ 구조 패턴
- 객체, 클래스 등으로 큰 구조를 만들 때 유연하고 효율적으로 만드는 방법이 들어간 디자인 패턴
- 프록시, 어댑터, 브리지, 복합체, 데코레이터, 퍼사드, 플라이웨이트페턴
- ✏️ 행동 패턴
- 객체나 클래스 간의 알고리즘, 책임 할당에 관한 디자인 패턴
- 이터레이터, 옵저버, 전략, 책임연쇄, 커맨드, 중재자, 메멘토, 상태, 템플릿메서드, 비지터 패턴
- ✏️ flux 패턴, MVC 패턴, MVVM 패턴
📖 참고 📖 TDD (Test Driven Development, 테스트 주도 개발)
- 반복 테스트를 이용한 소프트웨어 방법론
- 작은 단위의 테스트 케이스를 작성하고, 이를 통과하는 코드를 추가하는 단계를 반복하여 구현
- 애자일 방법론 중 하나인 eXtream Programming(XP)의 ‘Test-First’ 개념에 기반을 둔 단순한 설계
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
const a = new Rectangle(1, 2)
const b = new Rectangle(1, 2)
console.log(a === b) // false
class Singleton {
constructor() {
if (!Singleton.instance) {
Singleton.instance = this
}
return Singleton.instance
}
getInstance() {
return this
}
}
const a = new Singleton()
const b = new Singleton()
console.log(a === b) // true
const URL = 'mongodb://localhost:27017/kundolapp'
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
Mongoose.prototype.connect = function (uri, options, callback) {
const _mongoose = this instanceof Mongoose ? this : mongoose;
const conn = _mongoose.connection;
return _mongoose._promiseOrCallback(callback, cb => {
conn.openUri(uri, options, err => {
if (err != null) {
return cb(err);
}
return cb(null, _mongoose);
});
});
};
// 메인 모듈
const mysql = require('mysql');
const pool = mysql.createPool({
connectionLimit: 10,
host: 'example.org',
user: 'kundol',
password: 'secret',
database: '승철이디비'
});
pool.connect();
// 모듈 A
pool.query(query, function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
// 모듈 B
pool.query(query, function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
class Singleton {
private static class singleInstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return singleInstanceHolder.INSTANCE;
}
}
public class HelloWorld{
public static void main(String []args){
Singleton a = Singleton.getInstance();
Singleton b = Singleton.getInstance();
System.out.println(a.hashCode());
System.out.println(b.hashCode());
if (a == b){
System.out.println(true);
}
}
}
/*
705927765
705927765
true
1. 클래스안에 클래스(Holder), static이며 중첩된 클래스인 singleInstanceHolder를
기반으로 객체를 선언했기 때문에 한 번만 로드되므로 싱글톤 클래스의 인스턴스는
애플리케이션 당 하나만 존재하며
클래스가 두 번 로드되지 않기 때문에 두 스레드가 동일한 JVM에서 2개의 인스턴스를 생성할
수 없습니다.
그렇기 때문에 동기화, 즉 synchronized를 신경쓰지 않아도 됩니다.
2. final 키워드를 통해서 read only 즉, 다시 값이 할당되지 않도록 했습니다.
3. 중첩클래스 Holder로 만들었기 때문에 싱글톤 클래스가 로드될 때 클래스가 메모리에
로드되지 않고
어떠한 모듈에서 getInstance()메서드가 호출할 때 싱글톤 객체를 최초로 생성 및 리턴하게
됩니다.
*/
// npm install -g mocha
// mocha single1.js
const assert = require('assert');
const a = [1, 2, 3]
describe('Array', function () {
describe('#indexOf()', function () {
it('should return -1 when the value is not present', function () {
assert.equal(a.indexOf(4), -1);
a[0] = 4;
});
});
describe('#indexOf()', function () {
it('should return -1 when the value is not present', function () {
assert.equal(a.indexOf(4), -1);
});
});
});
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
// thread.java
public class YunhaSync {
private static String yunha = "오르트구름";
public static void main(String[] agrs) {
YunhaSync a = new YunhaSync();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
a.say("사건의 지평선");
}
}).start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
a.say("오르트 구름");
}
}).start();
}
public void say(String song) {
yunha = song;
try {
long sleep = (long) (Math.random() * 100);
Thread.sleep(sleep);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!yunha.equals(song)) {
System.out.println(song + " | " + yunha);
}
}
}
// thread2.java
public class YunhaSync {
private static String yunha = "오르트구름";
public static void main(String[] agrs) {
YunhaSync a = new YunhaSync();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
a.say("사건의 지평선");
}
}).start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
a.say("오르트 구름");
}
}).start();
}
public synchronized void say(String song) {
yunha = song;
try {
long sleep = (long) (Math.random() * 100);
Thread.sleep(sleep);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!yunha.equals(song)) {
System.out.println(song + " | " + yunha);
}
}
}
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
public class Singleton {
private final static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
public class Singleton {
private static Singleton instance = null;
static {
instance = new Singleton();
}
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
class Singleton {
private static class singleInstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return singleInstanceHolder.INSTANCE;
}
}
public class Singleton {
private volatile Singleton instance;
private Singleton() {
}
public Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
public class Test {
boolean flag = true;
public void test() {
new Thread(()->{
int cnt = 0;
while (flag) {
cnt++;
}
System.out.println("Thread1 finished\n");
}
).start();
new Thread(()-> {
try {
Thread.sleep(100);
} catch (InterruptedException ignored) {
}
System.out.println("flag to false");
flag = false;
}
).start();
}
public static void main(String[] args) {
new Test().test();
}
}
public enum SingletonEnum {
INSTANCE;
public void oortCloud() {
}
}
class CoffeeFactory {
static createCoffee(type) {
const factory = factoryList[type]
return factory.createCoffee()
}
}
class Latte {
constructor() {
this.name = "latte"
}
}
class Espresso {
constructor() {
this.name = "Espresso"
}
}
class LatteFactory extends CoffeeFactory{
static createCoffee() {
return new Latte()
}
}
class EspressoFactory extends CoffeeFactory{
static createCoffee() {
return new Espresso()
}
}
const factoryList = { LatteFactory, EspressoFactory }
const main = () => {
// 라떼 커피를 주문한다.
const coffee = CoffeeFactory.createCoffee("LatteFactory")
// 커피 이름을 부른다.
console.log(coffee.name) // latte
}
main()
enum CoffeeType {
LATTE,
ESPRESSO
}
abstract class Coffee {
protected String name;
public String getName() {
return name;
}
}
class Latte extends Coffee {
public Latte() {
name = "latte";
}
}
class Espresso extends Coffee {
public Espresso() {
name = "Espresso";
}
}
class CoffeeFactory {
public static Coffee createCoffee(CoffeeType type) {
switch (type) {
case LATTE:
return new Latte();
case ESPRESSO:
return new Espresso();
default:
throw new IllegalArgumentException("Invalid coffee type: " + type);
}
}
}
public class Main {
public static void main(String[] args) {
Coffee coffee = CoffeeFactory.createCoffee(CoffeeType.LATTE);
System.out.println(coffee.getName()); // latte
}
}
📖 참고 📖 컨테이너
- 동일한 요소들을 담아놓은 집합
- 🗒️ 예시 : 배열, 맵
const mp = new Map()
mp.set('a', 1)
mp.set('b', 2)
mp.set('cccc', 3)
const st = new Set()
st.add(1)
st.add(2)
st.add(3)
const a = []
for(let i = 0; i < 10; i++)a.push(i)
for(let aa of a) console.log(aa)
for(let a of mp) console.log(a)
for(let a of st) console.log(a)
/*
0
1
2
3
4
5
6
7
8
9
[ 'a', 1 ]
[ 'b', 2 ]
[ 'cccc', 3 ]
1
2
3
*/
import java.util.*;
class B {
public void go() {
System.out.println("B의 go()함수");
}
}
class A {
public void go() {
new B().go();
}
}
public class main{
public static void main(String args[]) {
new A().go();
}
}
// B의 go()함수
import java.util.*;
class BackendDeveloper {
public void writeJava() {
System.out.println("자바가 좋아 인터네셔널~");
}
}
class FrontEndDeveloper {
public void writeJavascript() {
System.out.println("자바스크립트가 좋아 인터네셔널~");
}
}
public class Project {
private final BackendDeveloper backendDeveloper;
private final FrontEndDeveloper frontEndDeveloper;
public Project(BackendDeveloper backendDeveloper, FrontEndDeveloper frontEndDeveloper) {
this.backendDeveloper = backendDeveloper;
this.frontEndDeveloper = frontEndDeveloper;
}
public void implement() {
backendDeveloper.writeJava();
frontEndDeveloper.writeJavascript();
}
public static void main(String args[]) {
Project a = new Project(new BackendDeveloper(), new FrontEndDeveloper());
a.implement();
}
}
interface Developer {
void develop();
}
class BackendDeveloper implements Developer {
@Override
public void develop() {
writeJava();
}
public void writeJava() {
System.out.println("자바가 좋아~ 새삥새삥");
}
}
class FrontendDeveloper implements Developer {
@Override
public void develop() {
writeJavascript();
}
public void writeJavascript() {
System.out.println("자바스크립트가 좋아~ 새삥새삥");
}
}
public class Project {
private final List<Developer> developers;
public Project(List<Developer> developers) {
this.developers = developers;
}
public void implement() {
developers.forEach(Developer::develop);
}
public static void main(String args[]) {
List<Developer> dev = new ArrayList<>();
dev.add(new BackendDeveloper());
dev.add(new FrontendDeveloper());
Project a = new Project(dev);
a.implement();
}
}
📖 참고 📖 마이그레이션
- 데이터나 소프트웨어를 다른 운영환경으로 옮기는 것
- DB이동, 데이터 이동 등
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
interface PaymentStrategy {
public void pay(int amount);
}
class KAKAOCardStrategy implements PaymentStrategy {
private String name;
private String cardNumber;
private String cvv;
private String dateOfExpiry;
public KAKAOCardStrategy(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 +" paid using KAKAOCard.");
}
}
class LUNACardStrategy implements PaymentStrategy {
private String emailId;
private String password;
public LUNACardStrategy(String email, String pwd){
this.emailId=email;
this.password=pwd;
}
@Override
public void pay(int amount) {
System.out.println(amount + " paid using LUNACard.");
}
}
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<Item>();
}
public void addItem(Item item){
this.items.add(item);
}
public void removeItem(Item item){
this.items.remove(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("kundolA",100);
Item B = new Item("kundolB",300);
cart.addItem(A);
cart.addItem(B);
// pay by LUNACard
cart.pay(new LUNACardStrategy("kundol@example.com", "pukubababo"));
// pay by KAKAOBank
cart.pay(new KAKAOCardStrategy("Ju hongchul", "123456789", "123", "12/01"));
}
}
/*
400 paid using LUNACard.
400 paid using KAKAOCard.
*/
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);
});
}
));
import java.util.ArrayList;
import java.util.List;
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 (!observers.contains(obj)) observers.add(obj);
}
@Override
public void unregister(Observer obj) {
observers.remove(obj);
}
@Override
public void notifyObservers() {
this.observers.forEach(Observer::update);
}
@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!!
*/
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}가 [${prev}] >> [${value}] 로 변경되었습니다`)
}
return true
}
})
return proxy
}
const a = {
"형규" : "솔로"
}
const b = createReactiveObject(a, console.log)
b.형규 = "솔로"
b.형규 = "커플"
// 형규가 [솔로] >> [커플] 로 변경되었습니다
1) 개념
2) 모델
3) 뷰
4) 컨트롤러
5) 장점
6) 단점
7) Spring의 MVC패턴 적용
@RequestMapping(value = "/ex/foos", method = POST)
@ResponseBody
public String postFoos() {
return "Post some Foos";
}
1) Action
2) Dispatcher
3) Store
4) View
const initialState = {
visibilityFilter: 'SHOW_ALL',
todos: []
}
function appReducer(state = initialState, action) {
switch (action.type) {
case 'SET_VISIBILITY_FILTER': {
return Object.assign({}, state, {
visibilityFilter: action.filter
})
}
case 'ADD_TODO': {
return Object.assign({}, state, {
todos: state.todos.concat({
id: action.id,
text: action.text,
completed: false
})
})
}
case 'TOGGLE_TODO': {
return Object.assign({}, state, {
todos: state.todos.map(todo => {
if (todo.id !== action.id) {
return todo
}
return Object.assign({}, todo, {
completed: !todo.completed
})
})
})
}
case 'EDIT_TODO': {
return Object.assign({}, state, {
todos: state.todos.map(todo => {
if (todo.id !== action.id) {
return todo
}
return Object.assign({}, todo, {
text: action.text
})
})
})
}
default:
return state
}
}
📖 참고 📖 전략패턴과 의존성주입의 차이
- ✏️ 전략패턴
- 어떠한 동일한 행동 계약을 기반으로 다양한 구현이 명시되어 있는 인터페이스를 만드는 것
- ✏️ 의존성 주입
- 단지 일부 동작을 구현하고 의존성을 주입하기만 하는 패턴
📖 참고 📖 컨텍스트
- ✏️ 의미
- 어떤 종류의 상태, 환경을 캡슐화한 것
- 작업이 중단되고, 나중에 같은 지점에서 계속 될 수 있도록 저장하는 최소 데이터 집합 (ex. context switching)
- ✏️ 구성
- context
- contextual information
- HTTP 요청을 하는 context에서 HTTP Header는 contextual information이라고 할 수 있음
- ✏️ 예시
- context API (react.js에서 context API를 통해 전역적으로 static contextType을 통해 상태 관리)
const ThemeContext = React.createContext('light'); class App extends React.Component { render() { return ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); } } function Toolbar() { return ( <div> <ThemedButton /> </div> ); } class ThemedButton extends React.Component { static contextType = ThemeContext; render() { return <Button theme={this.context} />; } }