어느 관점에서 보느냐에 다르겠지만 , 디자인 패턴에서 의미하는 좋은 코드란
확장등 유지보수에 용이한 코드를 의미 한다.
3가지로 분류할 수 있으며 , 23개의 디장 패턴으로 구성 된다.
스프링을 사용하다 보면 , 자연스럽게 알게 되는 패턴이다.
단 하나의 인스턴스를 생성해서 사용하는 패턴이다.
public class SingleInstance{
private static SingleInstance instance= new SingleInstance();
private SigleInstance(){}
public static SingleInstance getInstance(){
return instance;
}
}
내부적으로 인스턴스 하나를 생성해 둔다.
객체를 추가적으로 생성하지 못하게 기본생성자를 직접 명시한 뒤 접근 제어자를 private로 막아둔다.
java를 공부하시면 아시겠지만 , 직접 명시하지 않고 생성자도 하나도 없는 경우 컴파일 과정에서 자동으로 기본 생성자가 public으로 만들어 지기 때문에 누군가가 접근해서 새로운 객체를 생성할 수 있게 되기 떄문.
마지막으로 , 그럼 미리 생성해둔 하나의 객체에는 접근할 수 있어야 하므로,
static메소드로 생성된 인스턴스를 반환해주는 메소드를 선언.
SingleInstance instance = SingleInstance.getInstance();
//객체 가져오기.
사용하게 될 경우 장점을 뭘까?
무분별하게 생성되는 객체로부터 메모리를 절약할 수 있다.
하나의 인스턴스를 여러곳에서 사용하기 때문에 , 데이터를 공유하기 쉽다.
반대로 단점은??
동시성 문제로부터 안전하지 않다.
테스트 하기가 어렵다.
객체를 얻어올 때 구체클래스에 의존하게 된다.
참고 :
https://jeong-pro.tistory.com/86
https://tecoble.techcourse.co.kr/post/2020-11-07-singleton/
기존의 인스턴스를 복제하여 새로운 객체를 생성하는 방법이다.
프로토타입패턴은 복사를 위해 자바에서 제공하는 clone메소드를 사용하는데 , 이를 위해서 Clonable인터페이스를 구현해야 한다.
//학생
@Getter @Setter
public Student {
public String name;
public String tel;
public Student(){}
public Student(String name , String tel){
this.name = name;
this.tel = tel;
}
}
//수업
@Setter @Getter
public Lesson implements Cloneable{
private String teacher; //담당 선생님
private String lessonName; //수업 이름
private List<Student> students; //학생명단
public Lesson(List<Student> students){
this.students = students;
}
@Override
protected Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
//Lesson 객체를 생성한다고 가정해보자.
List<Student> studentList = new ArrayList<>();
Student student1 = new Student("홍길동1" , "000-0000-0000");
Student student2 = new Student("홍길동2" , "111-1111-1111");
Student student3 = new Student("홍길동3" , "222-2222-2222");
studentList.add(student1);
studentList.add(student2);
studentList.add(student3);
Lesson math = new Lesson(studentList);
math.setTeacher("수학선생님");
math.setLessonName("수학-1");
여기까지 하나의 Lesson을 생성하는 과정이다.
앞으로 , 국어 ,과학 ,영어등 추가적인 수업 객체를 생성해야 하는데
듣는 학생들이 같다고 가정해보자.
학생이 같은데 매번 같은 과정을 진행하는 것은 비효율적이다.
이를 위해 clone메소드를 이용해 보자.
Lesson eng = new Lesson(studentList);
eng.setTeacher("영어선생님");
eng.setLessonName("영어-1");
//간단하게 새로운 Lesson객체 생성.
장점은 무엇일까??
객체의 생성이 값비싼 경우 객체 생성의 비용을 줄일 수 있다.
구현 클래스에 직접 연결하지 않고 객체를 복사할 수 있다.
clone()메소드는 Object 클래스의 메소드로, 얕은 복사로 동작하기에 깊은 복제를 사용해야 할 경우 clone()메소드 재정의 항상 고려.
Lesson math와 Lesson eng의 참조는 다르나 , 내부의 값인,
math.getStudentList() 와 eng.getStudentList(); 가 바라보는 참조가 같다.
결과적으로 math.getStudentList().add(학생5); 을 하면 , eng의 학생목록에서 학생5가 같이 존재하게 됨.