1. 객체 지향(Object oriented) 프로그래밍이란?
2. 절차 지향과 객체 지향
- 절차 지향
- 객체 지향
- 절차 지향 VS 객체 지향
3. 객체 지향 프로그래밍의 특징
- 객체 지향 프로그래밍의 장점
- 소프트웨어의 생산성 향상
- 실세계에 대한 쉬운 모델링
- 보안성 향상
- 객체 지향 프로그래밍의 단점
- 느린 실행 속도

객체 지향(Object oriented) 프로그래밍이란? #
우리가 실생활에서 쓰는 모든 것을 객체라 하며, 객체 지향 프로그래밍은 프로그램 구현에 필요한 객체를 파악하고 각각의 객체들의 역할이 무엇인지를 정의하여 객체들 간의 상호작용을 통해 프로그램을 만드는 것을 말한다. 객체는 클래스라는 틀에서 생겨난 실체(instance)이다. 따라서 객체 지향 프로그램은 객체와 객체 간의 연결로 되어 있으며 각각의 객체 안에 자료구조와 알고리즘이 들어있는 것이다.

절차 지향과 객체 지향 #

그림1 절차 지향과 객체 지향 방식



절차 지향 #
절차 지향 모델링은 프로그램을 기능중심으로 바라보는 방식으로 "무엇을 어떤 절차로 할 것인가?"가 핵심이 된다. 즉, 어떤 기능을 어떤 순서로 처리하는가에 초점을 맞춘다.

객체 지향 #
객체 지향 모델링은 기능이 아닌 객체가 중심이 되며 "누가 어떤 일을 할 것인가?"가 핵심이 된다. 즉, 객체를 도출하고 각각의 역할을 정의해 나가는 것에 초점을 맞춘다.

절차 지향 VS 객체 지향 #
대형 프로그래밍의 경우 많은 기능을 수반하기 때문에 절차 지향보다는 객체 지향이 적합

각 객체가 하는 역할이 많아도, 많은 역할을 객체로 묶을 수 있기 때문
소형 프로그래밍의 경우 작은 기능을 수반하기 때문에 객체 지향보다는 절차 지향이 적합

작은 기능을 객체별로 나눌 경우, 오히려 복잡해질 수 있기 때문
객체 지향 프로그래밍의 특징 #
추상화(abstraction)

객체들의 공통적인 특징(기능, 속성)을 도출하는 것
객체지향적 관점에서는 클래스를 정의하는 것을 추상화라고 할 수 있다.(클래스가 없는 객체지향 언어도 존재 ex.JavaScript)
캡슐화(encapsulation)

실제로 구현되는 부분을 외부에 드러나지 않도록 하여 정보를 은닉할 수 있다.
객체가 독립적으로 역할을 할 수 있도록 데이터와 기능을 하나로 묶어 관리하는 것
코드가 묶여있어서 오류가 없어 편리하다.
데이터를 보이지 않고 외부와 상호작용을 할 때는 메소드를 이용하여 통신을 한다. 보통 라이브러리로 만들어서 업그레이드해 사용할 수 있다.
상속성(inheritance)

하나의 클래스가 가진 특징(함수, 데이터)을 다른 클래스가 그대로 물려받는 것
이미 작성된 클래스를 받아서 새로운 클래스를 생성하는 것
기존 코드를 재활용해서 사용함으로써 객체지향 방법의 중요한 기능 중 하나에 속한다.
다형성(polymorphism)

약간 다른 방법으로 동작하는 함수를 동일한 이름으로 호출하는 것
동일한 명령의 해석을 연결된 객체에 의존하는 것
오버라이딩(Overriding), 오버로딩(Overloading)

오버라이딩(Overriding) - 부모클래스의 메소드와 같은 이름을 사용하며 매개변수도 같되 내부 소스를 재정의하는 것
오버로딩(Overloading) - 같은 이름의 함수를 여러 개 정의한 후 매개변수를 다르게 하여 같은 이름을 경우에 따라 호출하여 사용하는 것
동적바인딩(Dynamic Binding)

가상 함수를 호출하는 코드를 컴파일할 때, 바인딩을 실행시간에 결정하는 것.
파생 클래스의 객체에 대해, 기본 클래스의 포인터로 가상 함수가 호출될 때 일어난다.
함수를 호출하면 동적 바인딩을 통해 파생 클래스에 오버라이딩 된 함수가 실행
프로그래밍의 유연성을 높여주며 파생 클래스에서 재정의한 함수의 호출을 보장(다형 개념 실현)
객체 지향 프로그래밍의 장점 #
소프트웨어의 생산성 향상 #
객체지향 프로그래밍은 다형성, 객체, 캡슐화 등 소프트웨어의 재사용을 지향한다. 이미 만들어진 클래스를 상속받거나 객체를 가져다 재사용하거나, 부분 수정을 통해, 소프트웨어를 작성하는 부담을 대폭 줄일 수 있다.

