객체는 클래스가 아닌 인터페이스로 참조하라

클래스가 아닌 인터페이스로 참조하는 예시

• 적합한 인터페이스가 있다면 객체를 클래스 타입이 아닌 인터페이스 타입으로 선언하는 것이 좋다.

    ◦ 이렇게 되면 구체적인 클래스 타입은 객체를 생성할 때 생성자에서만 사용하면 된다

    ◦ 아래는 Set 인터페이스를 구현한 LinkedHashSet 변수를 선언하는 코드이다.

LinkedHashSet implements Set

코드의 유연성을 높이는 설계

• 기존에 사용하던 구현 클래스 타입을 다른 것으로 바꿔야 하는 상황이 종종 있다.

    ◦ 더 성능이 좋은 클래스 타입을 사용하고 싶은 경우

    ◦ 더 다양한 신기능을 사용할 수 있는 클래스 타입이 있는 경우

         -  HashMap 보다 EnumMap 이 속도도 더 빠르고 순회 순서도 키의 순서와 같아 순서 예측이 가능하다.

         -  EnumMap 은 키가 열거 타입인 경우에만 사용할 수 있다. 이 때 LinkedHashMap 을 사용하면 키 타입과 상관없이

            사용할 수 있으면서 순회 순서를 예측할 수 있다.

• 인터페이스 타입으로 객체를 참조했다면 이런 변동사항에 훨씬 유연한 대처가 가능하다.

    ◦ 구현 클래스를 교체하고 싶다면 다른 클래스의 생성자를 호출해주기만 하면 되기 때문

 

• Example

    ◦ LinkedHashSet 대신 HashSet 를 사용하려고 코드를 수정하는 경우

    ◦ Set 인터페이스를 사용한 경우 우변의 생성자 외 부분은 수정이 필요 없다

    ◦ LinkedHashSet 클래스를 사용한 경우 좌, 우변 모두 수정이 필요하다.

 

    ◦ 그러나 누군가는 이렇게 생각할 수 있다

         -  굳이 인터페이스 써야 하나? 그냥 클래스 쓰고 나중에 수정할 때 좌, 우변 다 바꿔주면 되는거 아님?

         -  그러나 이 방법은 자칫하면 컴파일 에러가 발생할 수 있다.

         -  처음에 객체를 인터페이스로 만들었다면, 메소드를 설계할 때 파라미터로 인터페이스 객체를 받도록 유도할 수 있다.

         -  처음에 객체를 클래스 만들었다면, 메소드를 설계할 때 인터페이스가 아닌 클래스 객체를 파라미터로 받게 해버리는 상황이

            발생할 수 있다.

         -  인터페이스를 사용하면 이후 구체 클래스가 바뀌어도 컴파일 문제가 없으나 클래스를 사용하면 구체 클래스가

            바뀔 때 컴파일 문제가 생긴다. (즉 하나가 바뀔 때 수정해야 하는 부분이 더 많아진다 : 유연성 낮음)

         -  즉 애초에 변수를 인터페이스 타입으로 선언해 이 문제를 방지하자.

 

• 주의사항

    ◦ 기존에 사용하던 구현 클래스 타입을 다른 것으로 바꿀 때 유의사항

    ◦ 원래의 클래스가 인터페이스 레벌에서는 없는 특별한 기능을 제공했고, 주변 코드가 이 기능에 의존하여 동작하고 있었다면

      새로운 클래스도 동일한 기능을 제공해야 코드가 깨지지 않는다.

         -  LinkedHashSet 는 반복자의 순회 순서를 보장한다. 이를 염두에 두고 코드를 작성한 상황에서 LinkedHashSet

            HashSet 으로 대체해버리면 연산 오류가 발생할 수 있다.


참조할 만한 인터페이스가 없는 경우

값 클래스 (Value Class)

• 한번 값이 할당 된 이후에 변경되지 않음을 보장해야 하는 경우

    ◦ 예) String, BigInteger 등의 불변 객체

• 값 클래스가 여러가지로 구현될 수 있음을 염두에 두고 설계하는 일이 거의 없다.

• final 인 경우가 많고 상응하는 인터페이스가 별도로 존재하는 경우가 드물다.

• 값 클래스는 매개변수 / 변수 / 필드 / 반환 타입으로 사용해도 무방하다.

 

클래스 기반으로 작성된 프레임워크가 제공하는 객체

