Overview 개요

Google Cloud Messaging (GCM) is a free service that enables developers to send downstream messages (from servers to GCM-enabled client apps), and upstream messages (from the GCM-enabled client apps to servers). This could be a lightweight message telling the client app that there is new data to be fetched from the server (for instance, a "new email" notification informing the app that it is out of sync with the back end), or it could be a message containing up to 4kb of payload data (so apps like instant messaging can consume the message directly). The GCM service handles all aspects of queueing of messages and delivery to and from the target client app.

구글클라우드 메시징(GCM)은 개발자가 다운스트림 메시지( 서버에서 GCM이 가능한 클라이언트 앱으로)와 업스트림메시지(GCM이가능한 앱에서 써버로)를 가능하게하는 공짜서비스다.

이 가벼운 메시지는 서버로부터 새로운 메시지(예를들면 백엔드와 동기화하지 않는 앱에서 '새 메일'정보를 알려주는 메시지)를 가지고 오거나 최대 4kb의 데이터를 가지고 온다(앱이 메시지를 바로 사용할 수 있다.)  GCM은 모든면의 메시지쿼리를 다룰 수있고, 타겟 클라이언트앱으로 메시지를 전달하거나, 가져올 수 있다.

Key Concepts 주요 컨셉


This table summarizes the key terms and concepts involved in GCM. It is divided into these categories:

이 표는 GCM의 주요 컨셉과 용어를 요학안다. 카테고리별로 나누어져 있다.

  • Components — The entities that play a primary role in GCM.
  • 컴포넌트 - GCM에서 개별적 역할을 가지고있는 독립체(entities)
  • Credentials — The IDs and tokens that are used in GCM to ensure that all parties have been authenticated, and that the message is going to the correct place.
  • 자격(credentials) - GCM에서 권한을 주고, 메시지를 정확한곳으로 인도하는 토큰과 아이디들

Table 1. GCM components and credentials. 표1. GCM컴포넌트와 자격들

Components 컴포넌트

GCM Connection Servers
GCM 연결 서버

The Google-provided servers involved in sending messages between the 3rd-party app server and the client app.
구글이 제공하는 서머. 서드파티 앱서버와 클라이언트 앱사이의 메시지를 전송하는 기능이 포함되어있다.

Client App
클라이언트앱

A GCM-enabled client app that communicates with a 3rd-party app server.
서드파이 앱서버와 통신할 수 있는 GCM이 가능한 앱
3rd-party App Server
서드파티서버

An app server that you write as part of implementing GCM. The 3rd-party app server sends data to a client app via the GCM connection server.

당신이 만든 GCM이 포함된 서버의 일부분. 서드파티 앱서버는 GCM서버와의 연결을 통해서 데이터를 클라이언트 앱으로 보낸다.

Credentials  자격들

Sender ID
샌더아이디

A project number you acquire from the API console, as described in Getting Started. The sender ID is used in the registration process to identify a 3rd-party app server that is permitted to send messages to the client app.
API콘솔로부터 얻은 프로젝트넘버, 시작하기에 설명 되어있다.

이 센더아이디는 클라이언트로 메시지를 보내는 권한이 있는 서드파이템을 알아내기위한 등록 프로세스로 사용된다.

Sender Auth Token
샌더 권한 토큰

An API key that is saved on the 3rd-party app server that gives the app server authorized access to Google services. The API key is included in the header of POST requests.
API키는 구글 서비스에 겁속하기위한 권한으로써 서드파티앱 서버에 저장된다.

API는 포스트 리퀘스트해더를 포함하고있다.

Application ID
앱아이디

The client app that is registering to receive messages. How this is implemented is platform-dependent. For example, an Android app is identified by the package name from themanifest. This ensures that the messages are targeted to the correct Android app.
메지시를 받기위한 등록을 한 클라이언트앱. 플랫폼에 의존적으로 implement된다.
예를들어 안드로이드앱이 매니페스트에서 확인된다면, 이 확인은 메시지가 정확한 앱으로 가도록 타케팅 된다.

Registration ID
등록아이디

An ID issued by the GCM servers to the client app that allows it to receive messages. Note that registration IDs must be kept secret.
GCM서버가 클라이언트앱으로 메지시를 보내는것을 허용하기위해 발행되는 ID.

ID를 기록해놔야하고, 반드시 비밀로 유지해야한다.

Architectural Overview 구조적(Architectual) 개요


A GCM implementation includes a Google-provided connection server, a 3rd-party app server that interacts with the connection server, and a GCM-enabled client app. For example, this diagram shows GCM communicating with a client app on an Android device:

GCM은 구글이 제공한 컨넥션서버, 컨낵션서버와 소통하는 서드파티앱서버, GCM이 가능한 클라이언트 앱을 포함한다.

예를들어, 이 다이어그램은 안드로이드 디바이스에 있는 클라이언트앱이 GCM과 커뮤니케이션 하는 모습을 보여주는 다이어그램이다.

Figure 1. GCM Architecture.   그림1. GCM구조(Architecture)

This is how these components interact:

컴포넌트들이 소통하는 방법:

  • Google-provided GCM Connection Servers take messages from a 3rd-party app server and send these messages to a GCM-enabled client app (the "client app"). Currently Google provides connection servers forHTTP and XMPP.
  • 구글이 제공하는 GCM 컨넥션 서버는 서트파티 앱서버로 부터 메시지를 전달받는다, 그리고 클라이언트 앱으로 메시지를 전송한다. 현재 구글은 HTTP와 XMPP서버 컨넥션을 제공한다.
  • The 3rd-Party App Server is a component that you implement to work with your chosen GCM connection server(s). App servers send messages to a GCM connection server; the connection server enqueues and stores the message, and then sends it to the client app. For more information, see Implementing GCM Server.
  • 서드파티 앱 서버는 당신이 선택한 GCM연결 서버를 포함하는 요소(component)이다. 앱서버는 메시지를GCM으로 보낸다; 컨넥션 서버는 큐에 메시지를 넣고 저장한다. 그리고 클라이언트앱으로 전송한다. 더많은 정보는 Implementing GCM Server를 참고해라.
  • The Client App is a GCM-enabled client app. To receive GCM messages, this app must register with GCM and get a registration ID. If you are using the XMPP (CCS) connection server, the client app can send "upstream" messages back to the 3rd-party app server. For more information on how to implement the client app, see the documentation for your platform.
  • 클라이언트앱은 GCM이 가능한 앱이다. GCM메시지를 받기 위해서는 이 앱은 GCM에 등록하여 registrationID를 얻어야만한다. 만약 XMPP(CCS) 컨넥션서버를 사용한다면, 클라이언트앱은 서드파티앱서버로 업스트림메시지를 전송할 수 있다.  클라이언트앱에  포함시키기위한 더 많은 정보를 위해서 당신의 플랫폼 문서를 봐라

