-최근에 다시 공부하게된 디자인 패턴 -

싱글톤은 무엇인가 ?

특징 : 

1. 생성자가 없다..
즉 보통 클래스를 만들때 Test  test = new Test(); 로 생성한다 . 하지만 싱글톤 패턴은 new 로 생성자를 생성할수없다.
일반 적인 클래스
public TestClass {
public TestClass(){

 
}
}
이런 구조로 생성되어있다 하지만 생성돼는 부분 빨강부분이 private로 돼어있다.
public TestClass {
private TestClass(){
}
}
이런구조면 private  글래스 안에서만 사용할수있는 함수기 때문에 외부에서 호출할수 없는 부분이다. 이러면 클래스를 전혀 사용 못하게된다.


2. 1개의 인스턴스만 만들어진다.
만약 클래스가 메모리에있다면 더이상 만들지 않고 자기 생성된 생성자를 넘겨준다 .
아래와 같은 형태로 클래스 를 넘겨 받는다.
TestClass  test = TestClass.getInstance();


public TestClass {
/*유일한 인스턴스 저장 객체 선언*/
private static TestClass uniqueInstance ;
private TestClass(){ }

/*외부에서 사용할 함수 선언 클래스를 생성할떄 쓴다 */
public static TestClass getInstance(){
if(uniqueInstance  ==null){//있는지 체크 없으면
uniqueInstance  = new TestClass (); //생성한뒤
}

return uniqueInstance  ;//성성자를 넘긴다.
}
}



어디에 적용하면 좋을까 : 
딱 보면 감이 온다. 아 싱글톤이라는 패턴은 오직 1개만 만들어서 다른 곳에서도 사용할수있는거구나.
적용할수있는 곳은

ps. 블로거 저의 개인적인 생각입니다.

1. static으로 선언해서 공통적으로 사용되는 부분 환경 설정이나
2. 내용이 변경되면 다른 클래스에서도 그부분이 또같이 적용돼어 실행되어야할때.
3. 자주사용되는 부분을 싱글톤으로 만들어 생성된는 시간을 줄이고자할떄.
보통getInstance를 얻는  패키지나 프레임워크를 보면
DB 커낵션 커낵션풀 에서 사용돼는경우가있다.


유의 사항 !!!

Thread 사용시에는 위와같은 방법은 문제가 될수있다.
1. 싱크로 나이즈를 걸어준다.
public static  synchronized TestClass getInstance(){
if(uniqueInstance  ==null){
uniqueInstance  = new TestClass ();
}
return uniqueInstance  ;
}
-- 속도가  느려지지 빠른 속도를 원하면 이 방법은 비추 .
2. 인스턴스를 처음에 만든다.
private static TestClass uniqueInstance  = new TestClass();

3. DCL(duble0checking locking ) 사용 JDK 1.5부터 가능.

public TestClass {
/*유일한 인스턴스 저장 객체 선언*/
private  volatile static TestClass uniqueInstance ;
private TestClass(){ }

/*외부에서 사용할 함수 선언 클래스를 생성할떄 쓴다 */
public static TestClass getInstance(){
if(uniqueInstance  ==null){ //있는지 체크 없으면
synchronized(TestClass.class){
if(uniqueInstance  ==null){ //다시한번채크
 
uniqueInstance  = new TestClass (); //생성한뒤
}

}
}

return uniqueInstance  ;//성성자를 넘긴다.
}
}





 컴포넌트 기반의 개발

1) 개발하기전에 충분히 엄무를 분석하여 시스템의 도입 목적을 명시.
2) 엄무 프로세스별로 구분한다.
3) SOA(Serivce Orented Architecture)

모델 드리분 아키텍처 (MDA : Model Driven Architecture)
→ 모델 중심으로 시스템을 개발해 가는 이론으로서 UML의 사양을 관리하는 OME
    목적은 여러가지 변화에 유연하게 대응할 수 있는 시스템을 개발하는 것이다.
1) CIM
2) PIM
3) PSM

 
      

<----> 나름 기억 하고 싶은 말들 <---->
■ 원칙
1. 애플리케이션에서 달라지는 부분을 찾아 내고, 달라지지 않는 부분으로부터 분리 시킨다.


 


선작업
Windows SDK 최신으로 깔아주시고 .. 2008 쓰면 자동으로 깔리는데 현제 윈도우7지원까지나옴
DDK 요것도 깔아주시고
해더 라이브러리 걸어주시고  하면되요 ~_~;;

// TestJniFile.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "Common.h"


