plo를 소개 합니다. plo는 간단한 상태관리 컨테이너 입니다.

https://www.npmjs.com/package/plo

 

plo

plain javascript object state container

www.npmjs.com

먼저 state와 getter, setter를 가지고 있는 Object를 선언합니다. 

const object = {
    state: 'hello',
    getState() {
    	return this.state
    },
    setState(state) {
    	this.state = state
    }
}

Object로 model과 subscribe를 생성합니다.

const [model, subscribe] = createModel(object)

model을 구독 합니다.

subscribe(model => {
    console.log(model.getState())
})

완료 되었습니다!

Object에서 선언한 메소드를 호출하기만 하면 됩니다.

model.setState('this is plo')

간단하죠?

리액트와 같이 사용하려면 react-plo를 사용하면 좋습니다.

https://www.npmjs.com/package/react-plo

 

react-plo

```shell npm i react-plo ```

www.npmjs.com

import React from 'react';
import { createModel } from 'plo'
import { connect } from 'react-plo'

const [counterModel, counterSub] = createModel({
  count: 0, 
  getCount() {
    return this.count
  },
  inc() { 
    this.count += 1 
  },
  dec() {
    this.count -= 1
  }
})

function App() {
  return (
    <div>
      <button onClick={counterModel.inc}>+</button>
      <button onClick={counterModel.dec}>-</button>
      count: {counterModel.getCount()}
    </div>
  )
}

export default connect([counterSub])(App)

 

plo와 함께 즐코!

'programing' 카테고리의 다른 글

gitignore 패턴  (0) 2017.07.20
java 정렬하기  (0) 2017.04.03
가상 DOM 이란?  (3) 2016.06.21
클로저 시작하기  (0) 2016.06.09

.gitignore 패턴

* #으로 시작하는 라인은 무시한다.

* 슬래시(/) 로 시작하면 하위 디렉터리에 적용되지(recursivity) 않는다.

* 디렉터리는 슬래시(/)를 끝에 사용하는 것으로 표현한다.

* 느낌표(!)로 시작하는 패턴의 파일은 무시하지 않는다.

* 표준 Glob 패턴을 사용한다.


예제

# 확장자가 .a인 파일 무시

*.a


# 윗 라인에서 확장자가 .a인 파일은 무시하게 했지만 lib.a는 무시하지 않음.

!lib.a


# 현재 디렉터리에 있는 TODO 파일은 무시하고 subdir/TODO처럼 하위 디렉터리에 있는 파일은 무시하지 않음

/TODO


# build/ 디렉터리에 있는 모든 파일은 무시

build/


# doc/notes.text파일은 무시하고 doc/server/arch.txt 파일은 무시하지 않음

doc/*.txt


# doc 디렉터리 아래의 모든  .pdf 파일을 무시

doc/**/*.pdf


출처 progit

'programing' 카테고리의 다른 글

리액트 상태관리를 하는 가장 쉬운 방법 Plo  (0) 2020.03.12
java 정렬하기  (0) 2017.04.03
가상 DOM 이란?  (3) 2016.06.21
클로저 시작하기  (0) 2016.06.09

1. comparable과 comparator

Java 에서 object를 정렬 하기 위해서는 comparable interface 가 기본적으로 필요하다. 

@Test
public void sortObjects() {
    final String[] strings = {"z", "yy", "abc"};
    final String[] expected = {"abc", "yy", "z"};
	
    Arrays.sort(strings);
    assertArrayEquals(expected, strings);
}

String class는 comparable 인터페이스가 implements된 class 이므로 순서대로 정렬된다. 


comparable이 implements되지 않은 object를 sorting 하려고 하면 컴파일러가 comparable interface가 구현되어 있을거라고 예상하기 때문에 exception이 발생한다.

class Obj {
    private int orderNo;
	
    public Obj(int i) {
        this.orderNo = i;
    }

    public int getOrderNo() {
        return this.orderNo;
    }
}

@Test
public void sortNotComparable() {
    final List<Obj> objects = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        objects.add(new obj(i));	
    }
    // java.lang.ClassCastException: Sorting$Obj cannot be cast to java.lang.Comparable
    Arrays.sort(objects.toArray());
}
Comparable interface를 implements해서 compareTo 메소드를 override하면 sorting을 할 수 있다.
class Obj implements Comparable<Obj>{
    private int orderNo;
    ...
    @Override
    public int compareTo(Obj o) {
        return this.orderNo - o.orderNo;
    }
}