Lifecycle Flow 라이프사이클 흐름


  • Register to enable GCM. A client app registers to receive messages. For more discussion, see Register to enable GCM.
  • GCM이 가능하게 등록한다. 클라이언트앱을 메시지를 받기 위하여 등록한다. 더많은 설명을 보려면 REgister to Enable GCM을 봐라
  • Send and receive downstream messages.
  • 다운스트림 메시지 보내기
    • Send a message. A 3rd-party app server sends messages to the client app:
    • 메시지 보내개. 서드파티앱서버가 클라이언트앱으로 메시지를 보낸다:

      1. The 3rd-party app server sends a message to GCM connection servers.  서드파티앱이 GCM컨넥션 서버에 메시지를 전송한다.
      2. The GCM connection server enqueues and stores the message if the device is offline.  디바이스가 오프라인일 경우 컨넥션 서버는 메시지를 큐에 넣고 저장한다.
      3. When the device is online, the GCM connection server sends the message to the device. 디바이스가 온라인이 되었을때 GCM 컨넥션 서버는 디바이스로 메시지를 보낸다.
      4. On the device, the client app receives the message according to the platform-specific implementation. See your platform-specific documentation for details. 디바이스에서, 클라이언트앱을 platform-specific 확장을 통하여 메시지를 받는다. 세부사항을 위해서 당신의 디바이스의 platform0specific문서를 봐라
      5. Receive a message. A client app receives a message from a GCM server. See your platform-specific documentation for details on how a client app in that environment processes the messages it receives. 메시지 수신, GCM서버로부터 메시지를 수신한 클라이언트앱. 당신의 platform-specific문서를 봐라 클라이언트앱이 수신된 메시지를 처리하는 환경 프로세스를 어떻게 처리하는지 알기 위하여
  • Send and receive upstream messages. This feature is only available if you're using the XMPP Cloud Connection Server (CCS).
  • 업스트림 메시지의 전송과 수신. 이 특징은 오직 당신이 XMPP Cloud Connection(CSS)를 사용할때만 적용된다.

    • Send a message. A client app sends messages to the 3rd-party app server: 메시지보내기. 클라이언트앱이 서드파티앱서버로 메시지를 보낸다.
      1. On the device, the client app sends messages to XMPP (CCS).See your platform-specific documentation for details on how a client app can send a message to XMPP (CCS).  디바이스에서, 클라이언트앱은 XMPP로 메시지를 보낸다. 클라이언트앱이 XMPP로 메시지를 보내는 방법에 대한 세부사항을 위해서 당신의 platform-specific 문서를 봐라.
      2. XMPP (CCS) enqueues and stores the message if the server is disconnected. XMPP(CCS)는 서버가 연결이 안돼있을경우 메시지를 큐에 넣고, 저장한다.
      3. When the 3rd-party app server is re-connected, XMPP (CCS) sends the message to the 3rd-party app server. 서드파티앱서버가 연결되었을때 XMPP(CCS)는 서드파티 앱서버로 메시지를 보낸다.
    • Receive a message. A 3rd-party app server receives a message from XMPP (CCS) and then does the following: 메시지 수신. 서드파티 앱서버는 아래사항에 따라서 XMPP(CCS)로부터 메시지를 받는다.
      1. Parses the message header to verify client app sender information. 클라이언트 앱 전송자의 절보를 확인하기위해 메시지 해더를 파싱한다.
      2. Sends "ack" to GCM XMPP connection server to acknowledge receiving the message.  메시지를 수신받았다는 것을 GCM XMPP연결서버에 알려주기 위해 "ack"를 보낸다.
      3. Optionally parses the message payload, as defined by the client app. 선택적으로 메시지 데이터(payload)를 파싱한다. 클라이언트앱을 정의하기 위해서

Register to enable GCM GCM을 가능하게 하기위한 등록


Regardless of the platform you're developing on, the first step a client app must do is register with GCM. This section covers some of the general best practices for registration and unregistration. See your platform-specific docs for details on writing a GCM-enabled client app on that platform.

당신이 개발해놓플랫폼의 종류와 상관없이. 클라이언트 앱의 첫번째 스탭은 GCM에 등록하는것이다. 이 섹션은 등록과 등록해지의 가장좋은 방법이다.

Keeping the Registration State in Sync 동기화에서 등록 상태 유지

Whenever the app registers as described in Implementing GCM Client, it should save the registration ID for future use, pass it to the 3rd-party server to complete the registration, and keep track of whether the server completed the registration. If the server fails to complete the registration, the client app should retry passing the registration ID to 3rd-party app server to complete the registration. If this continues to fail, the client app should unregister from GCM.

앱이 Implementing GCM Client 에서 말해놓은 등록을 할땐 언제라도, 미래의 사용하고, 서드파티 앱서버에 완벽하게 등록하고, 서버가 등록여부를 완전히 알고있게하기 위해서 registrationID를 저장해 놔야한다. 만약 서버가 등록에 실패하면, 클라이언트앱은 registrationID를 서트파티앱서버에 다시 전송해서 완전한 등록을 해야한다. 만일 계속해서 실패하면 클라이언트앱은 GCM에서 등록해지된다.

There are also two other scenarios that require special care:  별한 관리를 위한 두가지 시나리오가 있다.

  • Client app update   클라이언트 앱 업데이트
  • Backup and restore   백업과 저장