int main(int argc, char* argv[])
{

  HDEVINFO hDevInfo;
  SP_DEVINFO_DATA DeviceInfoData;
  DWORD iCnt;
  ///FILE *fp;
  char str_buffer[100];
  char * sDiveName = "USB"; // 인자 받은것 포트번호
  int iState =1; ///  죽이냐 살리느냐 0 살린다 1 죽인다.


  // Create a HDEVINFO with all present devices.
  hDevInfo = SetupDiGetClassDevs( NULL,
          0, // Enumerator
          0,
          DIGCF_PRESENT | DIGCF_ALLCLASSES );   // 디바이스 정보를 가저오는곳입니다.. DIGCF_PRESENT | DIGCF_ALLCLASSES  이부분인자를 바꺼줌으로써.. 가져울 정보의 갯수를
                                                                       바꿀수있다 그래픽만 , 아님 이너넷만 머 이런식인듯...  인터넷 찾아보면 길이보임 .. 난 잘모름 .. 나하하 ~ 

  if (hDevInfo == INVALID_HANDLE_VALUE)
  {  
   return 1;
  }

  DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  for (iCnt=0;SetupDiEnumDeviceInfo(hDevInfo,iCnt,&DeviceInfoData);iCnt++) /// 갯수 가지고 포문 을 돌린다 한갯식 정보를 가져와야지/
  {
  DWORD DataT;
  LPTSTR buffer = NULL;
  DWORD buffersize = 0;
  int i=SPDRP_DEVICEDESC;

  while (!SetupDiGetDeviceRegistryProperty(   // 디바이스의 각종 정보를 가져온다.
             hDevInfo,
             &DeviceInfoData,
             SPDRP_FRIENDLYNAME,  // 디바이스 정보가저오는것을 여기서 변경할수있다 아이디 또는 머 기타 부수적인것 변경해줌으로써 내용이 바뀐다.
             &DataT,
             (PBYTE)buffer,
             buffersize,
             &buffersize)
    )
    {
   if (GetLastError() ==ERROR_INSUFFICIENT_BUFFER)
   {
     // Change the buffer size.
     if (buffer) LocalFree(buffer);
     // Double the size to avoid problems on
     // W2k MBCS systems per KB 888609.
     buffer = (LPTSTR)LocalAlloc(LPTR,buffersize * 2);
   }
   else
   {
    // Insert error handling here.
     break;
   }
    }
    printf("장치명 :[ %s ]  \n",buffer);
    /// LGE CDMA USB Serial Port(COM7)
  
    sprintf_s(str_buffer,"%s\n",buffer);
    if(strstr(str_buffer,sDiveName))
    {  
   
   if  (iState == 0)
   {    
    if (DiviceStateChange(DICS_ENABLE, iCnt , hDevInfo)){
     printf("Divice Name :[ %s ] Divice Num -> %d 을 사용으로 변경완료. \n",buffer,iCnt);
    }
    else
    {
     printf("Divice Name :[ %s ] Divice Num -> %d 을 사용으로 변경하려 했지만 실패 하였습니다.. \n",buffer,iCnt);
    }
    
   }
   else
   {
    if (DiviceStateChange(DICS_DISABLE, iCnt , hDevInfo) )
    {
     printf("Divice Name :[ %s ] Divice Num-> %d 을 사용 않함으로 변경완료. \n",buffer,iCnt);
    }
    else
    {
     printf("Divice Name :[ %s ] Divice Num -> %d 을 사용 않함으로 변경하려 했지만 실패 하였습니다.. \n",buffer,iCnt);
    }
    
   } 
   getchar();
   return 0; 
   
    } 

  };
 getchar();
  if ( GetLastError()!=NO_ERROR &&
  GetLastError()!=ERROR_NO_MORE_ITEMS )
  { 
  return 1;
  }
 
     SetupDiDestroyDeviceInfoList(hDevInfo);
 
  return 1;
}

BOOL DiviceStateChange(DWORD NewState, DWORD SelectedItem,HDEVINFO hDevInfo)
{
    SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTALL_HEADER)};
    SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
    //  HCURSOR hCursor;

    //
    // This may take a while :^(
    //
 //   hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));

    //
    // Get a handle to the Selected Item.
    //
 
    if (!SetupDiEnumDeviceInfo(hDevInfo,SelectedItem,&DeviceInfoData))
    {
        DisplayError(TEXT("EnumDeviceInfo"));
        return FALSE;
    } 

    //
    // Set the PropChangeParams structure.
    //
 PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);  
    PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
    PropChangeParams.Scope = DICS_FLAG_GLOBAL;
    PropChangeParams.StateChange = NewState;
 PropChangeParams.HwProfile = 0;


    if (!SetupDiSetClassInstallParams(hDevInfo,
        &DeviceInfoData,
        (SP_CLASSINSTALL_HEADER *)&PropChangeParams,
        sizeof(PropChangeParams)))
    {
        DisplayError(TEXT("SetClassInstallParams"));     
  return FALSE;
    }
 
    if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
        hDevInfo,
        &DeviceInfoData))
    {     
        return TRUE;
    }
    return TRUE;
}

 


