프록시 패턴이란? 대상 객체에 접근할때 직접 접근하지 않고 대상 객체를 대행하는 객체를 통해 간접적으로 접근하는 방식이다. 프록시의 사전적인 의미는 대리인이라는 뜻이다. 즉, 대상 객체의 대리인을 통해 접근하는 패턴이라고 이해하면 될 것이다. 프록시 서버를 생각하면 해당 패턴의 특징을 이해할 수 있을 것이다. 더보기 프록시 서버란? 서버와 클라이언트 사이에서 클라이언트가 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 시스템이다. 이제 프록시 패턴을 어떻게 구현하는지 확인해보자 public interface ISubject { void action(); } public class RealSubject implements ISubject { @Override public void action() ..
이터레이터 패턴이란? 이터레이터를 사용하여 컬렉션의 요소들에 접근하는 디자인 패턴이다. 해당 패턴을 통해 여러 가지 자료구조와 상관없이 이터레이터라는 하나의 인터페이스로 순회가 가능하다. 예제를 통해 어떻게 구현하는지 알아보자. 위의 사진과 같은 구조로 되어있고, 아래와 같이 코드를 구현했다. public interface Aggregate { Iterator createIterator(); } public class Book { private String name; public Book(String name) { this.name = name; } public String getName() { return name; } } public class BookShelf implements Aggregate ..
자바는 다양한 내부 라이브러리들을 제공하고 있는데, 그 중 정말 중요한 컬렉션 프레임워크에 대해 정리해보려고 한다. 앞으로 개발을 할 때 List, Set, Map 등 다양한 자료구조를 사용하게 될 텐데, 그 만큼 각 자료구조의 장/단점을 이해하고 있어야 상황에 맞는 자료구조를 이용할 수 있을 것 같다. 우리가 처음 배열을 배우면 int[], String[] 등 정적배열을 사용했을 것이다. 정적배열이다보니 연산을 하다보면 사이즈가 부족할 경우가 생기고, 배열 중간에 값의 삽입 또는 삭제가 어려울 것이다. 그리고 배열 사이즈를 미리 크게 할당할 경우에는 메모리 낭비가 심해질 것이다. 컬렉션 프레임워크는 이러한 문제들이 이미 구현되어 있어 개발자들은 해당 메서드들만 호출하여 사용하면 되기 때문에 훨씬 편해..
오늘은 재귀에 대해서 정리해보려고 한다. 재귀는 코테에서 가장 많이 나오는 DFS, BFS를 이해하기 위해서 반드시 알아야 하는 내용이기 때문에 정리한 후에도 계속 여러 예제들을 풀어보면서 습득해야될 것 같다. 재귀는 쉽게 말해서 자기 자신을 호출하는 함수이다. 예를 들어, 1부터 10까지 더하여 출력하도록 작업한다면 아래와 같이 for문을 이용하여 출력하는게 먼저 떠오를 것이다. public class Main { public static void main(String[] args) { System.out.println(loop()); } public static int loop() { int n = 0; for (int i = 1; i
자바를 처음 시작하면 문자열을 다루는 클래스 중 하나인 String을 가장 먼저 배울 것이다. 그리고 좀 더 공부하다보면 StringBuilder, StringBuffer를 배우게 될텐데 왜 이렇게 여러 클래스가 있는 것이고 언제 각 클래스를 써야하는지 정리해보려고 한다. String String 클래스는 문자열을 다루는 가장 기본적인 클래스로서 불변성이라는 특성을 가진다. 아래의 사진을 보면 String 클래스가 final로 선언되어 있는 것을 알 수 있다. String은 불변성을 가지고 있는데, +나 concat을 이용해 값을 추가하면 어떻게 될까? 아래의 예제를 통해 살펴보려고 한다. public class StringTest { public static void main(String[] args)..
Comparable과 Comparator가 필요한 이유와 이 둘의 차이점에 대해 한 번 정리해보려고 한다. 이 둘의 이름에서 유추할 수가 있듯이 뭔가 비교를 할 때 쓰이는 것 같은데 정확히 어떤 역할을 하는지 한번 알아보자. 왜 써야하는가? 우리가 가장 많이 대소 관계의 비교를 사용하는게 if문일 것이다. 아래처럼 기본 데이터 타입은 연산자를 통해 쉽게 비교가 가능하다. if (1 > 10) { System.out.println("참"); } else { System.out.println("거짓"); } 그렇다면 객체는 어떻게 비교(대소 관계)해야 할까? 이 때 '객체 간의 비교는 equals로 하지 않나? 라는 의문이 들 수 있는데, 여기서 말하는 비교란 대소 관계 (a > b, a = b, a < b..
상속을 공부할 때, 클래스 간의 다중 상속은 지원하지 않는다고 배웠다. (extends a, b 불가능) 근데 인터페이스는 다중 상속이 가능하다. (implements a, b 가능) 왜 인터페이스는 가능한지 의문이 들어서 내용을 정리해보려고 한다. 우선 클래스 간의 다중 상속은 왜 안될까? 자식 클래스가 2개의 부모 클래스를 상속 받는다고 가정하자. 부모 A, B 클래스에 각각 show() 라는 메서드가 정의되어 있다. 그러면 자식 클래스는 show()메서드를 A, B 중 어느 것을 상속받아야 할까? 자식 클래스에서는 알 수 없기 때문에 이미 구현된 동일한 메서드를 상속받는 것은 불가능하다. 인터페이스는 왜 다중 상속이 가능할까? 인터페이스는 메서드가 정의되어 있지 않다. 이 뜻은 인터페이스를 상속받으..
public class StudentTest { public static void main(String[] args) { Student me = new Student("park"); System.out.println(me); } } //결과 //hashandequal.practice01.Student@2d209079 객체를 만들고 해당 객체를 출력해보면 hashandequal.practice01.Student@2d209079 해당 값이 출력된다. 그 이유는 우리가 기본 생성자를 생성하지 않아도 컴파일러가 알아서 기본생성자를 생성해주는 것과 동일하게 객체를 출력하면 컴파일러가 자동으로 toString() 메서드를 실행한다. 그렇다면 toString() 메서드가 무엇인지 알아보자. toString() 개체의..