신뢰성 있는 소프트웨어를 손쉽게 작성할 수 있다. (개발자가 만든 데이터를 사용하기 때문에 신뢰할 수 있다.)
코드를 재사용하기 쉽다 (상속, 캡슐화, 다형성으로 인해 재사용할 수 있다.)
업그레이드가 쉽다.
디버깅이 쉽다.
실세계에 대한 쉬운 모델링 #
컴퓨터가 산업 전반에 다양하게 활용되는 요즘 시대에는 응용 소프트웨어를 하나의 절차로 모델링하기 어렵다. 산업 전반에서 요구되는 응용 소프트웨어 특성상, 절차나 과정보다 관련된 많은 물체(객체)들의 상호 작용으로 묘사하는 것이 더 쉽고 적합하다.

실세계에 대한 모델링을 좀 더 쉽게 해준다. (모든 것을 객체들의 상호작용으로 생각)
보안성 향상 #
객체 지향적 프로그래밍의 캡슐화 특징으로 실제로 구현되는 부분을 외부에 드러나지 않도록 하여 정보를 은닉할 수 있다.

보안성이 높다 (캡슐화, 데이터 은닉, 다형성으로 인해 필요한 정보를 재정의하거나 getter, setter를 이용하기 때문에 보안성이 높다.)
객체 지향 프로그래밍의 단점 #
느린 실행 속도 #
객체 지향 프로그래밍은 캡슐화와 격리구조에 때문에 절차지향 프로그래밍과 비교하면 실행 속도가 느리다. 또한, 객체지향에서는 모든 것을 객체로 생각하기 때문에 추가적인 포인터 크기의 메모리와 연산에 대한 비용이 들어가게 된다.

절차지향 프로그래밍에 비해 느린 실행 속도
필요한 메모리양의 증가

/*Singletone Pattern sample*/

using System;
using System.Drawing;

public class APMMemory
{
    private static APMMemory apmMemory=null;
    string ____processid;
    System.Drawing.Color ____bgColor;

    public static APMMemory GetInstance
    {
        get
        {
            if(apmMemory == null)
            {
                apmMemory=new APMMeory();
                Console.WriteLine("Singletone Pattern sample");
            }
        }
    }
    public string processid
    {
        get{return ____processid;}
        set{___processid=value;}
    }
    public System.Drawing.Color bgColor
    {
        get{return ____bgColor;}
        set{____bgColor=value;}
    }
}
class SampleManage
{
    public void running()
    {
        Console.WriteLine("" + APMMemory.GetInstance.processid);
        Console.WriteLine("" + APMMemory.GetInstance.bgColor);
    }
}
class Program
{
    public static void Main()
    {
        APMMemory.GetInstance.processid = "9999";
        APMMemory.GetInstance.bgColor=System.Drawing.Color.SteelBlue;

        SampleManage nm = new SampleManage();
        nm.running();
    }
}


/*Update by 2022.04.18*/

int common_chek(int direction)
{
    int ii,kk;
    int[,] tmp = new int[MAPY,MAPX];

    for(ii=0; ii <MAPY; ii++)
    for(kk=0; kk<MAPX; kk++)
    {
        tmp[ii,kk]=comm[ii,kk];
    }

    for(ii=0; ii<ARR; ii++)
    for(kk=0; kk<ARR; kk++)
    {
        if(design[ii,kk]==1)
        {
             if(ypos+ii>MAPY-1) continue;
             if(xpos+kk>MAPX-1) continue;
             if(xpos+kk<0) continue;

             tmp[ypos+ii,xpos+kk]=0;
        }
    }

    if(direction==D_RIGHT) xpos++;
    if(direction==D_LEFT) xpos--;
    if(direction==D_DOWN) ypos++;

    ff=0;
    for(ii=0; ii<ARR; ii++)
    for(kk=0; kk<ARR; kk++)
    {
        if(design[ii,kk]==1)
        {
             if(ypos+ii>MAPY-1) continue;
             if(xpos+kk>MAPX-1) continue;
             if(xpos+kk<0) continue;

             tmp[ypos+ii,xpos+kk] += 1;
             if(tmp[ypos+ii,xpos+kk]>1) ff++;
        }
    }

    if(ff>0)
    {
        if(direction==D_RIGHT) xpos--;
        if(direction==D_LEFT) xpos++;
        if(direction==D_DOWN) ypos--;

        return(FAIL);
    }
    else
    {
        for(ii=0; ii<MAPY; ii++)
        for(kk=0; kk<MAPX; kk++)
        {
            comm[ii,kk]=tmp[ii,kk];
        }
    }
    return(SUCC);
}

/*
c# 프로그램 전체 종료*/

1. Console

Environment.Exit(0);

2. Windows Form

Application.Exit();

1. 외부 시스템에 제공할 서비스 또는 객체 정보를 직접적인 class가 아닌 "선언" 만을 제공한다.

2. 다중 상속에 따른 class의 표현을 여러가지로 가능하게 한다.

C Pattern(C로 만드는 Interface)

