1. component-scan

- spring 2.5 버전에 출시

- 2.5 버전 이전엔 xml file 에 모든 bean 을 설정해야 했는데, component-scan 이 xml 내의 bean 설정 양을 줄여줬다

- @Component, @Repository, @Service, @Controller 어노테이션을 스캔한다

- @Autowired, @Qualifier 어노테이션도 해석

- component-scan 이 선언되어있다면 annotation-config 는 필요없음

 

2.annotation-driven

- annotation-driven 은 spring mvc 컴포넌트를 활성화

- annotation-driven 을 포함하지 않아도 component-scan을 사용하여 Bean을 생성한 경우 mvc application은 동작

- annotation-driven은 구성되지 않은 특정 빈을 구성하는데 추가 작업을 수행

- @Controller 에 요청을 하기 위해 필요한 HandlerMapping, HandlerAdapter 을 등록

- @Number로 숫자 필드 지원 , classPath에 Jackson이 있는 경우 JSON 쓰기 읽기를 지원 와 같은 작업 적용

 

3. annotation-config

- 어플리케이션 context에 이미 등록되어 있는 (xml에 선언돼있거나 package scanning 으로 검색된) 어노테이션 빈을 활성화

- 스프링 컨텍스트에 의해 생성 및 저장된 빈에 대해 @Autowired, @Qualifier 어노테이션을 해석

- component-scan 또한 같은 일을 하지만, annotation-config 는 빈을 찾아 등록해주진 않는다. 이미 등록이 끝난 bean 들을 활성화할 할 뿐이다.

 

※ annotation-config 만 설정에 잡혀있을 경우, Bean 이 스캔에 의해 자동으로 등록되지 않으므로 xml 에 Bean 설정을 해주어야 함. 현재 개발중인 배치서버 설정에 빈이 자동으로 잡히지 않아 찾아보니 annotation-config 설정만 잡혀있고, component-scan 혹은 annotation-driven 은 잡혀있지 않았음.

 

참고 및 해석 : https://javabeat.net/spring-mvc-component-scan-annotations/ 

반응형

1. #{}

#{}사용시 mybatis 가 preparedStatement 를 생성하고, preparedStatement 매개변수 #{?} 값을 안전하게 셋팅하게 한다.

#{param} 값을 'param' 과 같이 ''로 감싸며 치환한다.

SQL injection 과 같은 공격을 방지할 수 있다. 더 빠르고, 안전하다.

 

1
2
3
4
5
SELECT *
FROM user_info
WHERE 1=1
AND id = #{id}    -- #{id} >> 'developyo@tistory.com'
AND pw = #{pw}    -- #{pw} >> '1234'
cs

 

2. ${}

${} 사용시 ${param} 값을 param 과 같이 '' 로 감싸지 않은채 치환한다.

SQL injection 과 같은 공격을 받을 수 있다.

직접적인 값 셋팅(ORDER BY 절의 기준 칼럼을 동적으로 지정하고 싶은 경우 등)이 필요한 경우 사용할 수 있다.

1
2
3
SELECT *
FROM user_info
ORDER BY ${columnName} -- ${columnName} >> join_date
cs

 

 

[ SQL injection 공격의 예 ]

1. #{} 사용

id 파라미터로 developyo@tistory.com

pw 파라미터로 '1' OR 1=1 

1
2
3
4
5
SELECT *
FROM user_info
WHERE 1=1
AND id = 'developyo@tistory.com'
AND pw = ''1' OR 1=1'
cs

: sql Exception 발생

 

2. ${} 사용

id 파라미터로 'developyo@tistory.com'

pw 파라미터로 '1' OR 1=1 

1
2
3
4
5
SELECT *
FROM user_info
WHERE 1=1
AND id = 'developyo@tistory.com'
AND pw = '1' OR 1=1
cs

: 조회 성공

 

※ 만약 ${}을 사용할 경우 SQL injection 공격을 막기위해 이스케이프 처리가 필요하다.

 

