
객체지향 프로그래밍 족보
문서 내 토픽
-
1. 제너릭 코드제너릭 정의: 데이터 타입을 일반화(generalize) 하는 것을 의미합니다. 클래스나 메소드에서 사용할 내부 데이터 타입을 컴파일 시에 미리 지정하는 방법입니다. 객체의 타입 안정성을 높일 수 있으며, 반환값에 대한 타입 변환 및 타입 검사에 들어가는 노력을 줄일 수 있습니다.
-
2. ISP 설계원칙ISP 정의: 인터페이스 분리 원칙, 객체는 자신이 사용하는 메서드에만 의존해야 한다. 인터페이스를 분리하여 작성하면 객체가 불필요한 메서드에 의존하지 않게 됩니다.
-
3. DIP 설계원칙DIP 정의: 의존성 역전 원칙, 추상화에 의존하고 구체화에 의존하지 말기. 고수준 모듈은 인터페이스나 추상 클래스를 사용하고, 저수준 모듈은 구체적인 구현을 합니다. 이를 통해 사용자와 통신 모듈이 특정 구현에 의존하지 않게 됩니다.
-
4. List와 Collection 메소드 비교List 인터페이스에만 있는 메소드는 get, set입니다. Collection 인터페이스에는 add, isEmpty, contains 등의 메소드가 있습니다.
-
5. 박싱/언박싱자바의 데이터 타입은 원시타입과 참조타입(Wrapper 타입)이 있습니다. 박싱은 원시타입을 Wrapper 클래스로 변환하는 것이고, 언박싱은 그 반대입니다. 박싱/언박싱은 제너릭과 연관되어 사용되며, 불필요한 객체 생성으로 인해 성능 저하가 발생할 수 있습니다.
-
6. UIData 인터페이스UIData 인터페이스는 GUI 레이어에서 요소 클래스를 접근하기 위한 인터페이스이며, DataEngine 인터페이스는 GUI 레이어에서 엔진을 접근하기 위한 인터페이스입니다. UIData 인터페이스는 사용할 요소 데이터가 되기 위한 조건을 정의합니다.
-
7. Iterator 인터페이스Iterator 인터페이스는 자바에서 Collection 객체의 값을 가져오거나 조작할 때 사용하는 인터페이스입니다. 모든 컬렉션 프레임워크에 공통으로 사용되며, 코드 개발 및 유지보수에 용이합니다. 단방향 반복만 가능하고, 중간에 값을 변경/추가할 수 없습니다.
-
8. 이벤트 핸들러와 DIP이벤트 핸들러는 스윙에서 발생하는 사용자의 동작(이벤트)에 대해 응답을 담당하는 고수준 모듈입니다. DIP 설계원칙에 따라 이벤트 핸들러 구현 시 특정 스윙 컴포넌트에 종속되지 않도록 합니다. 액션 리스너에 인터페이스를 구현하여 이벤트 핸들러가 스윙 컴포넌트에 의존하지 않게 합니다.
-
9. 컬렉션 클래스 상속관계컬렉션 인터페이스는 List, Queue, Set 등으로 구성되며, List 인터페이스에는 ArrayList, LinkedList, Vector 등의 구현 클래스가 있습니다. Map 인터페이스에는 HashMap, LinkedHashMap, TreeMap 등의 구현 클래스가 있습니다.
-
10. 컬렉션 클래스의 벌크 연산컬렉션 클래스에서 벌크 연산을 이용하면 효율적인 알고리즘을 작성할 수 있습니다. 예를 들어 비당첨자 집합을 구하거나 중복 신청자 집합을 구할 수 있습니다.
-
1. 제너릭 코드제너릭 코드는 코드의 재사용성을 높이고 타입 안전성을 보장하는 중요한 기능입니다. 제너릭 코드를 사용하면 동일한 로직을 다양한 타입에 적용할 수 있어 코드의 중복을 줄일 수 있습니다. 또한 컴파일 시점에 타입 오류를 발견할 수 있어 런타임 오류를 방지할 수 있습니다. 제너릭 코드는 특히 컬렉션 클래스와 같이 다양한 타입의 데이터를 다루는 경우에 유용하게 사용될 수 있습니다. 하지만 제너릭 코드를 사용하기 위해서는 제너릭 타입 매개변수와 제너릭 메서드 등의 개념을 이해해야 하며, 이를 적절히 활용하는 것이 중요합니다.
-
2. ISP 설계원칙ISP(Interface Segregation Principle)는 클라이언트가 사용하지 않는 메서드에 의존하지 않도록 인터페이스를 작게 유지해야 한다는 원칙입니다. 이 원칙을 따르면 클라이언트 코드가 변경되더라도 다른 클라이언트에게 영향을 미치지 않으며, 인터페이스 구현 클래스의 변경도 최소화할 수 있습니다. 또한 ISP는 SRP(Single Responsibility Principle)와 밀접한 관련이 있어, 인터페이스의 책임을 명확히 정의하고 분리하는 것이 중요합니다. 이를 통해 코드의 유지보수성과 확장성을 높일 수 있습니다. 하지만 ISP를 지나치게 적용하면 인터페이스가 지나치게 세분화되어 복잡성이 증가할 수 있으므로, 적절한 수준의 인터페이스 분리가 필요합니다.
-
3. DIP 설계원칙DIP(Dependency Inversion Principle)는 상위 수준의 모듈이 하위 수준의 모듈에 의존하지 않도록 하는 원칙입니다. 이를 통해 모듈 간의 결합도를 낮추고 유연성을 높일 수 있습니다. DIP를 적용하면 상위 모듈이 인터페이스에 의존하도록 하여 하위 모듈의 구현 변경에 영향을 받지 않도록 할 수 있습니다. 이는 OCP(Open/Closed Principle)와도 관련이 있어, 기존 코드를 수정하지 않고도 새로운 기능을 추가할 수 있게 해줍니다. DIP는 특히 의존성 주입(Dependency Injection) 기법과 함께 사용되어 효과적으로 적용될 수 있습니다. 하지만 DIP를 적용하다 보면 추상화 수준이 높아져 복잡성이 증가할 수 있으므로, 적절한 수준의 추상화가 필요합니다.
-
4. List와 Collection 메소드 비교List와 Collection 인터페이스는 Java 컬렉션 프레임워크에서 중요한 역할을 합니다. List는 순서가 있는 데이터 집합을 표현하는 인터페이스이며, Collection은 List, Set, Queue 등 다양한 컬렉션 타입을 포괄하는 상위 인터페이스입니다. 이 두 인터페이스는 공통적으로 add(), remove(), contains() 등의 메서드를 제공하지만, 각각의 특성에 따라 추가적인 메서드를 제공합니다. 예를 들어 List는 get(), set(), indexOf() 등의 메서드를, Collection은 iterator(), toArray() 등의 메서드를 제공합니다. 이러한 차이점을 이해하고 상황에 맞는 인터페이스를 선택하는 것이 중요합니다. 또한 이 두 인터페이스는 다형성을 활용하여 코드의 재사용성을 높일 수 있습니다.
-
5. 박싱/언박싱박싱(Boxing)과 언박싱(Unboxing)은 Java에서 기본 데이터 타입과 래퍼 클래스 간의 변환 과정을 의미합니다. 박싱은 기본 데이터 타입을 해당 래퍼 클래스의 인스턴스로 변환하는 것이며, 언박싱은 그 반대 과정입니다. 이러한 변환은 자동으로 이루어지기 때문에 개발자가 직접 변환 코드를 작성할 필요가 없지만, 성능 측면에서는 주의가 필요합니다. 박싱/언박싱 과정에서 메모리 할당과 해제가 발생하므로, 이를 과도하게 사용하면 성능 저하가 발생할 수 있습니다. 따라서 필요한 경우에만 박싱/언박싱을 사용하고, 가능한 경우 기본 데이터 타입을 직접 사용하는 것이 좋습니다. 또한 Java 8부터 도입된 기본 데이터 타입 스트림 API를 활용하면 박싱/언박싱 없이 효율적으로 데이터를 처리할 수 있습니다.
-
6. UIData 인터페이스UIData 인터페이스는 UI 컴포넌트와 데이터 모델 간의 연결을 추상화한 인터페이스입니다. 이 인터페이스를 구현하면 UI 컴포넌트가 데이터 모델의 변경 사항을 감지하고 이에 따라 UI를 업데이트할 수 있습니다. UIData 인터페이스는 주로 MVC(Model-View-Controller) 또는 MVVM(Model-View-ViewModel) 아키텍처에서 사용되며, 이를 통해 UI 컴포넌트와 데이터 모델 간의 결합도를 낮출 수 있습니다. 이는 코드의 유지보수성과 확장성을 높이는 데 도움이 됩니다. 또한 UIData 인터페이스는 데이터 변경 이벤트를 발생시키는 등의 기능을 제공하여 UI 업데이트 프로세스를 효율적으로 관리할 수 있습니다. 이러한 특성으로 인해 UIData 인터페이스는 복잡한 UI 애플리케이션 개발에 유용하게 사용될 수 있습니다.
-
7. Iterator 인터페이스Iterator 인터페이스는 Java 컬렉션 프레임워크에서 컬렉션의 요소를 순차적으로 접근할 수 있는 기능을 제공합니다. Iterator 인터페이스는 hasNext(), next(), remove() 메서드를 정의하며, 이를 통해 컬렉션의 요소를 안전하고 효율적으로 순회할 수 있습니다. 이는 컬렉션의 내부 구현 방식에 상관없이 일관된 방식으로 요소에 접근할 수 있게 해줍니다. 또한 Iterator 인터페이스는 for-each 루프와 함께 사용되어 코드의 가독성과 생산성을 높일 수 있습니다. 이처럼 Iterator 인터페이스는 컬렉션 처리에 있어 필수적인 역할을 하며, 개발자가 이를 효과적으로 활용할 수 있도록 이해하는 것이 중요합니다.
-
8. 이벤트 핸들러와 DIP이벤트 핸들러와 DIP(Dependency Inversion Principle)는 객체 지향 프로그래밍에서 중요한 개념입니다. 이벤트 핸들러는 특정 이벤트가 발생했을 때 실행되는 코드 블록을 의미하며, DIP는 상위 수준의 모듈이 하위 수준의 모듈에 의존하지 않도록 하는 원칙입니다. 이 두 개념은 서로 밀접한 관련이 있습니다. 이벤트 핸들러를 DIP에 따라 설계하면 이벤트 발생 시 상위 모듈이 하위 모듈의 구현에 의존하지 않도록 할 수 있습니다. 이를 통해 이벤트 핸들러의 유연성과 재사용성을 높일 수 있습니다. 예를 들어 이벤트 핸들러가 인터페이스에 의존하도록 설계하면 하위 모듈의 구현이 변경되더라도 상위 모듈에 영향을 미치지 않습니다. 이처럼 이벤트 핸들러와 DIP를 함께 적용하면 객체 지향 설계 원칙을 효과적으로 구현할 수 있습니다.
-
9. 컬렉션 클래스 상속관계Java 컬렉션 프레임워크에서 컬렉션 클래스들은 상속 관계를 가지고 있습니다. 이 상속 관계는 컬렉션 클래스들 간의 공통 기능을 효과적으로 재사용할 수 있게 해줍니다. 예를 들어 List 인터페이스를 구현한 ArrayList와 LinkedList 클래스는 공통적으로 add(), get(), remove() 등의 메서드를 제공합니다. 이러한 공통 기능은 상위 클래스인 AbstractList에 구현되어 있어, 하위 클래스들이 이를 상속받아 사용할 수 있습니다. 또한 Set 인터페이스를 구현한 HashSet, TreeSet, LinkedHashSet 클래스들도 상위 클래스인 AbstractSet을 통해 공통 기능을 공유합니다. 이처럼 컬렉션 클래스들의 상속 관계를 이해하면 컬렉션 API를 효과적으로 활용할 수 있습니다. 단, 상속 관계를 잘못 사용하면 코드의 복잡성이 증가할 수 있으므로 적절한 설계가 필요합니다.
-
10. 컬렉션 클래스의 벌크 연산Java 컬렉션 프레임워크에서 제공하는 벌크 연산(Bulk Operations)은 컬렉션 내의 여러 요소를 한 번에 처리할 수 있는 기능입니다. 대표적인 벌크 연산으로는 addAll(), removeAll(), retainAll(), containsAll() 등이 있습니다. 이러한 벌크 연산을 사용하면 개별 요소를 처리하는 것보다 효율적으로 컬렉션을 다룰 수 있습니다. 예를 들어 removeAll() 메서드를 사용하면 한 컬렉션의 요소를 다른 컬렉션에서 제거할 수 있습니다. 또한 스트림 API와 함께 사용하면 복잡한 데이터 처리 로직을 간단하게 구현할 수 있습니다. 벌크 연산은 컬렉션 처리 시 발생할 수 있는 반복적인 코드를 줄여주어 코드의 가독성과 유지보수성을 높일 수 있습니다. 다만 벌크 연산 사용 시 컬렉션의 상태 변화를 주의 깊게 관찰해야 하며, 적절한 사용 방법을 숙지하는 것이 중요합니다.
객체지향 프로그래밍 족보
본 내용은 원문 자료의 일부 인용된 것입니다.
2024.02.20