Client app update: When a client app is updated, it should invalidate its existing registration ID, as it is not guaranteed to work with the new version. The recommended way to achieve this validation is by storing the current app version when a registration ID is stored. Then when the app starts, compare the stored value with the current app version. If they do not match, invalidate the stored data and start the registration process again.

클라이언트 앱 업데이트: 클라이언트 앱이 업데이트될따, 기존의 registrationid는 만료된다. 따라서 기존의 registration ID는 새로운 버전에서의 동작을 보장하지 않는다.  유혀성을 위해 추천되는 방법은 registration ID가 저장될때 현재의 앱 버전을 저장하는것이다. 그래서 앱이 실행될때 저장된 정보와 현재 앱버전을 비교한다. 만약 두 정보가 일지하지않는다면 저장된 데이터(registrationID)를 폐기하고, 등록 프로세스를 다시한번 실행한다.

Backup and restore: You should not save the registration ID when an app is backed up. This is because the registration ID could become invalid by the time the app is restored, which would put the app in an invalid state (that is, the app thinks it is registered, but the server and GCM do not store that registration ID anymore—thus the app will not get more messages). The best practice is to initiate the registration process as if the app has been installed for the first time.

백업과 저장: 앱이 백업될때 registrationID를 저장하면 안된다. 왜냐하면 registrationID는 앱이 다시 저장될때 만료되기 때문이다. 백업시 registrationID를 저장한다면 앱을 권한이 없는 상태로 만든다(왜냐면 앱은 지가 등록되어있다고 생각하지만 서버와 GCM은 해당 registrationID를 더이상 가지고있지 않기떄문이다. 그래서 앱은 더이상 메시지를 받을 수 없다.) 가장 좋은 방법은 앱이 처음 인트톨될때터럼 초기화 하는 방법이다.

Canonical IDs  예전 ID들

If a bug in the app triggers multiple registrations for the same device, it can be hard to reconcile state and you might end up with duplicate messages. 

만약 버그가 한 디바이스에서 여러 등록을 시켜버린다면,  다시 조정하기가 아주 어렵다 그래서 너는 메시지를 복제하게되는 상황에 처하게 될것이다.

GCM provides a facility called "canonical registration IDs" to easily recover from these situations. A canonical registration ID is defined to be the ID of the last registration requested by your app. This is the ID that the server should use when sending messages to the device.

GCM은  해당 상황에서 쉽게 벗어나게 해주기 위하여 "canonical registration IDs"라고 불리는 기능을 제공한다. conical registrationID는 앱에서 보낸 마지막 등록아이디로 정의되어있다. 이 아이디가 서버에서 디바이스로 보낼떄 써야하는 ID이다.

If later on you try to send a message using a different registration ID, GCM will process the request as usual, but it will include the canonical registration ID in the registration_id field of the response. Make sure to replace the registration ID stored in your server with this canonical ID, as eventually the ID you're using will stop working.

만일 나중에 당신이 다른 registrationID를 이용하여 메지시를 보내려고한다면, GCM 프로세스는 일반적 상황과 같게 요청할것이다. 그러나 그것은 응답(response)의 registration_id필드 안에있는 canonical registration ID를 포함할 것이다. 서버에 저장된 registrationID를 이 conanoical ID로 대체하기위해서 당신이 사용하던 ID는 동작을 멈출것이다.

Automatic Retry Using Exponential Back-Off  Exponential Back-Off를 이요한 자동 재요청

When registration or unregistration fails, the app should retry the failed operation.

등록 또는 등록해지가 실패했을때 앱은 실패한요청을 다시 시도해야한다.

In the simplest case, if your app attempts to register and GCM is not a fundamental part of the app, the app could simply ignore the error and try to register again the next time it starts. Otherwise, it should retry the previous operation using exponential back-off. In exponential back-off, each time there is a failure, it should wait twice the previous amount of time before trying again.

간단한 케이스에서, 너의 앱이 등록을 시도했는데 GCM이 앱의 구성요소가 아닐때, 앱을 앱은 간단하게 에러를 무시하고, 다음번에 앱이 실행될때 다시 시도한다.  그렇지않다면, exponential back-off를 이용하여 미리 재시도를 해야한다. exponential back-off에서 매번 실패가 있다면 다시 시도하기전에 두배로 기다려야한다.

Unregistration 등록해지

This section explains when you should unregister in GCM and what happens when you do.

이 섹션은 당신이 GCM에서 등록을 해지할 시기와 등록을 해지할때 일어나는 일에대해 설명한다.

Why you should rarely unregister   왜 당신은 드물게 등록해지를 해야하는가

You should only need to unregister in rare cases, such as if you want an app to stop receiving messages, or if you suspect that the registration ID has been compromised. In general, once an app has a registration ID, you shouldn't need to change it.

당신은 아주 드물게 등록해지를 해야만한다,  당신이 메시지를 더이상 받기를 원하지 않을때, 또는 registration ID가 제대로 작동하지 못했다고 생각될때 같은 경우 등록을 해지한다. 일반적으로 앱이 한번 regsistration ID를 생성하면 변경할 필요가 없다.

In particular, you should never unregister your app as a mechanism for logout or for switching between users, for the following reasons:

특히, 아래와 같은이유로 당신을 로그아웃시나, 유저를 변경할시 등록해지를 하는 행위를 절대로 하면 안된다.

  • A registration ID isn't associated with a particular logged in user. If you unregister and then re-register, GCM may return the same ID or a different ID—there's no guarantee either way.  registrationID는 로그인한 유저와는 연관되지 않는다. 만약 등록해지 후 재등록을 하면 GCM은 같은 ID를 리턴하거나 다른 아이디를 리턴하는데 둘중 어떤것이 될지는 알 수 없다.
  • Unregistration may take up to 5 minutes to propagate.      등록해지가 될때까지 최대 5분이 소요된다.
  • After unregistration, re-registration may again take up to 5 minutes to propagate. During this time messages may be rejected due to the state of being unregistered, and after all this, messages may still go to the wrong user.  등록해지 이후에  재등록까지는 다시 최대 5분이 소요된다. 이 소요시간동안 메시지는 전달되지 않을것이다. 그리고 이 모든 메시지는 다른 유저에게 갈 수 있다.