참고 : https://stackoverflow.com/questions/39954300/when-to-use-vs

반응형

- 자바스크립트에서 원시 타입을 제외한 모든 나머지 값들(함수 배열 정규표현식 등)은 객체.
- 객체는 key 와 value 로 구성된 property 의 집합
- 프로퍼티 값이 함수인 경우 일반 함수와 구분하기 위해 메소드라 부름 (자바스크립트의 함수는 일급객체(참고)이므로 값으로 취급 가능)
- 객체는 데이터를 의미하는 프로퍼티와 데이터를 참조하고 조작할 수 있는 동작(메소드)로 구성된 집합
- 프로퍼티 및 메소드를 모두 포함할 수 있어 하나의 단위로 구조화하기 유용
- 프로토타입을 상속받아 객체지향의 상속을 구현한다

[프로퍼티]
- 프로퍼티 키를 중복 선언시 나중에 선언한 프로퍼티가 먼저 선언한 프로퍼티를 덮어씀
- 프로퍼티간 순서를 보장하지 않음

[메소드]
- 프로퍼티 값이 함수인 경우 메소드라 부름
- 객체에 제한되어 있는 함수를 의미

[객체 생성 방법]
1. 객체 리터럴
- 중괄호 사용하여 생성
- 비어있는 객체 생성 가능 ex) var empty = {};

