SW 품질속성 6가지

|

품질 속성(QA : Quality Attribute)은 시스템이 이해 당사자의 요구 사항을 얼마나 잘 만족시키는지를 나타내기 위해 사용하며, 측정하거나 테스트할 수 있는 시스템의 특성을 의미합니다.

품질 속성은 보통 다음과 같이 6개의 요소로 구성됩니다.

image


Stmulus(자극)

자극은 시스템에 도달하는 이벤트를 말합니다. 사용자의 명령이 될 수도 있고, 보안적인 측면에서는 외부로부터의 공격이 될 수도 있습니다.


Source of Stimulus(자극원)

자극원은 자극의 원인입니다. 자극원은 시스템이 처리하는 방식에 영향을 줄 수 있습니다. 예를 들면, 신뢰할 수 있는 사용자로부터의 요청과 신뢰할 수 없는 사용자로부터의 요청은 서로 다르게 수행될 것입니다.


Response(반응)

시스템이 자극에 반응하는 방법입니다.


Response Measure(반응 측정)

반응에 대한 측정입니다. 반응이 요구 사항을 만족시켰는지 여부를 결정하며, Latency(지연 시간)나 Throughput(산출량) 등이 측정 요소가 될 수 있습니다.


Environment(환경)

시나리오가 발생하는 상황입니다. 자극은 특정한 조건에서 발생하며 환경은 자극을 가하는 역할을 합니다.


Artifact(대상)

대상은 시스템을 말합니다. 전체 시스템이 될 수도 있고 특정 부분이 될 수도 있습니다. 예를 들면 데이터 저장소(Data Store)와 메타 데이터 저장소(Metadata Store)에서의 오류는 다르게 처리되어야 할 것입니다.

예제

가용성이라는 시나리오 기반으로 각 요소들을 생각하면 다음과 같습니다.

image

Android 폰으로 USB 테더링하기

|

Android 폰으로 USB 테더링하기

예전에는 별도의 세팅없이 안드로이드 폰으로 USB 테더링이 가능했는데, 어느 순간부터 USB 테더링이 안되도록 변경되었습니다. 그래서 별도의 프로그램을 설치해주어야 USB 테더링을 할 수 있습니다.


프로그램 다운로드

해당 프로그램은 여기에서 다운받을 수 있습니다. 최신 버전으로 다운받도록 합시다. 현재 최신 버전은 여기에서 받을 수 있습니다.


Mac 재부팅

그런 다음, Mac을 재부팅시켜줍니다. 그 이후 안드로이드 폰에서 설정에서 USB 테더링을 켜주면 USB 테더링을 사용할 수 있게 됩니다.

플라이웨이트(Flyweight) 패턴 for Game (C++)

|

Flyweight 패턴

플라이웨이트(Flyweight) 패턴은 객체간 동일한 정보나 유사한 정보들을 같이 공유(Sharing)해서 메모리 사용량을 최소화하는 패턴입니다. 게임에서 나무나 관객 등의 배경을 표현할 때 많이 사용되는 패턴입니다.


나무를 표현하는 클래스

숲의 나무를 표현한다고 할 때, 다음과 같은 데이터들이 필요합니다.

  • 줄기, 잎 등을 표현하는 폴리곤 메시(Mesh)
  • 나무 껍질과 입사귀 텍스처(Texture)
  • 나무의 높이와 굵기
  • 각각의 나무들의 색상을 조금씩 다르게 하기 위한 색의 농도(Tint)

클래스로 표현하면 다음과 같습니다.

class Tree {
 private:
  Mesh mMesh;
  Texture mBark;
  Texture mLeaves;
  Vector mPosition;
  double mHeight;
  double mThickness;
  Color mBarkColor;
  Color mLeavesColor;
};

데이터 종류도 많지만, 메시나 텍스처의 경우 데이터 크기도 큽니다. 이런 나무를 수십, 수백 그루를 표현해야 할 때, 메모리 소모나 성능적인 면에서 한계가 있습니다.


메모리 사용량을 줄이기 위한 방법

