① SRP(Single Responsibility Principle)
② OCP(Open/Closed Principle)
③ LSP(Liskov Substitution Principle)
④ ISP(Interface Segreation Principle)
⑤ DIP(Dependency Inversion Principle)
① 어댑터 패턴
② 프록시 패턴
③ 데코레이터 패턴
④ 싱글톤(SingleTon) 패턴
③ 옵저버 패턴
④ 파사드(Facade) 패턴
자바는 표준 입출력 장치를 위해 System이라는 표준 입출력 클래스를 정의한다. java.lang 패키지에 포함되어 있으며 아래의 클래스 변수를 제공한다.
입출력 스트림은 자바가 자동 생성하므로 개발자가 별도로 생성하지 않아도 된다.
표준 입출력의 대상을 변경하는 것도 가능하다. 앞서 살펴본 세가지 입출력 스트림은 모두 콘솔을 대상으로 한다. System의 메서드를 활용하면 스트림의 대상을 다른 입출력 장치로 변경할 수 있다.
입출력 스트림을 사용하면 파일을 통한 입출력 작업도 수행할 수 있다. 하지만 입출력 작업 이외의 다른 작업은 수행할 수 없기 때문에 자바는 File클래스를 통해 아래의 기능을 제공한다.
입출력은 쉽게 말해 한쪽에서 다른쪽으로 데이터를 전달하는 것이다. 이 때 입출력을 위한 데이터의 흐름을 스트림이라고 한다. 스트림은 연속적인 데이터의 흐름을 물에 비유해서 붙여진 이름인데, 물이 한쪽 방향으로만 흐르듯이 스틈 또한 단방향 통신만 가능하다. 그러므로 입력과 출력을 동시에 수행하기 위해선 입력스트림과 출력스트림, 총 2개의 스트림이 필요하다. 스트림은 FIFO 구조를 이룬다. 이러한 스트림에는 바이트 기반 스트림과 문자 기반 스트림이 있다.
바이트 기반 스트림(InputStream, OutputStream)은 바이트 단위로 데이터를 전송한다. 즉, 입출력의 단위가 1byte이다. InputStream클래스에서 제공하는 메서드는 아래와 같다.
참고로 read()의 반환타입이 byte가 아니라 int인 이유는 읽기에 실패한 경우 -1을 반환해야 하기 때문이다. OutputStream클래스의 메서드는 아래와 같다.
문자기반 스트림(Reader, Writer)은 바이트 기반의 스트림으로는 2byte 문자(자바는 문자를 2byte의 유니코드로 처리함)를 처리하기 어렵기 때문에 사용된다. 따라서 문자데이터를 입출력할 때는 문자 기반 스트림을 사용하는 것이 좋다.
스트림의 기능을 추가, 확장, 보완해주는 역할로 보조스트림도 있다. 그리고 보조스트림에는 바이트 기반 보조스트림과 문자기반 보조스트림이 있다.
문자열을 입력받는 코드를 생각해보자. 문자열을 입력받는 방법에는 두가지가 있는데, 첫번째는 Scanner를 이용하는 것이고, 두번째는 BufferReader를 이용하는 것이다. Scanner는 바이트기반 입력이고, BufferReader는 문자열 기반 입력이다.
Scanner방식이 BufferReader에 비해 코드가 간결하고, int, long, short, float, double, String을 nextInt(), nextLong(), nextShort(), nextFloat(), nextDouble(), nextLine()과 같은 함수로 모두 받을 수 있다.
반면 BufferReader는 오직 String형식의 값만 읽을 수 있기에 readLine()함수만 사용 가능하다. 다만, 그 외에 모든 점은 다 BufferReader가 좋다고 보면 된다. 메모리 용량도 효율적이고 멀티쓰레드 환경에서도 안전하며, 실행속도도 매우 빠르다. 형식은 아래의 예시를 참고하자.