hader 구조
JNIEXPORT jint JNICALL Java_com_common_aa_diviceStateChange
  (JNIEnv * env, jobject obj , jint iState, jbyteArray blDiveName);
---------------------------------------------------------------
JNIEXPORT jint JNICALL Java    --> 여기 까지는 기본으로 만들어진다.
_com_common -- > 패키지 위치
_aa  --> 클레스이름
_diviceStateChange -->함수명
(JNIEnv * env, jobject obj  --> 기본으로 만들어지는  값들
, jint iState, jbyteArray blDiveName); --> 내가 인자 넘기는 값이 정의 대어있다 . 여기서보면 int 형은 jint 로 보이고  , byte값은 jbyteArray  값으로 나타난다.


------------------------------------------------------------------
cpp 만들기
해더파일 복사해서 붙여넣기하면 끝 ... 그담에 ; 빼고 {} 묵고 그안에다가 자료 넣는다 리턴값이있는 클래스 이기 때문에 .. 리턴값정의한다.
JNIEXPORT jint JNICALL Java_com_common_aa_diviceStateChange
  (JNIEnv * env, jobject obj , jint iState, jbyteArray blDiveName)
{
return int a =0; // 대는지는 모름 .. ㅋㅋㅋㅋ c 문법에 맞게 하세요
}
그담에 컴파일 f7 누루면 DLL만들어진다..

참고

디버깅 예
F9 브러킹 거는거
F5 는 블럭킹 건거 순차적으로 디버깅 (DLL 만들떄는 안돼요 실행파일이 없기때문에 ?? 아님 나도 몰름 .. 이상한 창뜸 ..)
F7 컴파일
조사식에  자료형태를 보고싶으면 마우스로 끌어당기면 보인다 @,.@ 신기..






자료형

shortint  :(정수형) ~128~127
integer : -32768
longint : 2147483648
byte : 0~125
word : 0 65535
real :  (실수형)
double:
extended :
comp
currency

숫자와 관련해서 자주 사용되는 루틴
 Low(x) X의 법위중 가장 최소 값을 리턴  (X는 배열)
 High(x)  x의 최대값(X는 배열)
 Ord(x)  x의 서수값
 Pred(x)  x -1 값을 리턴한다
 Succ(x) x+1 값을 리턴 
 Frac(x) x의 소수점 이하 부분을 리턴 
 int(x) 실수X의 정수 부분을 리턴한다. 123.0
Trunce(x) 실수형 정수부분만 1.222 => 1 


문자열
 chr(x) 정수를 아스키문자로 전환   C1 := chr(65); A가 저장된다.
 Concat(s1,s2,s3); 문자들을 합친다.  s := s1 +s2+s3
 CompareStr(s1,s2) 대소문자구분하여비교한다.
숫자값리턴 
l := compareStr(s1,s2);
if l <0 then
showmessage('스트링값이틀려');
 CompareText  대소문자 구분안하고 비교한다.  l := CompareText(s1,s2);
if l < 0 then
showmessage('틀리거든');
 copy(s,pos,len) 문자열 s 에서 pos 위치로부터 len 길이만큼 리턴한다   s := 'ABCDE';
s:= Copy(s,2,3); {'BCD'}
 Delete(s,pos,len) 위치에서 길이만큼지운다   s := 'ABCDE';
s:= Delete(s,2,3); {'A}
insert(source,target,pos) 타겟에다가 pos 위치에다가  source 추가한다.
Length(s)  문자열 길이를 리턴한다.
LowerCase(s) 아스키 스트링을 소문자로 리턴
Pos(substing,s) 문자열 s 에서 문자열 substring 을 찾아 시작 되는 위치 값을 리턴한다.
SetLength(s,newLen)  동적으로 문자열 길이를 다시 지정한다.
Str(x,s) 정수 타입을 문자열로 바꾼다.
StrUpper(s) 문자열 대문자로 변환합니다.
StrLower(s) 문자열을 소문자로 변환합니다.
 UpperCase(s) a~z 까지의 아스키 소문자를 대문자로 전환



상속
_name = class(_parent)



형변환
 CurrToStr currency 값을 스트링형으로 변환하여 리턴한다. 
 FloatToDecimal 실수형값을 Decimal 값으로 변환합니다. 
IntToStr int -> str 
StringToWidchar  
 StrToCurr  
 strToFloat  
 strToInt 스트링값을 integer 값으로 형변환