SOLID

J/Java 2017. 6. 12. 18:00
  1. 단일 책임 원칙 (Single responsibility principle)

    클래스는 단 한개의 책임을 가져야 한다. 
    클래스 변경은 단 하나여야만 한다.

    단일 책임 원칙
    public class DataViewer {
     
       public void display(){
          String data = loadHtml();
          updateGui(data);
       }
     
        //
        public String loadHtml(){
            HttpClient client = new HttpClient();
            client.connect(url);
            return client.getResponse();
        }
     
       private void updateGui(String data){
          GuiData guiModel = parseDataToGuiData(data);
    //    tableUI.changeData(guiModel);
       }
     
       private GuiData parseDataToGuiData(String data) {
          return null;
       }
    }

    DataViewer에서 데이터 화면을 보여주는 display, updateGui, parseDataToGuiData 와 Html을 로드하는 loadHtml 메소드가 있다. DataViewer이라는 클래스에 화면을 보여주는 책임을 갖고 있지만 loadHtml이라는 html을 로드하는 부분도 포함되어있어 Single responsibility principle에 어긋나게 된다.
     

    단일 책임 원칙 DataViewer - DataLoader 분리
    public class DataViewer {
       DataLoader<String> dataLoader;
     
       public void display(){
          String data = dataLoader.loadHtml();
          updateGui(data);
       }
     
       private void updateGui(String data){
          GuiData guiModel = parseDataToGuiData(data);
    //    tableUI.changeData(guiModel);
       }
     
       private GuiData parseDataToGuiData(String data) {
          return null;
       }
    }
     
     
    public class DataLoader<T> {
     
       public T loadHtml() {
          HttpClient<T> client = new HttpClient<T>();
     
          client.connect();
          return client.getResponse();
       }
     
       class HttpClient<T> {
          private T response;
     
          public void connect() {
     
          }
     
          public T getResponse() {
             return response;
          }
       }
     
    }

    따라서 DataLoader 클래스를 따로 두어 분리한다. 


  2. 개방 폐쇄 원칙 (Open-closed principle)
    확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다.
    기능을 변경하거나 확장할 수 있으면서 그 기능을 사용하는 코드는 수정하지 않는다.


  3. 리스코프 치환 원칙 (Liskov substitution principle)

    상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
    파생 클래스는 부모 클래스와 치환되더라도 문제가 없어야 한다.
    부모 클래스가 제공하는 메소드 형태를 따라 기능을 제공해야 한다.
    파생 클래스는 확장이 주요 목적이다. 추가는 부차적인 문제이다.

    ex) Rectangular, Square 상속 관계

  4. 인터페이스 분리 원칙(Interface segregation principle)

    인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다.

    ex) Java Swing의 JTable, Android Activity의 View?

  5. 의존 역전 원칙(Dependency inversion principle)

    고수준 모듈은 저수준 모듈의 구현에 의존해서는 안 된다. 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야한다.


설정

트랙백

댓글

QueryDSL 문서

J/JPA 2017. 6. 12. 16:41

상수 값 넣기

NumberTemplate.ZERO.castToNum(BigDecimal.class)


'J > JPA' 카테고리의 다른 글

영속성 관리  (0) 2015.11.22

설정

트랙백

댓글

영속성 관리

J/JPA 2015. 11. 22. 20:22

JPA

EntityManagerFactory : 엔티티 매니저를 만드는 공장 ( 여러 스레드가 동시에 접근해도 안전하다. )

EntityManager : 엔티티를 저장하는 가상 데이터베이스 ( 여러 스레드가 동시에 접근하면 동시성 문제가 발생 )


엔티티의 생명주기

비영속(new/transient), 영속(managed), 준영속(detached), 삭제(removed)




영속성

- 식별자 값이 반드시 있어야한다.

- 1차 캐시와 같은 영속성 관리 테이블에서 영속성 데이터들을 관리한다.

- 트랜잭션을 지원하는 쓰기 지연을 제공한다.

- 변경 감지

- 엔티티의 동일성을 보장한다.

- 지연 로딩


동일성 : 실제 인스턴스가 같다.

동등성 : 실제 인스턴스는 다를 수 있지만 인스턴스가 가지고 있는 값이 같다.

쓰기 지연 : 영속성에 있는 데이터를 바로 데이터베이스에 저장하지 않고 쓰기 지연 저장소에 저장해둔 쿼리들을 모아서 flush하는 시점에 보낸다. 이때 쓰기 지연 저장소에 보관해서 모아서 보내는 과정을 쓰기 지연이라 한다.