하지만 클래스 외부에서 compare 방법을 변경할 수 없기 때문에 보통 comparable을 설명 할때 natural order sorting(예를 들어 id순서나 날짜 순서 같은 자연스러운 sorting)을 구현할때 사용하라고 하는 경우를 볼 수 있다. 우리가 알고 있는 디자인 패턴에 맞는 방법은, 다양한 sorting방법을 변경하면서 사용하는 것인데, 그래서 comparator 가 필요하다.

class CustumOrder implements Comparator {
@Override public int compare(Obj o1, Obj o2) { return o2.getOrderNo() - o1.getOrderNo(); } }

완성된 코드는 아래와 같다.
class Obj {
    private int orderNo;
	
    public Obj(int i) {
        this.orderNo = i;
    }

    public int getOrderNo() {
        return this.orderNo;
    }

    @Override
    public boolean equals(Object other) {
        Obj self = (Obj) other;
        return this.orderNo == self.getOrderNo();
    }
}

class CustumOrder implements Comparator {
    @Override
    public int compare(Obj o1, Obj o2) {
        return o2.getOrderNo() - o1.getOrderNo();
    }	
}

@Test
public void sortNotComparable() {
    final List<Obj> objects = new ArrayList<>();
    for (int i = 0; i < 5; i++) {
        objects.add(new Obj(i));
    }

    final List<Obj> reversedExpectedObjects = Arrays.asList(new Obj(4), new Obj(3), new Obj(2), new Obj(1), new Obj(0));
    final List<Obj> expectedObjects = Arrays.asList(new Obj(0), new Obj(1), new Obj(2), new Obj(3), new Obj(4));
	
    // 내림차순
    Collections.sort(objects, new CustumOrder());
    assertEquals(reversedExpectedObjects, objects);
	
    // 오름차순
    // Comparator가 functional interface이기 때문에 lambda expression을 사용할 수 있다.
    Collections.sort(objects, new Comparator<Obj>() {
        @Override
        public int compare(Obj o1, Obj o2) {
            return o1.getOrderNo() - o2.getOrderNo();
        }
    });
    assertEquals(expectedObjects, objects);
}


2. TreeMap

자바에서 기본 자료구조로 TreeMap을 제공한다. HashMap과 달리 이진트리 자료구조이기 때문에 key를 가지고 comparable과 comparator interface를 사용해서 sorting한다. (그렇기 때문에 hashCode 메소드는 사용하지 않는다.)

@Test
public void treeMapTraversal() {
    final Map<Integer, String> counts = new TreeMap<>();
    counts.put(4, "four");
    counts.put(1, "one");
    counts.put(3, "three");
    counts.put(2, "two");
	
    final Iterator<Integer> keys = counts.keySet().iterator();
    assertEquals("one", counts.get(keys.next()));
    assertEquals("two", counts.get(keys.next()));
    assertEquals("three", counts.get(keys.next()));
    assertEquals("four", counts.get(keys.next()));
}
@Test
public void treeMapTraversalWithComparator() {
    final Map<Integer, String> counts = new TreeMap<>(new Comparator() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o2 - o1;
        }
    });
    counts.put(4, "four");
    counts.put(1, "one");
    counts.put(3, "three");
    counts.put(2, "two");
	
    final Iterator<Integer> keys = counts.keySet().iterator();
    assertEquals("four", counts.get(keys.next()));
    assertEquals("three", counts.get(keys.next()));
    assertEquals("two", counts.get(keys.next()));
    assertEquals("one", counts.get(keys.next()));
}


'programing' 카테고리의 다른 글

리액트 상태관리를 하는 가장 쉬운 방법 Plo  (0) 2020.03.12
gitignore 패턴  (0) 2017.07.20
가상 DOM 이란?  (3) 2016.06.21
클로저 시작하기  (0) 2016.06.09

가상 DOM 이란?

원글
https://medium.com/tony-freed-consulting/what-is-virtual-dom-c0ec6d6a925c#.wdffntbv4