• OutputStreamjava.io 패키지의 여러 클래스가 이 부류에 속한다.

 

인터페이스에는 없는 특별한 메소드를 제공하는 클래스

• PriorityQueue 클래스는 Queue 인터페이스에는 없는 comparator 메서드를 제공한다.

• 클래스 타입을 직접 사용하는 경우, 이런 특별 메서드의 사용은 꼭 필요한게 아니라면 최소화하는 것이 좋다.

    ◦ 코드의 유연성을 많이 떨어트리기 때문


정리

객체를 표현할 적절한 인터페이스가 있는지 먼저 찾아보자. 인터페이스로 객체를 참조하면 더 유연한 코드를 작성할 수 있기 때문이다.

만약 없다면, 필요한 기능을 제공해주는 범위 내에서 가장 상위 클래스의 타입을 사용하자.

 

 

인터페이스

• 응용 프로그램과 커널의 첫번째 인터페이스

• 커널에 사용자의 명령을 전달하고 실행 결과를 다시 사용자에게 알려주는 역할

• 운영체제는 커널과 인터페이스를 분리하며, 같은 커널이여도 다른 인터페이스 형태로 제작 가능하다.

    ◦  같은 커널이라도 다른 인터페이스가 장착되면 사용자에게 다른 운영체제로 보일 수 있다.

          -  예) 유닉스의 인터페이스는 쉘(shell)이라 하며, bash 쉘, C 쉘, T 쉘 등 여러 종류가 있다.


시스템 호출

• 응용 프로그램과 커널의 두번째 인터페이스

• 커널은 사용자나 응용 프로그램으로부터 컴퓨터 자원을 보호하기 위해 외부에서 자원에 직접 접근하는 것을 차단한다.
   따라서 자원을 이용하기 위해서는 시스템 호출 이라는 인터페이스를 사용해 접근해야 한다.


커널

• 운영체제 중 항상 필요한 부분만을 전원이 켜짐과 동시에 메모리에 올려놓고, 그렇지 않은 부분은 필요할 때 메모리에 올려서 사용하는데
    이 때 메모리에 상주하는 부분을 커널 이라 부른다.

• 주로 하는 일은 메모리 관리, 프로세스 관리, 파일 시스템 관리, 입출력 관리, 프로세스 간 통신 관리 등이 있다.

 

단일형 구조 커널

    ◦  초창기 커널 구조. 커널의 핵심 기능을 구현하는 모듈이 구분 없이 하나로 구성되어 있다.

    ◦  장점

          -  모듈 간의 통신 비용이 적어 효율적이다.

    ◦  단점

          -  모든 모듈이 하나로 묶여 있기 때문에 버그나 오류를 처리하기 어렵다.

          -  기능 간 상호 의존성이 높기 때문에 한 기능의 결함이 시스템 전체 결함으로 이어질 수 있다.

          -  다양한 환경 시스템에 적용하기 어렵다. (수정이 불가능하므로)

 

계층형 구조 커널

    ◦  단일형 구조 커널이 발전된 형태. 비슷한 기능을 가진 모듈을 묶어서 하나의 계층으로 만들고,

        계층 간의 통신을 통해 운영체제를 구현하는 방식

    ◦  비슷한 기능 끼리 모듈화 되어 있기 때문에 오류가 발생하면 문제가 있는 계층만 고치면 되는 등 단일형 구조보다 버그나 오류를

         쉽게 고칠 수 있다.


드라이버

• 응용 프로그램과 커널의 인터페이스가 시스템 호출이라면 커널과 하드웨어의 인터페이스드라이버이다.

• 다양한 하드웨어에 맞는 인터페이스를 직접 개발하는 것은 어렵기 때문에, 하드웨어의 특성을 반영한 소프트웨어인 디바이스 드라이버

    하드웨어 제작자에게 받아 커널이 실행될 때 함께 실행되도록 한다.


참고자료

 

운영체제 - YES24

운영체제

www.yes24.com

 

'CS Knowledge > 운영체제' 카테고리의 다른 글

[OS] CPU 스케줄링 개념  (0) 2022.09.16
[OS] 스레드와 멀티스레드  (0) 2022.09.08
[OS] 프로세스와 Context Switching  (0) 2022.09.08
[OS] 운영체제 개요  (0) 2022.09.07
[OS] 운영체제와 프로세스 & 스레드  (0) 2022.06.26