To make sure that messages go to the intended user:     메시지가 원하는(intented)유저에게 전달되는것을 보장하기

  • Your app server can maintain a mapping between the current user and the registration ID. 당신의 앱서버는 현재 유저와 registration ID 사이의 매핑을 유지(matain)할 수 있다.
  • The app can then check to ensure that messages it receives match the logged in user. 앱은 로그인한 유저가 메시지를 받있는지 확인할 수 있다.

How unregistration works   등록해지는 어떻게 이루어지는가.

A client app can be automatically unregistered after it is uninstalled. However, this process does not happen right away. What happens in this scenario is as follows:

클라이언트 앱은 제거된(uninstalled)후 자동으로 등록을 해지한다. 이 프로세스는 바로 작동하지는 않는다. 아래의 시나리오에서 어떤일이 일루어지는지 보자

  1. The end user uninstalls the client app. 유저가 앱을 지운다.
  2. The 3rd-party app server sends a message to GCM server. 서드파티앱서버가 GCM에 메시지를 보낸다.
  3. The GCM server sends the message to the GCM client on the device. GCM서버가 클라이언트의 디바이스에 메시지를 보낸다.
  4. The GCM client on the device receives the message and detects that the client app has been uninstalled; the detection details depend on the platform on which the client app is running.  디바이스의 GCM클라이언트는 메시지를 받는다 그리고 클라이언트 앱이 지워진것을 발변한다;  발견에 관한 세부사항은 플랫폼에 어떤 클라이언트앱이 동작하고있는가에따라 다르다.
  5. The GCM client on the device informs the GCM server that the client app was uninstalled.  GCM클라이언트는 GCM서버에 앱이 삭제되었단것을 알려준다.
  6. The GCM server marks the registration ID for deletion. GCM서버는 registrationID에 삭제되었다는 마크를한다.
  7. The 3rd-party app server sends a message to GCM. 서드파티 앱서버가 메시지를 GCM에 전송한다.
  8. The GCM returns a NotRegistered error message to the 3rd-party app server. GCM은 'NotRegistered'에러메시지를 서드파티앱서버에 리턴한다.
  9. The 3rd-party app server deletes the registration ID. 서드파티앱서버는 registrationID를 제거한다.

Note that it might take a while for the registration ID be completely removed from GCM. Thus it is possible that messages sent during step 7 above gets a valid message ID as response, even though the message will not be delivered to the client app. Eventually, the registration ID will be removed and the server will get a NotRegisterederror, without any further action being required from the 3rd-party server (this scenario happens frequently while an app is being developed and tested).     

registrationID가 GCM에서 완전하게 지워지기까지는 시간이 좀 걸린다. 이렇게해서 7단계보다 위로 메시지가 보내지는것이 가능한것은 응답으로 유효한 메시지 아이디를 받는것이 가능하다. 비록 클라이언트앱으로 메시지가 전달되지 않았다고 할지라도. 결국 registrationID는 지워질 것이다 그리고 서버는 notregistered에러를 받게 될 것이다. 서드파티앱서버에서 더나아간 행위가 요구되는것 없이(이 시나리오는 테스트에서 자주 발생한다.) 


반응형

Google Cloud Messaging for Android

Google Cloud Messaging (GCM) for Android is a service that allows you to send data from your server to your users' Android-powered device, and also to receive messages from devices on the same connection. The GCM service handles all aspects of queueing of messages and delivery to the target Android application running on the target device, and it is completely free.

안드로이드 구글 클라우드 메시징(GCM)은 당신의 서버에서 유저의 안드로이드 장치에 데이터를 보내는 서비스이며 같은 연결(Connection)을 이용하여 안드로이드 장치로부터 메시지를 받을 수 있는 서비스이다.

GCM서비스는 모든면의 메세지쿼리를 다룰 수 있고, 타겟 디바이스에서 구동중인 앱에 메지시 쿼리를 전달할 수 있다, 그리고 전부 공짜이다.



반응형

안녕하세요.

예지우랑입니다.


오늘은 유용한 싸이트 및 소프트웨어에 대해서 알려드립니다.


http://ocr.retia.co.kr/


위의 URL인데요 정식 프로그램을 구입하지 않아도 

하루 10회에 한하여 pdf파일을 word파일로 변환시켜주는 서비스를 하고있습니다.


인식률은 뛰어난편이며 

바뀐파일을 원본과 대조하여 약간의 오/탈자를 수정해주시면 됩니다.


감사합니다

반응형

[Vim] vi에디터에서 중복제거


:%!uniq

반응형

안녕하세요.

예지우랑입니다.

요즘 공부하면서 버전관리 프로그램으로 깃을한번 써보려고 공부중입니다.


자료를 찾다보니 깃 프로라는 공식 문서가 있더군요

한글화도 나름 잘 되어있으니 공부하시는 분들은 참고하시면 좋을거같네요


http://git-scm.com/book/ko/v2


반응형

'프로그래밍 > git' 카테고리의 다른 글

github 저장소 생성 후 로컬 프로젝트 푸시하기  (0) 2020.09.29

[노트북리뷰] 에이서 아스파이어 V3-371-78RV






안녕하세요. 자전거타는 프로그래머 예지랑입니다.

그동안 사용하던 노트북이 말도못하게 무거운데다가

베터리가 사망하여서 노트북이 필요했던 찰나!

여친느님께서 노트북을 사주셨습니다!

기념으로 리뷰 겸 개봉기를 작성하려고합니다.

개발용으로 쓸만하면서 가볍고 가성비 높은 노트북을 찾던도중 최종적으로 두가지 제품으로 좁혀졌습니다.

1. 지금 리뷰를 남기고 있는 에이서의 아스파이어 V3-271-78RV 모델

2. 한성 컴퓨터의 새로나온 인민에어 브로드웰버전.