What is DOM?

가상 DOM 에 대해 말하기 전에 실제 DOM에 대해서 먼저 말해보자.

DOM은 Document Object Model의 약자로, 구조화된 문서를 표현하는 방법을 말한다. 크로스 플랫폼이고 랭귀지 독립적인 컨벤션을 가졌으며 HTML, XML 등에서 데이터를 표현하거나 상호작용하는데 사용된다. 웹브라우저는 DOM 을 사용하기 때문에 우리는 자바스크립트와 CSS를 사용해서 상호작용할 수 있다. 노드를 검색하고 해당 노드의 디테일을 변경하거나, 삭제하고 새롭게 생성할 수 있다.
이제 DOM API는 대부분의 크로스 플랫폼이며 크로스 부라우저 를 지원한다.
그럼 뭐가 문제일까?

DOM Problem

제일 큰 문제점은 DOM은 다이나믹 UI를 생성하는데 최적화 되어 있지 않다는 점이다.

우리는 자바스크립트와 JQuery 같은 라이브러리를 사용해서 개발을 하지만, JQuery 같은 라이브러리들은 퍼포먼스 문제를 해결하기엔 부족하다. 트위터나 페이스북, 핀터레스트 같은 모던 소셜 네트워크를 보면 조금만 스크롤해도 유저는 수천개의 노드를 받게 된다. 이런상황에서 효울적인 DOM사용은 중요한 문제가 된다. 예를 들어 1000 개의 div를 5 픽셂만 옮긴다면 1초이상 걸릴 것이다. 모던웹에선 너무 긴 시간이다. 스크립트와 몇몇 트릭으로 최적화 할 수 있을진 몰라도 결국엔 다이나믹 UI와 많은 페이지를 작업하기엔 너무 힘든 일이다.

이 문제를 해결할 수 있을까? 그럴 수 있을것 같다.
현제 W3C 그룹은 Shadow DOM을 작업중이다.
Shadow DOM - W3C working draft standard 이다. 명세에 따르면 여러 DOM트리를 하나의 계층에 통합하고 이 트리가 다른것에 어떻게 영향을 미치는지 알게되어 좀더 나은 DOM 구성이 가능하다고 한다.
다른 옵션으로 Virtual DOM이 있다. 표준은 아니지만 표준 DOM에서 해결책으로 사용되고 있다.

Virtual DOM

DOM을 직접 건드리기 보다 우리는 이것의 추상화된 버전을 만든다. 다시 말해서 가벼운 버전의 DOM 복사본을 만드는 격이다.
가상 DOM에 수정을 하고 실제 DOM에 적용할 수도 있다. 실제 DOM에 적용하기 전에 바뀐 부분이 있는지 비교한 후에 적용한다.

렌더링 비용이 큰 부분들이 전부 필요하지 않기 때문에 직접 DOM을 핸들링하는것 보다 훨씬 빠르다. 좋은 방법이지만 올바르게 사용해야 한다.
2가지 주의해야할 사항이 있다. “언제 DOM을 다시 렌더링 할것인가?” 와 “어떻게 효율적으로 할 것인가?”

언제.
데이터가 바뀌면 업데이트할 필요가 있다. 하지만 데이터가 바뀌었는지 어떻게 알까?
두가지 방법이 있다. 간단히 생각해서(dirty checking) 데이터의 모든 값을 체크하는 것이다.
두번째 방법으로 (observable)  상태(state)가 바뀌는지 관찰(observe) 하고 있는것이다. 만약 바뀐게 없다면 아무것도 하지 않으면 된다. 만약 바뀌었다면 무엇을 업데이트 해야할지 알게 된다.

어떻게.
가상 DOM 을 실제로 빠르게 하는 것은 무었인가?

  • 효과적인 비교 알고리즘.
  • DOM을 읽고 쓰는 작업
  • 효율적으로 서브 트리만 업데이트하는 것.

위에 나열한 것들은 쉽게 구현하기 힘든 것들이다. 그래서 도움을 받을 라이브러리들이 있다. 제일 유명한 것으로 페이스북의 React JS 가 있다.

React JS