Java에서는 객체지향, 패턴, Interface을 빼놓고는 아무것도 아닙니다. Interface를 사용해야 언제든지 교체가능한 모듈형태의 프로그래밍을 할 수 있습니다.
Interface의 필요성에 대해서는 다른 곳에도 많이 나와 있기때문에 따로 설명하지 않겠습니다. C로 Interface를 만들어 보겠습니다. 이번에 만들 Interface는 UART입니다.
UART는 MCU와 Device와의 커뮤니케이션 도구로 많이 사용합니다. 예를 들면 GPS Module, RS232를 통한 PC와의 통신 등등에서 사용되므로 Interface를 설명하기에 적합합니다. 

typedef struct
{
    InitFunction Init;
    OpenFunction Open;
    TxHandlerFunction TxHandler;
    RxHandlerFunctioin RxHandler;
    //....(필요시 추가)

}UartInterface;



우선 UART interface를 만들었습니다. 이 interface를 이용해서 GPS Device Interface를 만들어 보겠습니다.

GpsUart.c 에는 다음과 같은 코드가 들어가야 합니다.

void CreatGpsUart(UartInterface *uart)
{
  uart->Open = GpsUartOpen;
  uart->TxHandler = GpsTxHandler;
  uart->RxHandler = GpsRxHandler;
}
void GpsUartOpen()
{
//
}
void GpsTxHandler()
{
//
}

void GpsRxHandler()
{
//
}

Rs232.c 에는 다음과 같은 코드가 들어가야 합니다.

CreatRs232Uart(UartInterface *uart)
{
  uart->Open = Rs232UartOpen;
  uart->TxHandler = Rs232TxHandler;
  uart->RxHandler = Rs232RxHandler;
}
void Rs232UartOpen()
{
//
}

void Rs232TxHandler()
{
//
}

void Rs232RxHandler()
{
//
}

이제 Main.c를 살펴보겠습니다.

UartInteface gGpsUart;
UartInteface gRs232Uart;

void main(void)
{
    CreatGpsUart(&gGpsUart);
    CreatRs232Uart(&gRs232Uart);

    //...
}

UartInterface를 통해 두가지 기능을 만들어 냈습니다. 

/*
interface는 규약이다. usb를 예로 들어보면(?) */

windows os를 사용하는 노트북에 usb를 꽂는다. 이 usb가 어느제조업체에서 만들었는지 알수있는
windows 제어판을 제공한다고 하자.

usb를 만드는 제조업체는 반드시 제조업체와 만든날짜 그리고 버젼을 등록하고 싶다.
windows os의 개발도구 interface를 이용해서 가능하게 할수 있다.

 

interface ____usb_register
{
    public void register_company();
    public void register_version();
    public void register_date();
}

위의 interface를 상속해서 반드시 구현해 주어야 windows os에 usb를 꽂으면 제어판에서 usb의 개략정보를
확인할수 있다.
즉 usb제조업체에서 위의 ____usb_register interface를 상속해서 메소드를 구현해주어야 한다.

/*interface는 규약이다. 반드시 interface상속을 했으면 규약대로 구현을 해야 한다.
상속했는데, 구현을 안했다면 위배가 된다.
usb를 예로 들수 있다. usb를 만든업체는 windows라는 os에서 동작하도록 하려면
windows os에서 규약해놓은 interface의 대부분을 구현해줘야 usb를 노트북이나 데스크탑에 꽂았을때에
제대로 동작하는것이다. usb를 만들어서 windows os에서 동작하려면, windows os의 interface규약집을 참조하여
구현하여야 할것이다. 그러므로 method의 선언만 되어 있을뿐, 구현되는부분은 usb제조사에서 구현해서
사용해야 한다.*/

using System;

interface IAnimal
{
void Eat();
}

interface IAnimalDrink
{
void Drink();
}

class Person : IAnimal,IAnimalDrink
{
public void Eat()
{
Console.WriteLine("Rice.Shape Eating,,,,!!");
}
public void Drink()
{
Console.WriteLine("Water.Shape Drinking,,,,!!");
}
}

class Lion : IAnimal,IAnimalDrink
{
public void Eat()
{
Console.WriteLine("Meat.Shape Eating,,,,!!");
}
public void Drink()
{
Console.WriteLine("Water.Shape Drinking,,,,!!");
}
}

class Camel : IAnimalDrink
{
public void Eat()
{
Console.WriteLine("Green.Shape Eating,,,,!!");
}
public void Drink()
{
Console.WriteLine("Water.Shape Drinking,,,,!!");
}
}

class Program
{
static void Main(string[] args)
{
Person myPerson = new Person();
Lion myLion = new Lion();
Camel myCamel = new Camel();

ExecuteInterface(myCamel);
ExecuteInterface(myPerson);
ExecuteInterface(myLion);
}
private static void ExecuteInterface(object obj)
{
IAnimal target1 = obj as IAnimal;
if (target1 != null)
{
target1.Eat();
}

IAnimalDrink target2 = obj as IAnimalDrink;
if (target2 != null)
{
target2.Drink();
}
}
}

+ Recent posts