안녕하세요? 윤경록입니다.회사가 멀어지니까, 보통 수준의 야근을 하고 왔는데도 이제야 집에 들어왔네요. 하지만 통근 시간이 한 시간 반이 조금 넘게 되어서 퇴근할 때는 지하철에서 책을 볼 수 있어서 좋군요.이 주제에 대한 예제 코드를 다음 주 주말까지 작성해서 올려보겠습니다. 이번 주말엔 막내 결혼식이 있어서 고향에 갑니다;출퇴근 시간에 조금씩 제가 어려움을 느끼는 리팩토링 과제의 예를 생각해보니까, 예를 작성하는데 100라인이 안되어도 충분할지도 모르겠다는 감이 오기 시작했습니다.대략 스케치만 하자면,1. 스탑 워치 프로그램을 짜려고 하는데2. 두 개의 스레드가 있고 (UI, Clock)3. 이 중 하나의 스레드 내에서 몇 개의 중의적인 이벤트를 처리하는 플래그들로 논리 연산하여 조건 처리를 하도록 하고 (버튼 1:시작, 카운트 시간은 가지만 보여지는 시간은 멈춤; 버튼2:종료 및 리셋)4. 이 플래그가 전역변수인데 다른 스레드에서 값을 변경하도록 할 작정입니다. (UI 스레드에서 조작)혹시 이 글타레가 시간에 묻혀 잊혀지거나, 겨우 떠올린 예제 프로그램의 스케치를 잊어버릴까봐 글을 남깁니다. ^^;전에는 매일 쓸데없는 조바심이 나서 괜한 자학과 투정만 한 듯 합니다. 최근에 퇴계 이황 선생님의 글을 모아 쓴 신창호 님의 "함양과 체찰"을 읽고 느낀 점이 있어서 소 걸음 걷듯 살기로 하였습니다. 벼 이삭을 잡아 뽑는다고 벼가 빨리 자라지는 않는다는 말씀이 있었습니다. ^^허접한 질문 하나를 하는데 몇 주가 지나가지만, 그게 밉다고 버려두지는 말아주세요. ^^;윤경록 드림
이제서야 질문을 위한 예제 코드를 올리게 되었습니다.
집에서 쓰는 PC에 우분투 OS만 깔려 있어서 리눅스 기반으로 작성하였습니다.pthread 라이브러리를 링크 할 수 있어야 테스트 하실 수 있을 것 같습니다.예제를 작성하고 보니 전형적인 C 프로그램의 형태로 잘 작성된 것 같습니다. 제 수준이 이것밖에 안됩니다; ㅠ.ㅠ
아래의 예고 글의 스케쥴과는 조금 다른 것 같은데, 변경된 내용은 이렇습니다입력은 버튼 A, B, C입니다.A 버튼 : 스탑워치 시작, 히스토리 기록B 버튼 : 리셋C 버튼 : 프로그램 종료예제 코드에서 지금 당장은 (제가 보기에) 아직 냄새가 심하게 나는 부분은 없어 보입니다.
그런데 만약 A 버튼이 "시작"의 의미로 한 번 눌린 뒤 2초 이내에 한 번 더 눌렸을 경우에 "히스토리 기록이 아닌 램프를 켜라"라는 요구사항이 추가하게 될 경우 지저분한 코드로 금방 바뀔 것이라는 생각이 듭니다. 제 경험 상 이런 경우가 무척 많았거든요.이것은 지금 생각하기에, 제가 짠 이 예제 코드에는 (지금은 알 수 없지만) 이미 지저분한 코드로 쉽게 변경될 수 있는 요소가 존재하는 것 같습니다.그런데 어떤게 그런건지 잘 모르겠습니다.
객체지향의 맛을 느끼기 위해 자바 공부는 계속하겠지만, 첨부된 예제 코드에 "지저분한 코드로 쉽게 변경될 요소"가 무엇인지, 그리고 어떻게 이러한 것들을 리팩토링 할 수 있을지 알고 싶습니다.
pthread_mutex_init
pthread_mutex_destrocy
pthread_mutex_lock
pthread_mutex_unlock
On 5월27일, 오후12시48분, Hans Yoon <ddumbu...@gmail.com> wrote:
> ӿ ߴ ڵ ۼ ߽ ϴ .
> ڵ ణ ȥ κ ̶ մϴ . (2
> space indentation).
>
> ÷ ҽ ⺻ Լ ؼ Դϴ .
>
> pthread_mutex_init
> pthread_mutex_destrocy
> pthread_mutex_lock
> pthread_mutex_unlock
>
> Լ ó Ķ ͷ pthread_t ѱ ϴ .
> pthread_t ܸԾ н 迭 OS Ȯ
> ʽ ϴ . ׳ մϴ .
>
> ̷
> fopen
> fclose
> fwrite
> fread
> ftell
> ִ Դϴ .
>
> ÷ ҽ ֿ Լ ġ Ͽ ϴ .
>
> static int MyStopWatch_Init(MYSTOPWATCH *this);
> static void MyStopWatch_Fini(MYSTOPWATCH *this);
> static Command MyStopWatch_GetMessage(MYSTOPWATCH *this);
> static void MyStopWatch_SetMessage(MYSTOPWATCH *this, Command msg);
> static void MyStopWatch_SetTimeOption(MYSTOPWATCH *this); // PRIVATE
> static void MyStopWatch_RunTimeOption(MYSTOPWATCH *this); // PRIVATE
> static void MyStopWatch_Dispatch(MYSTOPWATCH *this, Command command,
> Action *colckstate);
>
> ִ Դϴ . , ü
> ذ å Դϴ . ܰ ϰ ,
> ̶ , Ÿ Ǵ ü
> (routing) ư ߿ մϴ .
> Ϻη Լ ù ° ̸ "this" Ͽ ϴ .
>
> ̷ ϸ Ϻ ϰ ټ ֽ ϴ .
>
> ܰ迡 ܰ Ѿ ҽ и Դϴ .
> ҽ
> 1. main.c
> 2. stopwatch.c
> 3. stopwatch.h
> и ϴ ϴ .
> main.c stopwatch.h Ƶ ľ ǵ Ǿ
> մϴ .
>
> ° ܰ ؾ
> stopwatch.c/h Ʈ ڵ带 ۼ ϴ ̰ ??
>
> Ӻ 忡 ü ؾ ϴ ϴ
> ڵ ϴ и ,
> ϴ .
>
> , OOP C++, Java ͼ OOP
> дϴ .
> , OOP C ߰ , κ α ¥
> ϴ .
>
> 2010-05-14 ( ), 10:20 +0900, Steve Yoon:
>
>
>
> > ȳ ϼ ? Դϴ .
> > ˰ ̰ , ۾ Ź
> > ߾ ϴ .
> > C ¥ Ž ڵ忡 丵 ɸ°
> > ٸ 丵 Ͽ Ž ڵ带 ϰ Ͽ ϴ .
> > Ȥ Ÿ ´ٰ Ͻ DZ ̷
> > ϴ ;
> > ̸ ̰ڽ ϴ .
>
> > 帲
>
> > 2010 5 14 2:13, Ronie kang <ronie.k...@gmail.com> :
>
> > ȳ ϼ ! Դϴ .
>
> > ϴ ٻڴٴ ŭ ҽ ϴ .^^
> > 丵 ø մϴ .
>
> > ΰ ڵ带 ÷ մϴ .
> > 1. StopWatch_Refactoring_roniekang.c
> > 2. StopWatch_Requirements_roniekang.c
>
> > 1 ҽ ҽ â ش ڸ Ʈ ݿ ϰ ,
> > ⺻ ϸ ߱ Ͽ ϴ .
>
> > 2 ҽ ϴ 䱸 "A ư 2 ȿ
> > ."
> > 䱸 ߰ Ͽ ϴ .
>
> > ̷ и 丵 κа 䱸 ݿ
> > ڵ带 Ѵ ֱ Դϴ .
>
> > Ģ Ʒ ó ۼ ϰ , غ ҽ ϴ .
>
> > ** 丵
> > * 丵
> > 1. ۷ι 켱 struct
> > ϴ .
> > 2. compilie test Ȯ
>
> > * 丵
> > 1. ߺ ڵ带
> > 2. Status ϰ (Command Action 1:1 Ī
> > · ΰ ; ϴ .)
> > 3. compilie test Ȯ
>
> > * Ÿ
> > 1. ڸ Ʈ Լ ߰
> > 2. ? ߰ .
>
> > ڵ ط° ̰ ٺ ,
> > ҽ ũ 丵 κ ʾҽ ϴ .
> > н ħ ڳ ̤ ;
>
> > ** 䱸 ߰
>
> > 䱸 ߰ ϴ 丵 Ŀ ߰ Ǿ
> > ϴ .
> > ѹ 丵 ̰ ʾ ϴ
>
> > ó 䱸 ߰ Ҷ
> > ٸ ظ , ߰ Ͽ ϴ .
>
> > ?( ϴ ) 䱸 "A ư " " ǹ̷
> > 2 ̳ 쿡 " 丮 ƴ
> > Ѷ " ̾ µ
>
> > " StopWatch ǰ 2 ȿ A ư
> > " ϰ
> > ߽ ϴ .
>
> > θ 䱸 ؼ ? ȭ ϰ ,
> > 䱸 Ȯ ϰ ϰ , ȣ Ȯ
> > ϴ
> > ʿ ϴ .
>
> > Ȯ 䱸
> > "StopWatch ǰ , A ư 2 ڿ A ư
> > ȭ 鿡 "
> > ̾ ϴ .
> > ---------------
>
> > ** 䱸 ߰
> > "A ư History 10 ο ϰ ִٰ
> > B ư(Reset) ִ ߰ ּ "
> > " 10 Ѿ ٸ ó մ
> > ."
>
> > **
> > 丵 ϸ鼭
>
> ...
>
> 추가 정보 »
>
> mystopwatch_oop.c
> 6K보기다운로드
int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
RSA *rsa, int padding)
{
return(rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
}
안녕하세요^^ 석한울 입니다.
음.. 전역변수를 모두 없엘 필요가 있을까? 라고 하셧는데.. 그냥 제가 해답을 제사한다기 보다는 저도. 그냥 생각을 해서 참여를 해볼까 합니다.
만약에.. 스탑워치가 하나만 필요한것이 아니라. 여러개의 스탑워치가 필요하게되었습니다. 시간을 제고 기록할 것이 많아진것이죠.
1. 사용자는 스탑워치를 사용해서 여러개의 시간을 젤수 있어야 한다.
2. 사용자는 현재 가지고 있는 모든 스탑워치의 진행 상태를 볼 수 있어야 한다.
라는 요구사항을 추가해 보면 어떨까요.. 전역변수가 여전히 아무런 문제도 일이키지 않을까요?
--
Google 그룹스 'Agile Beginners' Q&A' 그룹에 가입했으므로 본 메일이 전송되었습니다.
이 그룹에 게시하려면 ab...@googlegroups.com(으)로 이메일을 보내세요.
그룹에서 탈퇴하려면 abqna+un...@googlegroups.com로 이메일을 보내주세요.
더 많은 옵션을 보려면 http://groups.google.com/group/abqna?hl=ko에서 그룹을 방문하세요.
// Header ///////////////////////////////////////////////////////////
#define VTBL(iname) iname##Vtbl
#define QINTERFACE(iname) \
struct _##iname {\
struct VTBL(iname) *pvt;\
};\
typedef struct VTBL(iname) VTBL(iname);\
struct VTBL(iname)
#define DECLARE_IBASE(iname) \
uint32 (*AddRef) (iname*);\
uint32 (*Release) (iname*);
QINTERFACE(IGraphics)
{
DECLARE_IBASE(IGraphics)
RGBVAL (*SetBackground)(IGraphics *po, uint8 r, uint8 g,
uint8 b);
void (*GetBackground)(IGraphics *po, uint8 *r, uint8
*g, uint8 *b);
RGBVAL (*SetColor)(IGraphics *po, uint8 r, uint8 g,
uint8 b, uint8 alpha);
void (*GetColor)(IGraphics *po, uint8 *r, uint8 *g,
uint8 *b, uint8 *alpha);
boolean (*SetFillMode)(IGraphics *po, boolean fFill);
boolean (*GetFillMode)(IGraphics *po);
...
...
};
#define IGRAPHICS_AddRef(p) GET_PVTBL(p,
IGraphics)->AddRef(p)
#define IGRAPHICS_Release(p) GET_PVTBL(p,
IGraphics)->Release(p)
#define IGRAPHICS_SetBackground(p, r, g, b) GET_PVTBL(p,
IGraphics)->SetBackground(p, r, g, b)
#define IGRAPHICS_SetColor(p, r, g, b, a) GET_PVTBL(p,
IGraphics)->SetColor(p, r, g, b, a)
#define IGRAPHICS_SetFillMode(p, m) GET_PVTBL(p,
IGraphics)->SetFillMode(p, m)
#define IGRAPHICS_GetBackground(p, r, g, b) GET_PVTBL(p,
IGraphics)->GetBackground(p, r, g, b)
#define IGRAPHICS_GetColor(p, r, g, b, a) GET_PVTBL(p,
IGraphics)->GetColor(p, r, g, b, a)
#define IGRAPHICS_GetFillMode(p) GET_PVTBL(p,
IGraphics)->GetFillMode(p)
// Impl ///////////////////////////////////////////////////////////
IGraphics *m_pGraph;
if(SUCCESS == ISHELL_CreateInstance(m_pShell, AEECLSID_GRAPHICS,
(void**)&m_pGraph))
{
IGRAPHICS_SetColor(m_pGraph, GetRValue(c), GetGValue(c),
GetBValue(c), 0);
....
IGRAPHICS_Release(m_pGraph);
}
///////////////////////////////////////////////////////////
멤버 함수포인터의 초기화는 CreateInstance시에 라이브러리에서 해줬던거 같습니다.
직접 구현한 코드들도 위처럼 했었는데 좀 코딩이 많았던것 같네요.
참고가 되셨으면 좋겠습니다.
> 2010년 5월 27일 오후 12:48, Hans Yoon <ddumbu...@gmail.com>님의 말:
> > 2010년 5월 14일 오전 2:13, Ronie kang <ronie.k...@gmail.com>님의 말:
> ...
>
> read more >>
--
Google 그룹스 'Agile Beginners' Q&A' 그룹에 가입했으므로 본 메일이 전송되었습니다.
이 그룹에 게시하려면 ab...@googlegroups.com(으)로 이메일을 보내세요.
그룹에서 탈퇴하려면 abqna+un...@googlegroups.com로 이메일을 보내주세요.
더 많은 옵션을 보려면 http://groups.google.com/group/abqna?hl=ko에서 그룹을 방문하세요.
안녕하세요 이 쓰레드가 없어져 버리려고 하네요 호호
얼마전에 저도 이 쓰레드의 리펙토링을 시작하려고 해봤는데 허걱..
제가 리눅스나 쓰레드 프로그래밍 경험이 없어서.
애를 먹었습니다.
아예 동작하는 코드부터 시작한게 아니라서. 테스트를 어떻게 작성해야 할지도 모르겠고.
일단 Win32에서 돌아가게만 만들자라는 생각에 MSDN을 뒤져가면서.
Win32에서 동작하게 땜빵식으로 바꿔봤습니다.
그냥 Win32가 아니라서. 같이 리팩토링에 참여하고 싶은데 못하고 계시는 저같은 분이 또 있을까 해서요.
일단 이렇게 올리고 테스트코드도 추가해 보고
리팩토링도 해보고. 요구사항도 또 추가해 보는건 어떨까요^^
그리고 C++프로젝트로 바꿔보는거는요??