둘중에 에이서를 선택한이유는 

1. 가성비가 에이서가 높다.(현재스펙이 75만원정도.)

2. 인민에어는 램추가가 불가능하다.

두가지 입니다.

한성컴퓨터의 경우 HDD를 추가할 수 있지만 RAM추가가 불가능하더군요

반면 V3-371 시리즈는 램슬롯이 2개여서 추가가 가능하지만 HDD를 추가할 공간이 없었습니다.

개발하시는 분들은 아시겠지만 안드로이드 스튜디오가 램 점유율이 상당히 높은관계로 램추가는 필수였어요.

또한, 가성비 면에서도 앞섰기에 에이서를 선택했습니다.

이제 리뷰 시작하겠습니다.


먼저 스팩을 보시죠


스팩은 이정도입니다. 

아쉬운점은 USB포트가 2개뿐이란점과 그나마하나는 2.0이란점이네요


포장상태.jpg


뽁뽁이가 아주 많이 감싸져있었습니다.


풀패키지.jpg


구성품.jpg

좌상단부터 시계방향으로 hdmi to div cable, 노트북 , 어답터, 전원케이블메뉴얼 , DRIVER DVD(odd가 탐재되지 않은 제품인데 DVD가 있네요),

메뉴얼

메뉴얼은 여러 언어로 되어있습니다.

다른 제퓸리뷰를 보면 마감이 허접하다느니 하는 소리가있는데 

뽑기가 잘 된건지 제거는 마감도 깔끔하고 외관상 이상도 없었습니다.


구동사진.jpg

리눅스가 OS로 깔려있습니다.

GUI도 없고, CLI로 된 리눅스더군요 

저는 윈도우를 설치하였습니다.


약 이주일정도 사용해본결과 

굉장히 만족스럽습니다.

아직 램을 추가하지 않았지만 

속도면에서도 좋고, 키감도 괘찮네요.

홈페이지에서 각종 드라이버도 제공해 주고있구요

다반 드라이버의 경우 win8.1만을 제공해주기때문에 

하드웨어 제조사에서 win7용을 다시 받아야 하는 번거로움이 있었습니다.

부팅속도는 SSD모델답게 윈도우 로고가 완성되기도 전에 부팅이 되더군요.

가성비좋은 노트북 찾은시는 분들에게 추천합니다.


반응형

[안드로이드 오류] error: illegal character: '\ufeff' ( illegal character 65279)



안드로이드 코딩을 하다보면

error: illegal character: '\ufeff' ( illegal character 65279) 이런 오류 메시지를 만나게 됩니다.

원인은 유니코드 BOM 을 인식 못하는 문제입니다. 

유니코드에는 파일의 맨앞에, 보이지 않는 어떤 표시를 해두는데 그런 것을 BOM이라고 합니다. 

자바는 BOM이 있는 유니코드는 전혀 인식하지 못하더군요. 


해결방법으로는 

메모장이 아닌 다른 텍스트 에디터에 해당 내용을 백업 했다가,

java파일을 새로 만들어서 백업받은 내용을 붙여넣는 방법이 있습니다.


※참고 : http://wannastop.tistory.com/387

반응형

[디자인패턴] OBSERVERPATTEN(옵저버패턴) 

 

안녕하세요. 예지우랑입니다.

디자인패턴중 제일 처음에 나오는 observer(옵저버)패턴에 대해 알아보겠습니다.

(※ 이 포스팅의 내용과 예제는 한빛미디어의 HEAD FIRST DESIGN PATTERNS를 참조하여 작성하였습니다.)

 

1. OBSERVERPATTEN 

 

-정의 : 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들테 연락이 가고 자동으로 내용이 갱신되는 방식으로

            일대다(一對多 , one to many)의존성을 정의합니다.

-장점 : 주제 객체의 상태변화를 자동으로 알려주어 의존하는 다른객체를 동적으로 변화시킬 수 있다.


2.예제


사실 옵저버 패턴은 매우 간단합니다.

위의 정의가 전부입니다.

하지만 좀더 정확히 하기위해서 가벼운 예제를 들어보기로 합시다.


여러분이 농장 주인이라고합시다.

여러부는 농장의 동물들에게 밥을 주는대 매번 밥을 주러 사육장을 돌아다니기 귀찮아서 

사육장에 스피커를 연결해놓고 급식장에 밥을 준비한 후 벨을 울려서 동물들에게 밥이 나왔다는것을 알려줍니다.

그림 1. 처럼 말이죠

그림1. 주제와 옵저버


그림1.처럼 여러분이 급식송 밥을주면 각 사육장으로 알려주게 됩니다.

그러면 동물들은 밥을 먹으러 오게 되겠죠??


여기서 여러분이 '주제'객체이고 각 동물들은 '옵저버 그룹'에 속해있는 '옵저버 객체'가 됩니다.

여러분(주제)가 벨을 울리는 행위를 '주제'객체가 '옵저버'객체에게 상태가 업되이트 되었다는것을 알려주는 것이죠.


그런데 사업 확장을 위하여 어제부터 키우기 시작한 오리는 옵저버 그룹이아니어서(사육장에 벨이 없어서) 밥을 못먹는

구조네요. 

불쌍항 오리를 위하여 그림2.처럼 오리를 옵저버 그룹에 등록시켰습니다.





그림 2.  새로운 객체가 옵저버에 추가됨.


오리를 옵저버그룸에 등록(register)하여 이제 오리도 벨소리를 듣고 밥을 먹으러 올 수 있게 되었습니다.

농장을 운영하다보니 우리의 개들이 밥을 너무 많이먹고 운동이 부족하여 돼지가 되었습니다.


돼지는 아직 사육할 계획이 없는데, 돼지가 있으니 난감한 여러분은 각종 성인병의 원이이되는 비만을 치료하기 위하여

개에게 당분간 먹이를 주지 않기로합니다.


그림3. 처럼 말이죠



그림 3. 옵저버 그룹에서 특정 객체를 제거.


여러분은 개 사육장에 연결된 벨에 전선을 끊어버렸습니다.(remove)이로 인해서