변경 감지 : 초기에 스냅샷을 찍어 기존과 변경된 부분을 비교하여 변경된 부분을 찾는다.


영속성으로 전환하는 방법??



플러시

영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다.

데이터베이스에 동기화하는 것


영속성 컨텍스트를 플러시하는 방법

직접 호출

트랜젝션 커밋 시 플러시 자동 호출

JPQL 쿼리 실행 시 플러시 자동 호출


준영속

준영속 상태의 엔티티는 영속성 컨텍스트가 제공하는 기능을 사용할 수 없다.


준영속 상태로 만드는 방법

em.detach(entity) 특정 엔티티만 준영속성 상태로 전환

em.clear() 영속성 컨텍스트 완전한 초기화

em.close() 영속성 컨텍스트 종료


병합(merge) : 준영속 상태의 엔티티를 다시 영속 상태로 변경하려면 병합을 사용.

식별자 값으로 엔티티를 조회할 수 있으면 불러스 병합하고 조회할 수 없으면 새로 생성해서 병합한다.


em.contains : 파라미터로 넘어온 엔티티를 관리하는지 확인하는 메소드.

ex) em.contains(entity) 


성능 개선

JPA 기본적략은 엔티티의 모든 필드를 업데이트한다.

이때, 필드가 많거나 저장되는 내용이 너무 크면 수정된 데이터만 사용해서 동적으로 UPDATE SQL을 생성하는 전략 ( @DynamicUpdate )



'J > JPA' 카테고리의 다른 글

QueryDSL 문서  (0) 2017.06.12

설정

트랙백

댓글

자바스크립트 [1,2,3,[1,2,3],[1,2,3],[[[1]]]] 이런 문자열을 리스트로 바꾸고 싶은 경우가 발생한다. 이때 아래 예시 처럼 processBracket 처리 후, toList로 변환하면 된다.