1
2
3
4
5
6
7
var person = { 
    name : 'Lee'
    gender : 'male'
    sayHello : function(){ 
        console.log('My name is' + this.name); 
    } 
cs

 

2. Object 생성자 함수
- new 연산자와 Object 생성자 함수를 호출하여 빈 객체 생성 가능
- 생성자 함수의 이름은 파스칼 케이스를 사용하는게 일반적
- 객체가 소유하고 있지 않은 프로퍼티 키에 값을 할당하면 해당 객체에 프로퍼티를 추가하고 값을 할당, 이미 존재하는 프로퍼티 키에 새로운 값을 할당하면 해당 값으로 변경
* Object 생성자 함수 사용보단 객체 리터럴 사용 (객체 리터럴 사용시 내부적으로 Object 생성자 함수를 사용하여 객체를 생성하므로)

3. 생성자 함수
프로퍼티 값만 다른 객체를 여러개 생성할 때 객체 리터럴 및 Object 생성자 함수를 사용한다면 아래와 같이 코드량이 많아지고 불편

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var person1 = { 
    name : 'Lee'
    gender : 'male'
    sayHello : function(){ 
        console.log('My name is' + this.name); 
    } 
var person2 = { 
    name : 'Kim'
    gender : 'female'
    sayHello : function(){ 
        console.log('My name is' + this.name); 
    } 
cs

이를 아래와 같이 생성자 함수를 사용하면 간편

1
2
3
4
5
6
7
8
9
10
11
function Person(name, gender){ 
    this.name = name
    this.gender = gender; 
    this.sayHello = function(){ 
        console.log('Hi! My name is ' + this.name); 
    } 
var person1 = new Person('Lee''male'); 
var person2 = new Person('Kim''female'); 
person1.sayHello(); 
person2.sayHello(); 
cs

- 생성자 함수명은 대문자로 시작하여 생성자임을 인식하도록 도움을 줌
- 프로퍼티 또는 메소드 앞에 기술한 this는 생성할 인스턴스(비어있는 새로운 객체)를 의미(new 연산자와 함께 함수를 호출시 this 바인딩이 다르게 동작)
- this 에 바인딩되어있는 프로퍼티와 메소드는 외부에서 참조가 가능, 생성자 함수 내에서 선언된 일반 변수는 외부에서 참조 불가 : 생성자 함수 내부에서 자유롭게 접근이 가능하나 외부에서 접근은 불가 (아래 참고)

1
2
3
4
5
6
7
8
9
10
11
function Person(name, gender){ 
    var married = true
    this.name = name
    this.gender = gender; 
    this.sayHello = function(){ 
        console.log('Hi! My name is ' + this.name); 
    } 
var person = new Person('Lee''male'); 
console.log(person.gender); // 'male' 
console.log(person.married); // 'undefined' 
cs

※ 자바의 생성자와 다르게 형식이 정해져 있지 않고, 기존 함수와 동일한 방법으로 선언하고 new 연산자를 붙여 호출하면 생성자 함수로 동작
 생성자 함수가 아닌 일반 함수에 new 연산자를 붙일 경우 생성자 함수처럼 동작 가능하다는 것을 의미. 따라서 생성자 함수의 첫문자는 대문자로 명명하여 혼란 야기를 방지
new 연산자와 함께 함수를 호출하면 this 바인딩이 다르게 동작


[ new 연산자와 함께 생성자 함수 호출시 동작 순서 ]
1. 빈 객체 생성 및 this 바인딩 
- 생성자 함수의 코드가 실행되기 전 비어있는 객체가 생성된다
- 생성자 함수 내에서 사용하는 this 는 이 비어있는 객체를 가리킨다.
- 생성된 빈 객체의 프로토타입 객체는 생성자 함수의 prototype 프로퍼티가 가리키는 객체.
2. this를 통한 프로퍼티 생성
- 생성된 빈 객체에 this를 사용하여 프로퍼티나 메소드 생성 가능
3. 생성된 객체 반환
- this 에 바인딩된 객체 자동 반환


[ 객체 프로퍼티 선언 및 접근 ]
[ 프로퍼티 키 선언 ]
- 프로퍼티 키에 표현식(- 연산자 등)이 존재하는 경우 대괄호로 묶어야 함 otherwise, ReferenceError 발생, 예약어는 당연히 사용하면 안된다
ex: var person = {first-name : 'gildong'} >> ReferenceError

[ 프로퍼티 키 접근 ]
- 마짐표 . 표기법: 프로퍼티 키가 유효(표현식(- 연산자 등)이 있는 경우 무효), 예약어가 아닌 경우 마침표/대괄호 표기법 모두 사용 가능
- 대괄호 [] 표기법: 프로퍼티 키가 유효한 값이 아니거나, 예약어인 경우 대괄호 내에 들어가는 프로퍼티 이름은 반드시 문자열이어야 함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var person = { 
 'first-name''gildong'
  'last-name''Hong'
  gender: 'male'
  110 
console.log(person.first-name); // NaN : undefined - undefined  
console.log(person[first-name]); // ReferenceError 
console.log(person['first-name']); // 'gildong' 대괄호 표기법 대괄호 안이 반드시 문자열, 유효하지 않은 프로퍼티 키는 대괄호를 사용하여 읽음  
console.log(person.gender); // 'male' 유효한 프로퍼티 키는 대괄호, 마짐표 표기법 모두를 사용하여 읽기 가능 
console.log(person[gender]); // ReferenceError 
console.log(person['gender']); // 'male' 대괄호 표기법 대괄호 안이 반드시 문자열, 유효한 프로퍼티 키는 대괄호, 마짐표 표기법 모두를 사용하여 읽기 가능 
console.log(person['1']); //10 대괄호 표기법 대괄호 안이 반드시 문자열, 유효하지 않은 프로퍼티 키는 대괄호를 사용하여 읽음  
console.log(person[1]); //10 
console.log(person.1); //SyntaxError 
cs


[ 프로퍼티 값 수정 ]
- 객체가 갖고 있는 프로퍼티에 새로운 값 할당시 값이 수정됨 
ex) person.gender = 'female';

[ 프로퍼티 생성 ]
- 객체가 소유하고 있지 않은 프로퍼티 키와 값 할당시 새로운 프로퍼티 추가됨
ex) person.age = 30;

[ 프로퍼티 삭제 ]
- delete 키워드를 사용하여 객체 프로퍼티를 삭제, 이때 피연산자는 프로퍼티 키.
ex) delete person.gender;

[ 프로퍼티 값 출력 ]

1
2
3
4
5
6
for(var prop in person){ 
    console.log(prop + ':' +person[prop]); 
for(var idx in array){ 
    console.log(idx + ":" +array[idx]); 
cs

- for in문 사용하여 객체에 포함된 모든 프로퍼티 루프 출력이 가능
- for in문은 array 에서 사용을 삼가. 배열 요소만을 순회하지 않음
for of 사용 (ES6) 

[ pass by reference ]
객체 타입은 원시타입과 달리 동적으로 변화할 수 있으며 어느정도 메모리 공간을 확보해야 하는지 예측 불가하기 때문에 런타임에 메모리 공간을 확보하고 메모리의 힙영역에 저장된다. 

1
2
3
4
5
6
7
var foo = { 
    val : 10 
var bar = foo; 
console.log(foo.val, bar.val); // 10 10 
bar.val = 20
console.log(foo.val, bar.val); // 20 20 
cs

(위의 두 변수 모두 동일한 객체의 참조주소를 참조한다 (java의 참조객체와 동일))

참고 : https://poiemaweb.com/js-object#2-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1-%EB%B0%A9%EB%B2%95

반응형

github repository를 생성한 후, 매일 공부한 내용 중 일부를 커밋하고 있다.

1년 뒤 초록색으로 가득한 contribution chart를 기대하며 1일 1커밋을 실천하였으나, 

커밋을 아무리 해도 차트 셀의 색이 바뀌질 않았다.

 

github 사이트 내에서 레파지토리를 생성한다거나 커밋한 파일을 직접 삭제하면 색이 바뀌는데,

eclipse 에서 commit/push 할 경우 commit 기록엔 남게되나 차트 셀의 색이 바뀌지 않았다.

(혹시 몰라 sourcetree 도 사용해 보았지만 똑같았다)

 

위 이미지에서 Learn how we count contributions 링크를 통해 확인한 github 의 커밋(푸시)집계기준을 확인했으나 도저히 문제 파악이 되지 않았다.

 

문제는 로컬 git config 설정에 있었다.

.git/config 파일에 아래와 같이 본인이 사용중인 github 사용자 이름, email 정보를 넣어주자.

[git bash 를 사용하지 않는 경우]

[user]
name = develo-pyo
email = jungpyo9@gmail.com

[git bash 사용시]

1) repository 디렉토리로 이동

2)

>git config user.name "develo-pyo"

>git config user.email "jungpyo9@gmail.com"

혹은

>git config --global user.name "develo-pyo"

>git config --global user.email "jungpyo9@gmail.com"

※ repository 별 유저명, 메일주소 설정이 글로벌 유저명, 메일주소 설정보다 우선시 된다.

 

※ config 파일

  • /etc/gitconfig 파일: 시스템의 모든 사용자와 모든 저장소에 적용되는 설정이다. git config --system 옵션으로 이 파일을 읽고 쓸 수 있다. (git config --list 로 설정된 config 읽기 가능)
  • ~/.gitconfig 파일: 특정 사용자에게만 적용되는 설정이다. git config --global 옵션으로 이 파일을 읽고 쓸 수 있다.
  • .git/config: 이 파일은 Git 디렉토리에 있고 특정 저장소(혹은 현재 작업 중인 프로젝트)에만 적용된다. 각 설정은 역순으로 우선시 된다. 그래서 .git/config가 /etc/gitconfig보다 우선한다.

eclipse/sts git plugin 및 sourcetree 로 github 사용시 .git/config 파일만 생성되는 듯 하다.

 

 

참고 : https://alvinalexander.com/git/git-show-change-username-email-address

참고 : https://confluence.atlassian.com/bitbucket/configure-your-dvcs-username-for-commits-950301867.html

 

반응형

트리 구조에서 각각의 노드를 단 한 번만, 체계적인 방법으로 방문하는 과정

 

전위 순회(=깊이 우선 순회) : F, B, A, D, C, E, G, I, H (root, left, right)

중위 순회(=대칭 순회) : A, B, C, D, E, F, G, H, I (left, root, right)

후위 순회 : A, C, E, D, B, H, I, G, F (left, right, root)

레벨 순서 순회(=너비 우선 순회) : F, B, G, A, D, I, C, E, H

 

 

 

 

 

 

반응형

개발자로 진로를 틀게 된 후, 처음으로 읽은 자기계발서.

읽은지 2년이 다 되어가는 책.

개발자로 살아온 지난 2.5년을 돌아볼겸, TRUE 개발자의 자세로 다시금 정신무장 할 겸 정리해본다.

 

부숴도 괜찮은 장난감
장난감 프로젝트를 만들어 보아라

흰띠를 매라
새로운 것을 습득할 땐 기존의 것을 내려놓자
머리를 비워야 채울 수 있다

열정을 드러내라
팀에 맞추기 위해 개발에 대한 흥분과 열정을 숨기지 말라
팀에 열정을 불어넣고 모든 것에 질문하라
팀이 열정을 받아주지 못한다면 열정을 키울 다른 방법을 찾아라.

무지를 드러내라
다른 사람들이 내가 잘 모른다고 생각하는 것을 두려워 말라. 모르는 것을 질문하라

무지에 맞서라
빈틈을 능동적으로 메우자
무지함을 인지하면서도 그에 맞서지 않는 부류("잘은 모르지만 이렇게 하면 되잖아?")에 속하지 말자

깊은 쪽
어려운 문제가 주어진다면 그 기회를 잡아라
두려운 일을 맡고 해결을 하면서 성장 할 수 있다.
실패한다 해도 그 실패 속에서 경험치가 쌓인다

한 발 물러서라
너무나 부족한 나 자신을 발견하면, 압도됨을 느낄 때가 있다.
이 땐 익숙한 능력으로 돌아가라.
익숙한 코드를 짜며 힐링하라.

비교적 잘 해온 것들 : 한 발 물러서라, 깊은 쪽, 무지를 드러내라, 무지에 맞서라, 열정을 드러내라

비교적 잘 못 해온 것들 : 부숴도 괜찮은 장난감, 흰띠를 매라

 

Spring Boot + JPA 위에서 동작하는 게시판(TDD 개발) 형태의 부숴도 괜찮은 장난감부터 만들어봐야지

 

반응형

'etc. > books' 카테고리의 다른 글

[Book] HTTP 완벽 가이드  (0) 2020.03.17
[Book] 객체지향의 사실과 오해  (0) 2020.02.23
[Book] 소프트웨어 장인  (0) 2020.01.16
[Book] Clean Code (클린 코드)  (0) 2019.12.28
[Book] Head First : Design Patterns  (2) 2019.06.04

옵저버 패턴에서는 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다 의존성을 정의한다. (Head First Design Pattern 내용 발췌)

Subject(주제) 객체에 변화가 일어날 경우 Subject에 의존하고 있는 다수의 Observer 에 변화를 알리는 일대다 의존성을 갖는 디자인 패턴. 대표적으로 java.awt 의 listener가 Observer pattern 이라고 할 수 있다.

 

Observer pattern 을 파악하기 위해

java.awt 의 lister 와 Button 을 어설프게나마 직접 구현해보자.

 

[Listener]

Observer 와 같은 역할을 하는 Listener Interface

1
2
3
4
5
6
package design_pattern.observer;
 
public interface Listener {
    public void performAction();
}
 
cs

 

[CustomListener1]

Observer 를 구현한 CustomListener1

performAction() 은 주제 객체의 변화가 일어났을 때 호출이 되는 메소드

1
2
3
4
5
6
7
8
9
package design_pattern.observer;
 
public class CustomListener1 implements Listener {
    @Override
    public void performAction() {
        System.out.println("custom listener1 perform action !");
    }
}
 
cs

 

[Component]

주제 인터페이스 Component

1
2
3
4
5
6
7
8
package design_pattern.observer;
 
public interface Component {
    public void addListener(Listener l);
    public void removeListener(Listener l);
    public void notifyListeners();
}
 
cs

 

[Button]

주제 인터페이스를 구현한 주제 객체 Button

Observer 역할을 하는 listeners 를 멤버변수로 갖고 있다(구상)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package design_pattern.observer;
 
import java.util.ArrayList;
 
public class Button implements Component {
    
    private ArrayList<Listener> listeners;
    
    public Button() {
        this.listeners = new ArrayList<Listener>();
    }
    
    @Override
    public void addListener(Listener l) {
        listeners.add(l);
        System.out.println("listener added!");
    }
 
    @Override
    public void removeListener(Listener l) {
        int idx = listeners.indexOf(l);
        listeners.remove(idx);
        System.out.println("listener removed!");
    }
 
    @Override
    public void notifyListeners() {
        for(Listener l : listeners) {
            l.performAction();
        }
    }
    
    public void buttonClicked() {
        notifyListeners();
    }
    
}
 
cs

 

[Main]

Listener 를 익명클래스로 구현 후 customListeners2 변수로 선언하였다.

Listener(Observer) 두개를 Button(주제) 객체에 등록(addListener)해주었고,

실제 Button 을 클릭 해 볼 수 없으니,

마치 버튼을 클릭 한 것 처럼 버튼객체의 buttonClicked() 메소드를 호출해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package design_pattern.observer;
 
import java.awt.TextField;
import java.awt.event.ActionListener;
 
public class Main {
 
    public static void main(String[] args) {
        
        Button btn = new Button();
        
        Listener customListener1 = new CustomListener1();
        
        Listener customListener2 = new Listener() {
            @Override
            public void performAction() {
                System.out.println("custom listener2 perform action !");
            }
        };
        
        btn.addListener(customListener1);
        btn.addListener(customListener2);
        
        btn.buttonClicked();
        
        System.out.println("----------------------------");
        
        btn.removeListener(customListener2);
        
        System.out.println("----------------------------");
        btn.buttonClicked();
        
    }
    
}
 
cs

 

실행 결과

listener added!
listener added!
custom listener1 perform action !
custom listener2 perform action !
----------------------------
listener removed!
----------------------------
custom listener1 perform action !

 

반응형

"어떤 서브시스템의 일련의 인터페이스에 대한 통합된 인터페이스 제공.

퍼사드에서 고수준 인터페이스를 정의하기 때문에 서브시스템을 더 쉽게 사용할 수 있다."

 

사용할 메소드가 여러 클래스에 퍼져 있는 경우

필요한 클래스들을 모두 생성자로 생성하여 필요한 메소드를 각각 호출 하는 대신,

(최소 지식 원칙 (의존하는 클래스의 갯수를 최대한 적게) 위배)

별도의 클래스(퍼사드)에 사용할 클래스들을 멤버변수로 담고,

사용하고자 하는 멤버변수의 메소드들을 한곳에 묶은 새로운 메소드를 작성한다.

 

예를 들어, 메일 전송 로직을 다음과 같이 구현한다고 하자.

1. 수신인의 메일주소를 확인한다.

2. 메일을 전송한다.

3. 메일 전송 결과를 이력에 남긴다.

위 기능들이 각각 다른 클래스에 존재하는 메소드라고 한다면

위 세 기능을 묶은 하나의 메소드를 작성하여, 메인시스템에선 해당 메소드(서브시스템)만 호출한다.

 

[ValidationService class]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package design_pattern.fasade;
 
public class ValidationService {
    
    String mailAddr = "";
    
    public ValidationService(String addr){
        this.mailAddr = addr;
    }
    
    public boolean addrChk() {
        if(!mailAddr.isEmpty()) {
            System.out.println("mail validation check success!");
            return true;
        }
        return false;
    }
    
}
 
cs

 

[MailService class]

1
2
3
4
5
6
7
8
package design_pattern.fasade;
 
public class MailService {
    public void mailSend() {
        System.out.println("mail has been sent");
    }
}
 
cs

 

[HstService class]

1
2
3
4
5
6
7
8
package design_pattern.fasade;
 
public class HstService {
    public void hstSave() {
        System.out.println("sent mail saved");
    }
}
 
cs

 

[Facade.class]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package design_pattern.fasade;
 
public class Facade {
    private ValidationService vs;
    private MailService ms;
    private HstService hs;
    
    public Facade(ValidationService vs, MailService ms, HstService hs) {
        this.vs = vs;
        this.ms = ms;
        this.hs = hs;
    }
    
    public void facadeFunc() {
        if(vs.addrChk()) {
            ms.mailSend();
        } 
        hs.hstSave();
    }
}
 
cs

주시스템에서 사용하고자 하는 서브시스템들을 멤버변수로.

멤버변수 내에서 사용할 메소드들을 따로 모은, 새로운 메소드 구현(facadeFunc())

 

[main]

1
2
3
4
5
6
7
8
9
10
11
12
13
package design_pattern.fasade;
 
public class Main {
    
    public static void main(String args[]) {
        Facade f = new Facade(new ValidationService("receiver@gmail.com")
                            , new MailService()
                            , new HstService());
        f.facadeFunc();
    }
    
}
 
cs

 

디자인 패턴 중 가장 단순한(이해하기 쉬운..) 구조이며 가장 많이 쓰이는 패턴 중 하나

반응형

이상하게 라디오 관련 처리는 매번 할 때마다 바로바로 기억이 안나 정리해둔다.

 

[HTML]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<ul>
    <li>
        <input type="radio" id="type" name="type" value="1"><label for="type1">radio1</label>
        <input type="text" id="type_val" name="type_val" />
    </li>
    <li>
        <input type="radio" id="type" name="type" value="2"><label for="type2">radio2</label>
        <input type="text" id="type_val" name="type_val" />
    </li>
    <li>
        <input type="radio" id="type" name="type" value="3"><label for="type3">radio3</label>
        <input type="text" id="type_val" name="type_val" />
    </li>
</ul>
cs

 

[script]

1
2
3
4
5
6
7
8
9
$('input[type=radio][name=type]').change(function(){
    var arr = $('input[type=radio][name=type]');
    console.log($(this).val())
    for(var i=0; i<arr.length; i++){
        if($(this).val() != $(arr[i]).val()){
            $(arr[i]).siblings('input').val("");
        }
    }
});
cs

2번라인의 arr 은 radio 엘리먼트 배열이 들어가게 된다.

반복문을 돌려 this (현재 선택된 radio) 의 value 와 같지 않은 input value 는 비워준다.

※ 변수를 $() 로 감싸주면 javascript 변수가 jQuery 변수로 변환된다.

 

※ radio 버튼 강제 선택시키기

$("input:radio[name=radioGrp]:radio[value='U']").prop("checked", true);

참고

 

반응형

javascript 는 일부 에러를 무시하고 실행이 가능하다.

에러가 존재해도 동작한다는 이점이 있으나, 개발자의 디버깅을 더 힘들게 한다는 단점도 존재한다.

 

[ strict mode ? ]

ECMAScript5 에 추가된 기능으로써 에러를 더 엄격히 제한하는 기능.

사용법은 어렵지 않지만,

strict 사용시 기존에 묵인되던 에러들이 에러를 뿜게되니 관련부분은 나중에 정리.

 

참고 : https://www.geeksforgeeks.org/strict-mode-javascript/

 

반응형

+ Recent posts