[자바 디자인 패턴] 생성패턴 - 싱글톤 패턴
생성패턴 목록
- 팩토리 메소드 패턴 (Factory Method Pattern)
- 추상 팩토리 패턴 (Abstract Factory Pattern)
- 싱글톤 패턴 (Singleton Pattern)
- 프로토타입 패턴 (Prototype Pattern)
- 빌더 패턴 (Builder Pattern)
- 오브젝트 풀 패턴 (Object Pool Pattern)
싱글톤 패턴은 Enum Class 로 작성하는 것이 가장 효율적이라고 한다
장점
- 각 요청에서 객체가 생성되지 않으므로 메모리를 절약합니다.
- 하나의 인스턴스만 반복해서 재사용할 수 있습니다.
사용시기
- 멀티스레드 및 데이터베이스 응용 프로그램에서 사용합니다.
- 로깅, 캐싱, 스레드 풀, 구성설정 등
UML
Singleton Class : JDBCSingleton
public class JDBCSingleton{
private static JDBCSingleton jdbc;
private JDBCSingleton(){}
public static JDBCSingleton getInstance(){
if (jdbc==null){
jdbc=new JDBCSingleton();
}
return jdbc;
}
private static Connection getConnection() throws ClassNotFoundException, SQLException{
Connection con=null;
Class.forName("com.mysql.jdbc.Driver");
con= DriverManager.getConnection("jdbc:mysql://localhost:3306/ashwanirajput", "root", "ashwani");
return con;
}
public int insert(String name, String pass) throws SQLException{
Connection conn = null;
PreparedStatement ps = null;
int recordCounter=0;
try{
conn = this.getConnection();
ps = conn.prepareStatement("insert into userdata(uname,upassword)values(?,?)");
ps.setString(1, name);
ps.setString(2, pass);
recordCounter=ps.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
if(ps != null){
ps.close();
}
if(conn != null){
conn.close();
}
}
return recordCounter;
}
public void view(String name) throws SQLException{
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = this.getConnection();
ps = conn.prepareStatement("select * from userdata where uname=?");
ps.setString(1, name);
rs=ps.executeQuery();
while (rs.next()) {
System.out.println("Name= "+rs.getString(2)+"\t"+"Paasword= "+rs.getString(3));
}
}catch(Exception e){
System.out.println(e);
}finally{
if(rs!=null){
rs.close();
}
if (ps!=null){
ps.close();
}
if(conn!=null){
conn.close();
}
}
}
public int update(String name, String password) throws SQLException{
Connection conn = null;
PreparedStatement ps = null;
int recordCounter=0;
try{
conn = this.getConnection();
ps = conn.prepareStatement(" update userdata set upassword=? where uname='"+name+"' ");
ps.setString(1, password);
recordCounter=ps.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
if (ps!=null){
ps.close();
}
if(conn!=null){
conn.close();
}
}
return recordCounter;
}
public int delete(String userid) throws SQLException{
Connection conn = null;
PreparedStatement ps = null;
int recordCounter=0;
try{
conn = this.getConnection();
ps = conn.prepareStatement(" delete from userdata where uid='"+userid+"' ");
recordCounter=ps.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
if (ps!=null){
ps.close();
}
if(conn!=null){
conn.close();
}
}
return recordCounter;
}
}
Operation Class : JDBCSingletonDemo
public class JDBCSingletonDemo{
public static void main(String[] args) throws IOException {
JDBCSingleton jdbc= JDBCSingleton.getInstance();
String username = "userName";
String password = "userPassword";
jdbc.insert(username, password);
jdbc.view(username);
jdbc.delete(userid);
jdbc.update(username, password);
}
}
일반적인 Singleton 구현
- 인스턴스 생성에 대한 스레드 안전 O
- 직렬화 O
- 리플렉션 X
public class Singleton implements Serializable{
private volatitle Singleton INSTANCE;
private Singleton(){}
public Singleton getInstance(){
if(INSTANCE == null){
synchronized (Singleton.class){
if(INSTANCE == null){
INSTANCE = new Singleton();
}
}
}
return null;
}
protected Object readResolve(){
return getInstance();
}
}
간단한 Singleton 구현시 사용하는 코드
- 인스턴스 생성에 대한 스레드 안전 O
- 직렬화 O
- 리플렉션 O
public enum Singleton{
INSTANCE;
// ...
}
Enum class 사용에 대한 샘플코드 (우아한형제들)
public enum PayGroup{
CASH("현금", Arrays.asList("ACCOUNT_TRANSFER", "REMITTANCE", "ON_SITE_PAYMENT", "TOSS")),
CARD("카드", Arrays.asList("PAYCO", "CARD", "KAKAO_PAY", "BAEMIN_PAY")),
ETC("기타", Arrays.asList("POINT", "COUPON")),
EMPTY("없음", Collections.EMPTY_LIST);
private String title;
private List<String> payList;
PayGroup(String title, List<String> payList){
this.title = title;
this.payList = payList;
}
public static PayGroup findByPayCode(String code){
return Arrays.stream(PayGroup.vlues())
.filter(payGroup -> payGroup.hasPayCode(code))
.findAny().orElse(EMPTY);
}
public boolean hasPayCode(String code){
return payList.stream()
.anyMatch(pay -> pay.equals(code));
}
public String getTitle(){
return title;
}
}
참조 : http://woowabros.github.io
출처 : https://www.javatpoint.com/
know-one-by-one.tistory.com/35
'JAVA > Design Patterns' 카테고리의 다른 글
[자바 디자인 패턴] 구조패턴 - 어댑터 패턴 (0) | 2021.03.17 |
---|---|
[자바 디자인 패턴] 생성패턴 - 오브젝트풀 패턴 (0) | 2021.03.17 |
[자바 디자인 패턴] 생성패턴 - 빌더 패턴 (0) | 2021.03.16 |
[자바 디자인 패턴] 생성패턴 - 프로토타입 패턴 (0) | 2021.03.16 |
[자바 디자인 패턴] 생성패턴 - 추상 팩토리 패턴 (0) | 2021.03.16 |
[자바 디자인 패턴] 생성패턴 - 팩토리 메소드 패턴 (0) | 2021.03.16 |
[자바 디자인 패턴] 행동패턴 - 템플릿 패턴 (0) | 2021.03.16 |
[자바 디자인 패턴] 행동패턴 - 전략 패턴 (0) | 2021.03.15 |