본문 바로가기

STUDY

(102)
5-1) 제네릭 클래스의 raw type은 사용하지 마라 제네릭 클래스 public class Printer { private T source; public Printer(T source) { this.source = source; } public void setSource(T source) { this.source = source; } public void print() { System.out.println(source); } } // 제네릭 클래스 덕분에 String, Integer 타입의 클래스를 따로 만들지 않고 사용할 수 있다. Printer strPrinter = new Printer("hello"); strPrinter.print(); Printer intPrinter = new Printer(100); intPrinter.print(); 제네릭 ..
4-10) 멤버 클래스는 되도록 static으로 만들어라 중첩 클래스 중첩 클래스란 다른 클래스 안에 정의된 클래스로서 이너 클래스(inner class)라고도 불린다. 중첩 클래스는 자신을 감싼 외부 클래스에서만 쓰여야 하며, 그 이외에 쓰임새가 있다면 탑레벨 클래스로 만들어야 한다. 중첩클래스는 1) 정적 멤버 클래스 2) 멤버 클래스 3) 익명 클래스 4) 지역 클래스와 같이 4개의 유형이 있다. 정적 멤버 클래스 public class MyClass { private Integer myNumber; public static class MyInnerClass { public void method(MyClass myClass) { Integer number = myClass.myNumber; } } } // 일반 클래스와 같이 사용할 수 있다. MyInne..
4-9) 태그 달린 클래스보다는 클래스 계층구조를 활용하라 태그달린 클래스 class Figure { enum Shape { RECTANGLE, CIRCLE }; // 도형의 형태를 나타내는 태그 필드 final Shape shape; double length; double width; double radius; Figure(double radius) { shape = Shape.CIRCLE; this.radius = radius; } Figure(double length, double width) { shape = Shape.RECTANGLE; this.length = length; this.width = width; } double area() { switch(shape) { case RECTANGLE: return length * width; case CI..
4-8) 인터페이스는 타입을 정의하는 용도로만 사용하라 인터페이스 MyInf instance1 = new MyInfImpl(); MyInf instance2 = new YourInfImpl(); 자바의 인터페이스는 (일반적으로) 구현이나 필드 없이 메소드만 정의되어있는 추상화된 요소이다. 개발자는 인터페이스를 구현하여 동일한 기능을 내부 구현을 다르게하여 만들 수 있다. 클라이언트에서는 다르게 만들어진 인터페이스의 구현체들을 내부 모습을 모른체로 사용할 수 있다. 이처럼 인터페이스는 다양한 구현체의 인스턴스를 참조할 수 있는 타입 역할을 한다. 상수 인터페이스 안티패턴 // 수학 상수들을 정의한 인터페이스 public interface Math { static final double pi = 3.141592; ... } 상수 인터페이스란 메소드 없이 상수값들..
5. Docker Hub로 이미지 push/pull, 사용하기 도커 이미지 공유하기 도커의 이미지에는 어플리케이션 파일과 시스템 설정, 도구, 패키지와 같은 실행에 필요한 모든 것이 갖추어져있는 소프트웨어 패키지이다. 만들어진 도커 이미지는 동료들이나 서버에 공유하여 사용한다. 이때 도커를 공유하는 방식은 두가지 생각해 볼 수 있다. 먼저 Dockerfile 소스를 공유하는 것이다. Dockerfile을 공유하고 이를 빌드하면 이미지가 만들어지기 때문에 이미지를 공유하는 것과 비슷한 효과이다. 하지만 Dockerfile을 빌드하는 과정이 추가적으로 필요하고, 빌드를 위해 필요한 로컬 파일이나 소스가 있다면 함께 공유해야한다는 단점이 있다. 그래서 두번째 방법인 도커 이미지를 공유하는 것이 일반적이다. 도커 이미지를 공유하면 빌드할 필요없이 바로 사용할 수 있고 부가..
4. Docker 이미지/컨테이너 관리하기2 docker rm, rmi > docker ps -a > docker rm {container_id} > docker rm {container_id1} {container_id2} {container_id3} .... > docker ps -a docker run 명령어는 새로 컨테이너를 만들면서 동작하기때문에 docker ps -a로 도커 컨테이너 리스트를 보면 많은 컨테이너가 존재하는걸 확인할 수 있다. 하지만 더이상 사용하지 않는 컨테이너가 계속 남아있는건 자원의 낭비이기 때문에 삭제해주어야 하고 이때 사용하는 명령어가 docker rm이다. docker rm은 컨테이너를 삭제하는 명령어인데, 실행중인 컨테이너는 삭제하지 못하기 때문에 실행중인 컨테이너도 지우고 싶으면 docker stop으로 먼저..
3. Docker 이미지/컨테이너 관리하기1 --help > docker --help ... ps List containers ... > docker ps 지금까지 docker run 으로 이미지를 컨테이너로 실행하고, 실행중인 컨테이너를 docker stop으로 중지시킨것처럼 docker에는 많은 명령어가 존재한다. 도커에는 수많은 명령어와 옵션이 존재하는데 이를 모두 외울수는 없다. 이때 쓸 수 있는것이 --help이다. --help를 명령어와 함께 실행하면 사용할 수 있는 명령어와 옵션을 알 수 있다. docker --help를 통해 컨테이러 리스트를 볼 수 있는 docker ps를 발견하고 실행하였다. > docker ps --help ... -a, --all Show all containers (default shows just runni..
4-7) 인터페이스는 구현하는 쪽을 생각해 설계하라 인터페이스와 디폴트 메소드 // MyInterface.java // MyInterface의 구현체인 MyClass가 존재하기 때문에 MyInterfece에 메소드를 추가하면 컴파일 에러가 발생한다. public interface MyInterface { public void method1(); } // MyClass.java public class MyClass implements MyInterface { @Override public void method1() { } } 인터페이스의 구현체가 한번 정의되고 나면 인터페이스에 메소드를 새로 추가하기 어렵다. 구현체 클래스는 개발당시의 인터페이스 메소드들을 구현했기 때문에, 새로 추가된 메소드는 미구현 상태가 되고 컴파일 에러가 발생한다. 따라서 인터페이스..