특히 메모리를 많이 사용하면서, 공통적인 부분들을 추출하여 하나의 클래스로 만들 수 있습니다. 예를 들어, 다음과 같은 ‘TreeModel’ 클래스를 만들 수 있습니다.

class TreeModel {
 private:
  Mesh mMesh;
  Texture mBark;
  Texture mLeaves;
};

기존 ‘Tree’ 클래스는

class Tree {
 private:
  TreeModel *mTreeModel;

  Vector mPosition;
  double mHeight;
  double mThickness;
  Color mBarkTint;
  Color mLeavesTint;
};

가 됩니다. 나무가 아무리 많더라도 ‘TreeModel’ 클래스는 하나이기 때문에 메모리 사용량은 확실히 줄어듭니다.


지형을 표현하는 방법

조금 예제를 바꾸어서 이번에는 지형을 표현하는 방법입니다. 지형 정보에는 다음과 같은 정보들이 필요합니다.

  • 화면에 렌더링할 때 필요한 텍스처
  • 이동할 때 드는 비용(Cost)
  • 물인지 육지인지

코드로 표현하면 다음과 같습니다.

enum Terrain {
  TERRAIN_GRASS,
  TERRAIN_HILL,
  TERRAIN_RIVER,
};
class World {
 private:
  Terrain mTiles[WIDTH][HEIGHT];
};

int World::getMovementCost(int x, int y) {
  switch (mTiles[x][y]) {
    case TERRAIN_GRASS:
      return 1;
    case TERRAIN_HILL:
      return 2;
    case TERRAIN_RIVER:
      return 3;
  }
}

bool World::isWater(int x, int y) {
  switch (mTiles[x][y]) {
    case TERRAIN_GRASS:
      return false;
    case TERRAIN_HILL:
      return false;
    case TERRAIN_RIVER:
      return true;
  }
}

문제없이 돌아가는 코드이지만 지저분하게 구현되어 있습니다. 데이터와 함수들이 분리되어 있어서 응집도도 떨어지기 때문에 이런 경우는 ‘지형 클래스’를 하나 별도로 구현하는 것이 좋습니다.

class Terrain {
 public:
  Terrain(int movementCost, isWater, Texture texture)
      : mMovementCost(movementCost), mIsWater(isWater), mTexture(texture) {
  }

  int getMovementCost() const {
    return mMovementCost;
  }

  bool isWater() const {
    return mIsWater;
  }

  const Texture &getTexture() const {
    return mTexture;
  }

 private:
  int mMovementCost;
  bool mIsWater;
  Texture mTexture;
};

그리고 ‘World’ 클래스도 각 타일마다 ‘Terrain’ 인스턴스를 하나씩 가지도록 하는 것이 아니라 객체 포인터를 가지게 하여 중복되는 데이터를 공유해서 사용할 수 있도록 하는 편이 바람직합니다.

class World {
 private:
  Terrain *mTiles[WIDTH][HEIGHT];
};

Terrain 인스턴스의 생명 주기를 좀 더 쉽게 관리하기 위해서 ‘World’ 클래스를 다음과 같은 코드로 수정합니다.

class World {
 public:
  World() : mGrassTerrain(1, false, TEXTURE_GRASS), mHillTerrain(2, false, TEXTURE_HILL),
            mRiverTerrain(3, true, TEXURE_RIVER) {}

  const Terrain &getTile() const;

 private:
  void generateTerrain();
  
  Terrain *mTiles[WIDTH][HEIGHT];

  Terrain mGrassTerrain;
  Terrain mHillTerrain;
  Terrain mRiverTerrain;
};

void World::generateTerrain() {
  for (int x = 0; x < WIDTH; x++) {
    for (int y = 0; y < HEIGHT; y++) {
      if (random(10) == 0) {
        mTiles[x][y] = &mHillTerrain;
      } else {
        mTiles[x][y] = &mGrassTerrain;
      }
    }
  }

  int x = random(WIDTH);
  for (int y = 0; y < HEIGHT; y++) {
    mTiles[x][y] = &mRiverTerrain;
  }
}

const Terrain &World::getTile(int x, int y) const {
  return *mTile[x][y];
}

객체 지향 프로그램의 특징

|