이제 개들은 다시 옵저버 그룹에 등록(register)되기 전까지는 밥을 못먹게 되었네요.


이렇게 옵저버 패턴을 이용하여 여러분은 농장의 동물들의 체중을 쉽게 조절하면서 

농장을 운영할 수 있습니다.


위의 예에서 알 수 있는 옵저버 패턴의 특징은 

각 객체는 언제든 주제객체에 의존하는 옵저버 그룹에 가입하거나 탈퇴할 수 있다. 라는 것입니다.



개념 정리가 어느정도 되셨나요?

이제는 실제로 적용하는 코드르 보도록 합시다.


여러분은 프로젝트를 맡았습니다. 

프로젝트의 내용은 기상청에서 업데이트되는 기상정보중 기온, 습도, 기압을 이용하여 

사용자에게 실시간으로 알려주는 프로그램을 만드는 것입니다.


다행이 한국 기상청은 기상정보를 국민 모두가 볼수있게 공개하고 있으며, 

개발자들이 쉽게 쓸 수 있도록 API도 제공하고 있네요.


그림4.는 기상청이 제공하는 API에 있는 날씨정보 객체입니다.




그림4. 기상청이 제공해주는 API중 날씨정보 객체


getTemperature 메소드는 온도를,

getHumidity 메소드는 습도를,

getPressure 메소드는 기압을 각각 기상청에서 가저오는 메소드입니다.

measurementsChanged는 관측값이 갱신(그림엔 오타가있네요) 될때마다 알려주는 메소드입니다.


아래 코드1.에서 코드를 보도롭합시다.


 

public class WeatherData {
    //인스턴스 변수자리
    public void measurementsChanged(){
        //이미 구현되어있는 WeatherData의 getter method를 이용하여 최신측정값을 가져옴
       
        float temp = getTemperature();
        float humidity = getHumidity();
        gloat pressure = getPressure();
       
        currentContitionsDisplay.update(temp,humidity,presure);
        statisticsDisplay.update(temp,humidity,pressure);
        forecastDisplay.update(temp, humidity, pressure);
    }
//기타메소드
}

코드1. WhatherData 클래스


위의 코드에서 measurementChanged() 메소드를 구현해 봤습니다.

각 정보 업데이트 메소드를 이용해서 변수에 정보를 담은 후 

 currentContitionsDisplay.update(temp,humidity,presure);
        statisticsDisplay.update(temp,humidity,pressure);
        forecastDisplay.update(temp, humidity, pressure);
위의 세 메소드를 이용하여 우리가 기상정보를 보여줄 현재상태, 평균/최저/최고치 , 기상예보를 표시해주는
프로그램에(객체에) 정보를 보내주고 있습니다.

이쯤되면 눈치를 체시겠지만 우리는 기상청에서 제공해주는 API를 이용하여
현재 기상상태 , 평균/최저/최고치 , 기상예보 이렇게 세가지 정보를 유저들에게 제공해줄 생각입니다.
좀더 이해를 돕기위해 그림5.의 클래스 다이어그램을 보면서 살펴봅시다.


그림5. 옵저버패턴의 클래스다이어그램


먼저 Subject 부터 봅시다.


Subject는 주제를 나타내는 인터페이스입니다.

객체를 옵저버로 등록하거나 옵저버 목록에서 탈퇴시키고 싶을때는 이 인터페이스에 있는 메소드를 사용하면됩니다.

그다음은 Observer 인터페이스입니다.


Observer가 될 가능성이 있는 객체는 반드시 Oberver인터페이스를 구현해야 합니다.

이 인터페이스에는 주제의 상태가 바뀌었을때 호출되는 update()메소드밖에 없습니다.


각 주제마다 여러게의 Oberver가 있을 수 있습니다.


ConcreteSubject는 주제 역하을 하는 구상 클래스입니다.

항상 Subject인터페이스를 구현 해야하면 

주제 클래스에서는 등록 및 해지를 위함 메소드 웨에, 상태가 바뀔때마다 모든 옵저버들에게 연락을 하기위한

notifyObservers()메소드를 구현해야합니다.

또, 주제 클래스에는 상태를 설정하고 알아내기 위한 세터/게터 메소드가 있을 수도있습니다.


ConcreteObserver는 Observer인터페이스를 구현해야만 옵저버 클래스가 될 수 있습니다.

각 옵저버는 특정 주제 객체에 등록을 해서 연락을 받을 수 있습니다.


※의존성이란?

의존성이랑 한객체 또는 로직이 다른 객체의 상태에 따라 영항을 받는것을 이야기합니다.

옵저버패턴에서는 옵저버들이 주제 객체의 상태에따라 옵저버의 상태가 변하게되므로 

옵저번느 주제에대해 의존성을 가진다 라고 말합니다.


디자인원칙

 서롤 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합을 하는 디자인을 사용해야합니다.

느슨하게 결합하는 디자인을 사용하면 변경사항이 생겨도 무난히 처리할 수 있는 유연한 객체지향 시스템을 구축할 수 있습니다.

객체 사이의 상호 의존성을 최소화 할 수 있기 때문이죠

 옵저버 패턴의 주제와 옵저버는 느슨한결합(Loose Coupling)을 하고 있습니다. 

옵저버 패턴이 느슨한 결합이라는 근거와 장점을 알아보고 갑시다.

근거1. 주제가 옵저베에 대해서 아는것은 옵저버가 특정 인터페이스를 구현한다는것 뿐입니다.

           다른걸 알필요도 없고 알고싶지도 않습니다. 

장점1. 옵저버는 언제든 새로 추가할 수 있습니다. 

          주제는 옵저버 인터페이스를 구현하는 객체에만 의존하기 때문에 언제든 새로운 옵저버를 추가할 수 있죠.

장점2. 주제와 옵저버는 독립적으로 사용할 수 있습니다.

          어차피 서로에 대해 아는것은 특정 인터페이스를 구현할 수 있다는 것 뿐이고 그외에는 서로 관심도 없습니다.

          옵저버가 새로운 행동을 하는것이 주제와의 관계에서 문제가 일어날거같다면

          그저 주제의 목록에서 삭제해 버리면 그만입니다.