package demo; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Stack; import org.junit.Test; public class DemoApplicationTests {

@Test public void test1() { // javascript 배열 String str = "[1,[2,[1],1]]"; // 대각선 depth 위치 파악 배열 int[] strBracket = new int[str.length()]; procBracket(str, strBracket); List list = (List) toList(str, strBracket, 0, str.length() - 1); printList(list, 0); } // depth 0, 1, 2, 3, 4 .... // array [] [] [] [] public Object toList(String str, int[] strBracket, int sIdx, int lIdx) { List res = new ArrayList(); boolean isFirst = true; int cIdx = sIdx; for (;;) { int listIdx = str.indexOf('[', cIdx); int commaIdx = str.indexOf(',', cIdx + 1); // depth가 증가하는지 여부를 파악 if (listIdx != -1 && commaIdx != -1 && listIdx < commaIdx) cIdx = listIdx; else if (listIdx != -1 && commaIdx == -1) cIdx = listIdx; // 대각선이 있을 경우 depth를 증가시켜 해당 구역에 대한 toList를 구한다. if (str.charAt(cIdx) == '[') { int nextIdx = strBracket[cIdx]; // System.out.println((cIdx + 1) + " - " + (nextIdx - 1)); res.add(toList(str, strBracket, cIdx + 1, nextIdx - 1)); cIdx = nextIdx; if (isFirst) isFirst = false; } else if (isFirst || str.charAt(cIdx) == ',') { // 처음 일 경우 ,가 맨 앞에 존재하지 않아 예외처리로 따로 -1을 더한다. if (isFirst) cIdx -= 1; int nextIdx = str.indexOf(',', cIdx + 1); // 끝에 도달했을 경우 if (nextIdx > lIdx || nextIdx == -1) nextIdx = lIdx + 1; // System.out.println(str.substring(cIdx + 1, nextIdx).trim()); res.add(str.substring(cIdx + 1, nextIdx).trim()); if (isFirst) isFirst = false; cIdx = nextIdx; } // 다음 ,위치로 이동시킨다. int nextIdx = str.indexOf(',', cIdx); // 끝에 도달했을 경우, 끝냄. if (nextIdx > lIdx || nextIdx == -1) break; cIdx = nextIdx; } // System.out.println("finish"); return res; } }


'J > Java' 카테고리의 다른 글

SOLID  (0) 2017.06.12
자바 유용한 라이브러리  (0) 2014.12.11
Java 내부 분석  (0) 2014.10.12
자바 외부 멤버변수를 내부 클래스 안에서 호출 할 경우, 주의사항  (0) 2014.10.09
jackson generic type 관련  (0) 2014.08.24

설정

트랙백

댓글

참조 : http://rootbox.co.kr/p/421

설정

트랙백

댓글

Lombok 

써봤는 데, 의외로 유용하였다. 

get, set 메소드를 줄이는 것도 있지만 해쉬, toString을 동시에 만든다는 점에서 괜찮은 라이브러리이다.


Guava

구글에서 만든 라이브러리

사용은 안해봤지만 괜찮은 듯



'J > Java' 카테고리의 다른 글

SOLID  (0) 2017.06.12
javascript 배열 java 리스트 변환  (0) 2015.06.03
Java 내부 분석  (0) 2014.10.12
자바 외부 멤버변수를 내부 클래스 안에서 호출 할 경우, 주의사항  (0) 2014.10.09
jackson generic type 관련  (0) 2014.08.24

설정

트랙백

댓글

Java 내부 분석

J/Java 2014. 10. 12. 01:46

Java 내부 분석


VisualVM, jconsole ..기타등등의 메모리,  CPU 말그대로 내부적인 전반적인 것들을 보여준다.


이것들을 어디다 쓰느냐 하면 예로들면, Memory Leak 현상이 발생하거나 프로그램 사이즈가 커졌을 때가 있는 데,


나 같은 경우에는 메모리 릭 현상이 발생하여 사용하게 되었다.


스프링 프레임워크를 사용하면서 간과했던 실수인데 static 선언을 했을 시, 메모리가 누적되어 쌓이는 증상이 발생할 수 있다.


멀티 스레드 환경에선 static으로 선언된 부분이 classloader에 계속 올라오는 현상이 생기는 거 같다.


결론은 메모리 누적이 발생하면 jconsole이나 VisualVM을 이용해서 내부 분석을 하여 해당 누적 클래스를 찾는 것이 중요하다.


자세한 내용은 구글 검색하면 나옴니다. :)


설정

트랙백

댓글

package com.example.e03list;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

public class MainActivity extends ActionBarActivity {

	LectureDBOpenHelper helper;
	SQLiteDatabase db;
	Cursor cursor;
	SimpleCursorAdapter adapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		adapter = new SimpleCursorAdapter(this, R.layout.list_item, null,
				new String[] { "title", "modifiedTime", "_id" }, new int[] {
						R.id.text_view1, R.id.text_view2, R.id.text_view3 },
				CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
		ListView listView = (ListView) findViewById(R.id.listView1);
		listView.setAdapter(adapter);

		Button b = (Button) findViewById(R.id.button1);
		View.OnClickListener onClick = new OnClickListener() {
			public SQLiteDatabase db1 = db;
			
			@Override
			public void onClick(View v) {
				Log.e("db1", "db1 : " + db1 + " db : " + db); 
				// db1은 대입하여 메소드 호출하는 식
				// db는 내부 익명 클래스에서 외부 멤버변수를 호출하는 형식이라 
				// resume때 생성해도 상관이 없다.

				EditText e = (EditText) findViewById(R.id.editText1);
				String str = e.getText().toString();
				e.setText("");
				ContentValues value = new ContentValues(1);
				value.put("title", str);
				db.insert("ListItem", null, value);
				cursor.close();
				cursor = db.rawQuery("select * from ListItem", null);
				adapter.changeCursor(cursor);
			}
		};
		b.setOnClickListener(onClick);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	protected void onResume() {
		super.onResume();
		helper = new LectureDBOpenHelper(this);
		db = helper.getWritableDatabase();
		cursor = db.rawQuery("SELECT * FROM ListItem", null);
		adapter.changeCursor(cursor);
	}

    @Override
    protected void onPause() {
        super.onPause();
        cursor.close(); 
        db.close();
        helper.close();
    }
}

'J > Java' 카테고리의 다른 글

자바 유용한 라이브러리  (0) 2014.12.11
Java 내부 분석  (0) 2014.10.12
jackson generic type 관련  (0) 2014.08.24
URLConnection을 이용한 이미지 추출 프로그램  (0) 2014.06.28
Static 키워드  (0) 2014.03.18

설정

트랙백

댓글

jackson generic type 관련

J/Java 2014. 8. 24. 16:59
http://www.javacodegeeks.com/2013/01/json-deserialization-with-jackson-and-super-type-tokens.html

 

설정

트랙백

댓글

1. java 버젼이 낮을 경우 에러가 발생할 수 있으니 java builder path 에서 높이고 오면 해결

설정

트랙백

댓글