객체 지향 프로그래밍(Object-Oriented Programming, OOP)의 특징입니다.


Abstraction

가장 기본 적인 개념입니다. 불필요한 정보는 숨기고 필요한 정보만 일반적인 형태로 표현하는 것을 ‘추상화’라고 합니다.


Inheritance

기존의 클래스의 데이터나 형태 등을 물려받는 파생 클래스를 만들어내는 것을 ‘상속’이라고 하고, 기존 클래스는 부모 클래스, 물려받는 클래스를 자식 클래스라고 합니다. 상속을 통해 기존 클래스의 재활용성을 높이고, 불필요한 코드의 중복을 방지할 수 있습니다. 그리고 객체간의 종속 관계를 형성하여 다형성(Polymorphism)이라는 OOP의 핵심적인 특성을 제공할 수 있게 해줍니다.


Polymorphism

OOP의 핵심입니다. ‘다형성’이라는 말 그대로 특정한 요소가 다양한 형태를 가지게 되는 것을 말합니다.

예를 들면, Animal 이란 클래스가 있다고 가정하면, 이를 상속 받는 Dog 클래스와 Cat 고양이가 있을 수 있습니다. Dog 클래스와 Cat 클래스는 언제든지 Animal 클래스로 대체해서 사용이 가능합니다. (Dog 클래스와 Cat 클래스는 Animal의 모든 속성을 갖고 있기 때문입니다.)

이와 같이 추상화된 클래스를 상속받은 구체화된 클래스는 언제든지 부모 클래스로 취급을 받을 수 있습니다. 이러한 속성은 향후 동적 바인딩(Dynamic Binding)을 가능하게 해줍니다.

메소드 레벨에서의 다형성은 대표적으로 ‘오버로딩(Overloading)’과 ‘오버라이딩(Overriding)’이 있습니다.


Overloading vs Overriding

Overloading은 추가해서 더 싣는다고 생각하면 되며, 파라메터만 바꿔서 같은 이름의 메소드(함수)를 생성할 수 있는 것을 말합니다. 컴파일시에 결정되며 런타임 중에는 변경될 수 없습니다.

Overriding은 아예 태우는 것이라고 생각하면 되며, 상속시 부모 클래스와 자식 클래스의 메소드가 같을 경우 부모 클래스의 메소드 위에 자식 클래스를 태워서 실행시에 자식 클래스의 메소드가 호출되는 것을 말합니다. Dynamic Binding을 위한 중요한 개념입니다. Dynamic Binding은 이름 그대로 런타임 중에 변경될 수 있는 것을 의미합니다.

image -fullwidth

우측 cmd 키로 한/영 전환하기

|

우측 cmd 키로 한/영 전환하기

최신 Mac OS(시에라, Sierra)에서도 통하는 방법입니다. MAC OS에서는 기본적으로 한/영 전환을 Control + Space로 하고 있습니다. 그러다가 OS 버전이 Sierra가 되면서 Caps Lock 키로도 가능하도록 개선되었습니다.

어느 방법이든 Windows에서 일반적으로 사용하던 단축키와 달라 불편함을 겪어서 결국, Mac 에서의 한/영 전환을 Windows에 최대한 가깝게 만들기로 결심했습니다. 그래서 오른쪽 Command 로 한/영 전환을 할 수 있는 방법을 찾아보았습니다.

이 방법은 시에라 및 이전 버전의 OS에서도 작동하는 방법입니다.


Karabiner-Elements 설치

먼저 Karabiner-Elements를 설치합니다. 간편하게 여기에서 설치 파일을 다운받을 수 있습니다.


단축키 매핑

그런 다음 Karabiner-Elements를 실행합니다. 그리고 다음 그림과 같이 오른쪽 Command 키에 특수한 키를 매핑시키도록 합시다.

image

맥북 키보드엔 F1 ~ F12 까지 밖에 없으니, 그 이후 버튼(F13 ~ F20 등)을 매핑시켜주면 됩니다.

그런 다음 시스템 환경 설정으로 가서 키보드 설정을 선택합니다.

image

그리고는 입력 소스 단축키를 다음과 같이 설정합니다.

image