장점3. 주제나 옵저버가 바뀌더라도 서로에게 영향을 미치지 않습니다. 

          서로 인터페이스를 구현한다는 조건만 만족되면 어떻게 바꿔도 문제가 생기지 않습니다.

         



이제 최종적으로 우리의 시스템을 구현하기 위한 클래스 다이어그램인 그림6.을 봅시다.



그림6. 우리가 구현하게될 기상정보시스템의 최종 클래스 다이어그램. (클릭하면커집니다.)


하나씩 설명을 해봅시다.

Subject는 주제 인터페이스입니다. 우리가 지금까지해온것과 동일합니다.

Obser인터페이스는 주제 객체에서 옵저버에게 생신된 정보를 전달할 수 있는 방법을 정의하게 만듭니다.

DisplayElement인터페이스는 우리의 기상 정보를 화면에 표시해주는 방법을 정의하게하는 인터페이스입니다.


WeatherData는 기상청에서 제공해주는 객체입니다. Subject를 Implement하여 우리의 시스템에서 새로 갱신된 날씨데이터를 

가져다 줍니다.

CurrentConditions는 현재 측정된값을 보여줍니다.

StatisticsDisplay는 평균/최고/최저값을 보여줍니다.

ForecastDisplay는 기상 예보를 표시해줍니다.

ThirdPartyDisplay는 위의 세가지 이외에도 Obsever와 DisplayElement만 구현하면 옵저버객체가되며 정보를 표시해줄 수 있다는것을

알려주는것입니다.



이제 구현을 해봅시다. 

 public interface Subject {

  public void registerObserver(Observer o);   //옵저버를 등록
  public void removeObserver(Observer o);     // 옵저버를 제거
  public void notifyObservers();              // 주 객체의 상태 변경시 모든 옵저버에게 알려주는 메소드

}

코드2. Subject Interface


 public interface Observer {

  public void update(float temp , float humidity, float pressure); 
  /*
   * 옵저버 인터페이스는 모든 옵저버 클래스에서 구현해야합니다.
   * 따라서 모든 옵저버는 update메소드를
   * 구현해야합니다.
   */
}

코드3. Observer Interface


public interface DisplayElement {

  public void display();
  /*
   * display화면을 출력해야할 경우 호출해야되는 메소드.
   */
}

코드4. DisplayElement InterFace


 import java.util.ArrayList;

public class WeatherData implements Subject {
	private ArrayList observers;    //ArrayList자료구조를 사용합니다. ArrayList를 import합시다.
	private float temperature;
	private float humidity;
	private float pressure;
	
	public WeatherData(){
	  observers = new ArrayList();    //생성자에서 observers를 생성 해 줍니다.
	}
	
	public void registerObserver(Observer o){  //옵저버가 등록을 하면 목록 맨뒤에 추가해줍니다.
	  observers.add(o);
	}
	
	public void removeObserver(Observer o){   //옵저버가 탈퇴를 요청하면 목록에서 제거해줍니다.
	  int idx = observers.indexOf(o);
	  if(idx >=0 ){
	    observers.remove(idx);
	  }
	}
	
	public void notifyObservers(){
	  for(int i = 0 ; i < observers.size(); i++){
	    Observer observer = (Observer)observers.get(i);
	    observer.update(temperature, humidity, pressure);
	  }
	}
	
	public void measurementsChanged(){
	  notifyObservers();
	}
	public void setMeasurements(float temperature , float humidity, float pressure){
	  /*
	   * 기상청에서는 날씨정보를 알려주는 API를 제공합니다.
	   * 그러나 여기서 적용시키자면 배보다 배꼽이 커지게되어 이 메소드를 통하여
	   * 확인해보도록하겠습니다.
	   * http://www.kma.go.kr/weather/lifenindustry/sevice_website.jsp
	   * 진짜 날씨정보를 제공해주는 프로그램을 만드시고싶다면
	   * 위의 페이지를 참조하여주세요.
	   */
	  this.temperature = temperature ; 
	  this.humidity = humidity;
	  this.pressure = pressure;
	  measurementsChanged();
	}
//기타메소드
}

코드5. 실제 구현한 WeatherData Class


 

public class CurrentConditionsDisplay implements Observer, DisplayElement {
  /*
   * WeatherData객체로부터 변경사항을 받이귀아혀 Observer객체를 구현합니다. 
   * API구조상 모든 디스플레이 항목에서 DisplayElement를 구현하기로 했기 때문에 
   * DisplayElement인터페이스도 구현합니다.
   */
  private float temperature;
  private float humidity;
  private Subject weatherData;
  
  public CurrentConditionsDisplay(Subject weatherData){
    /*
     * 생성자에 weatherData라는 주제객체가 전달되며 , 그 객체를 써서 디스플레이를 옵저버로 등록합니다.
     */
    this.weatherData = weatherData;
    weatherData.registerObserver(this);
  }
  
  public void update(float temperature, float humidity , float pressure){
    /*update()가 호출되면 기온과 습도를 저장하고 display()를 호출합니다.*/
    this.temperature = temperature;
    this.humidity = humidity;
    display();
  }
  
  public void display(){
    System.out.println("현재 기온:" + temperature + " | 현재 습도:" + humidity);
  }
}

코드6. CurrentConditionsDisplay클래스



/*테스트용 클래스입니다. 우리가 만든 프로그램이 잘 동작하는지 알아봅시다.*/
public class WeatherStation {
  public static void main(String[] args){
    WeatherData weatherData = new WeatherData(); 
    //우선 웨더 데이터 객체를 생성합니다.
    
    CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
    //현재값을 보여주는 클래스인 CurrentConditionsDisplay 객체를 생성합니다. 인자로 미리 생성한 웨더데이터 객체를 줍니다.
    
    weatherData.setMeasurements(80, 65, 30.5f);
    weatherData.setMeasurements(10, 20, 88.7f);
    weatherData.setMeasurements(65, 23, 10.5f);
    //세로운 기상 값이 들어간것처럼 만들어줍니다.
    
    
  }

}