페이스북에서 만든 자바스크립트 라이브러리이다.
React는 자바스크립트 오브젝트에서 가져온, DOM 트리를 흉내낸 가벼운 트리(lightweight tree)를 만든다. 이것으로 HTML을 만들고 HTML 엘리먼트에 append 나 insert 한다. 브라우저가 다시 렌더링 하게 하는 것이다.
React는 라이브러리 이지 프레임웍은 아니다. 그래서 Angular나 Ember와 비교할 순 없다.

다른 라이브러리와 프레임웍

  • virtual-dom by Matt Esch- A JavaScript Virtual DOM and diffing algorithm.
  • Mithril- A Javascript Framework for Building Brilliant Applications.
  • Bobril- Component oriented framework inspired by Mithril and ReactJs.
  • cito.js- avaScript framework for building fast, scalable and modularized web applications.

결론

가상 DOM은 DOM트리를 모방한 가벼운 자바스크립트 Object 를 통해 직접 DOM을 핸들링 하지 않고 퍼포먼스를 향상시킬수 있는 테크닉과 라이브러리, 알고리즘의 모음 이다.
가상 DOM의 아이디어는 훌륭하지만 새로운것은 아니다. 이미 오래전부터 DOM은 비싸다는것을 알고 있었지만 구현하는 방법이 어려웠을 뿐이다.
React와 같은 라이브러리 덕분에 더 나은 퍼포먼스의 어플리케이션을 개발할 수 있게 되었다.

감사합니다.


'programing' 카테고리의 다른 글

리액트 상태관리를 하는 가장 쉬운 방법 Plo  (0) 2020.03.12
gitignore 패턴  (0) 2017.07.20
java 정렬하기  (0) 2017.04.03
클로저 시작하기  (0) 2016.06.09

closure

맥 환경에서 라이닝겐을 설치하고 repl 을 사용해 보자

brew install leiningen
lein new hello-clojure
cd hello-clojure
lein repl

기본적인 함수 호출하기

user=> (- 1)
-1
user=> (+ 1 1)
2
user=> (* 10 10)
100

이것은 간단한 산수에 불과하다. 나누기는 약간 흥미롭다.

user=> (/ 1 3)
1/3
user=> (/ 2 4)
1/2
user=> (/ 2.0 4)
0.5
user=> (class (/ 1 3))
clojure.lang.Ratio

클로저는 ratio라는 기본적이 자료형을 가지고 있다. 이것은 정밀도가 상실되는 것을 피하기 위해서 계산 자체를 지연하는 멋진 기능이다. 원한다면 부동소수점을 이용해서 계산을 수행할 수도 있다. 이런 방식을 통해 나머지를 쉽게 계산할 수 있다.

user=> (mod 5 4)

나머지 연산을 수행하는 간략한 방법이다. 이러한 표기법은 전위 표기법prefix notation이라고 불린다. 지금까지 보았던 언어들은 모두 4+1-2 처럼 연산자가 피연산자 사이에 오는 중위 표기법infix notation을 사용했다. 우리는 수학 공식을 이런 방식으로 표기하는데 익숙하기 때문에 많은 사람이 이미 익숙한 중위 표기법을 선호한다. 하지만 전위 표기법의 장점도 있다.


user=> (/ (/ 12 2) (/ 6 2))
2

클로저는 괄호가 지정하는 순서대로 계산할 것이다.

user=> (+ 2 2 2 2)
8

원한다면 계산 과정에 또 다른 인수를 추가하는 것은 간단하다.

user=> (- 8 1 2)
5
user=> (/ 8 2 2)
2

이렇게 단순한 연산자 평가를 통해서 놀라울 정도로 강력한 결과를 얻을 수 있다.

user=> (< 1 2 3)
true
user=> (< 1 3 2 4)
false

훌륭하다. 이렇게 연산자 하나와 임의 개수의 인자를 이용해서 리스트의 내용이 정렬되어 있는지 여부를 판별할 수 있다.


출처
브루스 테이트의 세븐랭귀지

참고
https://leiningen.org/


'programing' 카테고리의 다른 글

리액트 상태관리를 하는 가장 쉬운 방법 Plo  (0) 2020.03.12
gitignore 패턴  (0) 2017.07.20
java 정렬하기  (0) 2017.04.03
가상 DOM 이란?  (3) 2016.06.21

+ Recent posts