코드7. 테스트를 위해서 main메소드를 만들어봤습니다. 한번 돌려봅시다.


최대/최저/평균을 구하는 staticsDisplay클래스와 

기상예보를 해주는 ForecastDisplay클래스는 여러분이 직접 만들어보시면 좋을거같습니다.!!!!




3. 옵저버패턴은 실제 어디에서쓰일까?

옵저버패턴은 일종의 push방식의 알고리즘입니다.

업데이트된 정보 또는 DATA를 처리하는 알고리즘에는 크게 PUSH방식과 PULL방식이 있습니다. 

물론 두가지를 결합한 형태의 방식도 존재하죠


지금 알아본 옵저버패턴은 일종의 push방식 알고리즘으로써 

상태가 바뀐값을 다른 객체에 알려주면서(push하면서) 그 값을 다른 객체가 처리하고있죠

제가 생각했을때 일상에서 가장 쉽게 접할수있는 시스템중에 옵저버 패턴을 적욕할 법한 시스템은

쇼핑몰입니다.

우리가 구매 버튼을 누른 후 결제를 하고면 자동으로 우리 이메일로

결제가 완료되었습니다. 라는 안내메일이 오잖아요?


여러 구현 방법이 있을 수 있겠지만 결제모듈을 주제 객체로, 메일링 시스템을 옵저버 객체로 등록해놓고 

결제완료시에 update()메소드를 호출하면 자동으로 메일링 시스템이 메일을 보내주겠죠?



4. 최종적으로 옵저버패턴의 핵심을 다시 봅시다.

OBSERVERPATTEN 

 

-정의 : 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들테 연락이 가고 자동으로 내용이 갱신되는 방식으로

           일대다(一對多 , one to many)의존성을 정의합니다.

-장점 : 주제 객체의 상태변화를 자동으로 알려주어 의존하는 다른객체를 동적으로 변화시킬 수 있다

옵저버 패턴의 특징 

각 객체는 언제든 주제객체에 의존하는 옵저버 그룹에 가입하거나 탈퇴할 수 있다.





※의존성이란?

의존성이랑 한객체 또는 로직이 다른 객체의 상태에 따라 영항을 받는것을 이야기합니다.

옵저버패턴에서는 옵저버들이 주제 객체의 상태에따라 옵저버의 상태가 변하게되므로 

옵저번느 주제에대해 의존성을 가진다 라고 말합니다.


디자인원칙

 서롤 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합을 하는 디자인을 사용해야합니다.

느슨하게 결합하는 디자인을 사용하면 변경사항이 생겨도 무난히 처리할 수 있는 유연한 객체지향 시스템을 구축할 수 있습니다.

객체 사이의 상호 의존성을 최소화 할 수 있기 때문이죠

 옵저버 패턴의 주제와 옵저버는 느슨한결합(Loose Coupling)을 하고 있습니다. 

옵저버 패턴이 느슨한 결합이라는 근거와 장점을 알아보고 갑시다.

근거1. 주제가 옵저베에 대해서 아는것은 옵저버가 특정 인터페이스를 구현한다는것 뿐입니다.

           다른걸 알필요도 없고 알고싶지도 않습니다. 

장점1. 옵저버는 언제든 새로 추가할 수 있습니다. 

          주제는 옵저버 인터페이스를 구현하는 객체에만 의존하기 때문에 언제든 새로운 옵저버를 추가할 수 있죠.

장점2. 주제와 옵저버는 독립적으로 사용할 수 있습니다.

          어차피 서로에 대해 아는것은 특정 인터페이스를 구현할 수 있다는 것 뿐이고 그외에는 서로 관심도 없습니다.

          옵저버가 새로운 행동을 하는것이 주제와의 관계에서 문제가 일어날거같다면

          그저 주제의 목록에서 삭제해 버리면 그만입니다.

장점3. 주제나 옵저버가 바뀌더라도 서로에게 영향을 미치지 않습니다. 

          서로 인터페이스를 구현한다는 조건만 만족되면 어떻게 바꿔도 문제가 생기지 않습니다.

         



다음번엔 또 새로운 패턴으로 돌아오겠습니다. 감사합니다.






반응형

'프로그래밍 > 디자인패턴' 카테고리의 다른 글

[디자인패턴] STRATEGY(전략패턴)  (2) 2014.11.08

[IT 개발자 면접 대비문제](코딩면접) 

입력한 숫자만큼 *이 출력되는 프로그램

피라미드 모양으로 출력하기

*

**

***

****

*****

↑이 모양 나오게 자바 코드로 짜기

 

 

 

package MakeStarPiramid; 

import java.util.Scanner; 

public class MakeStarPiramid {
  public static void main(String args[]){ 
      int num; 
      Scanner sc = new Scanner(System.in); 
      System.out.println("몇단으로 만들까요?"); 
       
      num = sc.nextInt(); 
       
      //System.out.println(num); 
      for(int i = 0 ; i < num ; i ++){ 
        for(int j = 0 ; j < i +1 ; j ++){ 
            System.out.print("*"); 
        } 
        System.out.println(); 
      } 
  } 
} 


반응형

[IT 개발자 면접 대비문제] 오버로딩과 오버라이딩


1.     메소드 오버로딩과 오버라이딩

자바에서 다형성을 지원하는 방법으로 OVERLOADING OVERRIDING이 있다.

 

-오버로딩

같은 이름의 메소드를 여러 개 가지면서 매개변수의 유형과 개수가 다르도록 하는기술

메소드 오버로딩과 생성자 오버로딩이 있다. 그러나 둘다 같은 개념이다.

같은이름의 함수를 여러 개 정의하고, 매개변수의 유형과 개수를 다르게하여

다양한 유형의 호출에 응답하게 하는것이다.

 

-오버라이딩

상위 클래스가 가지고 있는 메소드를 상속 받을 때 자식 클래스에서 메소드를 재 정의하는것을 말한다.


소스코드를 보고 확인하자.



반응형

+ Recent posts