빅데이터 Java 개발자 교육 - 14일차 [Singleton패턴]

Jun_Gyu·2023년 2월 26일
1
post-thumbnail

오늘은 Singleton패턴에 대해서 한번 알아보고 넘어 gaboza.






Singleton 패턴이란??

Singleton 패턴

출처

정의

클래스가 최초 한 번만 메모리를 할당하고(static) 해당 메모리에 인스턴스를 만들어 사용하는 패턴을 이야기한다. 즉, '하나'의 인스턴스만 생성하여 사용하는 디자인 패턴인 것이다.

생성자가 여러번 호출되더라도, 실제로 생성되는 객체는 하나이며, 최초로 생성된 이후에 호출된 생성자는 이미 생성한 객체를 반호나시키도록 만드는 것이다. (java에서는 생성자를 private으로 선언해 다른 곳에서 생성하지 못하도록 만들고, getInstance() 메소드를 통해 받아서 사용하도록 구현한다)


왜 쓰는가?

먼저, 객체를 생성할 때마다 메모리 영역을 할당받아야 한다. 하지만 한번의 new를 통해 객체를 생성한다면 메모리 낭비를 방지할 수 있다.

또한 싱글톤으로 구현한 인스턴스는 '전역'이므로, 다른 클래스의 인스턴스들이 데이터를 공유하는 것이 가능한 장점이 있다.


많이 사용되는 상황?

주로 공통된 객체를 여러개 생성해서 사용해야하는 상황

  • [데이터베이스에서 커넥션풀, 스레드풀, 캐시, 로그 기록 객체 등]

이론으로 Singleton 패턴에 대해 알아보았으니 이번에는 직접 코드를 참고해보도록 하자.

package day14;

import org.bson.Document;

import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;

import day8.Config;

// DB 접속 클래스
// 객체 1번 생성만 = > singleton패턴
public class DBconn {
	
	// 스스로의 객체를 만들기 위한 변수설정
	private static DBconn db = null;
	
	// 외부에서 생성자를 호출할 수 없음. private
	private DBconn() { // 생성자.
	}
	
	// 인스턴스 생성.
	public static DBconn getInstance() {
		db = new DBconn(); 
		return db;	
	}
	
	// 외부에서 접속하고자 하는 컬렉션 이름을 넘겨주면 DB에 접속한 후 컬렉션 연결 객체를 반환
	// 객체명. getCollection('members');
	public MongoCollection<Document> getCollection(String coll){
		try {
			return MongoClients.create(Config.URL)   // 접속과 동시에 값을 반환
					.getDatabase(Config.DBNAME)
					.getCollection(coll);
		} 
		catch (Exception e) {
			e.printStackTrace();
		return null;
		}
	}
}

위의 클래스는 DB 접속을 도와주도록 설정을 하였다.

다른 클래스에서 DB에 접속하고자 할 때 사용하려는 컬렉션의 명칭을 대입하면 들어가게끔 설정을 한 코드이다.

혹시라도 이해가 되지 않는다면 아래의 글을 참고하여 추가적인 예제를 알아보도록 하자.


자바 싱글톤 패턴(Singleton Pattern)



어쨋든 위의 코드를 이용해서 한번 실습을 진행해보았다.

지난시간에 미리 만들어뒀던 Board 컬렉션은 이용해보도록 하자.

package day14;

import java.util.List;

public interface BoardDB {

	// 게시판 글쓰기
	public int insertBoardOne(Board board);

	// 게시판 조회 (최신글순으로 10개씩, 페이지네이션)
	public List<Board> selectBoardList(int page);

	// 게시판 수정 (제목, 내용만 변경)
	public int updateBoardOne(Board board);

	// 게시판 1개 조회
	public Board selectBoardOne(int num);

	// 게시판 삭제
	public int deleteBoardOne(long num);

}
package day14;

import java.util.ArrayList;
import java.util.List;

import org.bson.Document;
import org.bson.conversions.Bson;

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.InsertOneResult;
import com.mongodb.client.result.UpdateResult;

import day8.Config;

public class BoardDBImpl implements BoardDB {
	
	MongoCollection<Document> sequence = null;
	MongoCollection<Document> boards = null;

	public BoardDBImpl() {
		
		this.boards = DBconn.getInstance().getCollection(Config.BOARDCOL);
		this.sequence = DBconn.getInstance().getCollection(Config.RESEQUENCECOL);
	}

	/*---------------------------------------------------------------------------------------------------*/
	// 게시판 글쓰기
	@Override
	public int insertBoardOne(day14.Board board) {
		try {
			Bson filter = Filters.eq("_id", "SEQ_BOARD_NO");
			Bson update = Updates.inc("idx", 1);
			Document doc = this.sequence.findOneAndUpdate(filter, update);

			Document doc1 = new Document();
			doc1.append("_id", doc.getLong("idx"));
			doc1.append("title", board.getTitle());
			doc1.append("writer", board.getWriter());
			doc1.append("content", board.getContent());
			doc1.append("hit", board.getHit());
			doc1.append("reg date", board.getRegdate());

			InsertOneResult result = this.boards.insertOne(doc1);
			if (result.getInsertedId().asInt64().getValue() == doc1.getLong("_id")) {
				return 1;
			}
			return 0;
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
		
	}

	/*---------------------------------------------------------------------------------------------------*/
	// 게시판 조회 (최신글순으로 10개씩, 페이지네이션)
	@Override
	public List<day14.Board> selectBoardList(int page) {
		List<day14.Board> list = new ArrayList<>();
		try {
			Bson sort = Filters.eq("_id", -1);
			FindIterable<Document> docs = this.boards.find().sort(sort).skip(10 * (page - 1)).limit(10);
			for (Document doc : docs) {
				day14.Board board = new day14.Board();
				board.setNo(doc.getLong("_id"));
				board.setTitle(doc.getString("title"));
				board.setWriter(doc.getString("writer"));
				board.setContent(doc.getString("content"));
				board.setHit(doc.getLong("hit"));
				board.setRegdate(doc.getDate("reg date"));

				list.add(board);
			}
			return list;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

	}

	/*---------------------------------------------------------------------------------------------------*/

	// 게시판 수정 (제목, 내용만 변경)
	@Override
	public int updateBoardOne(day14.Board board) {
		try {
			Bson filter = Filters.eq("_id", board.getNo());

			Bson up1 = Updates.set("title", board.getTitle());
			Bson up2 = Updates.set("content", board.getContent());

			Bson update = Updates.combine(up1, up2);
			UpdateResult result = this.boards.updateOne(filter, update);
			if (result.getModifiedCount() == 1) {
				return 1;
			}
			return 0;

		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}

	/*---------------------------------------------------------------------------------------------------*/

	// 게시판 1개 조회
	@Override
	public day14.Board selectBoardOne(int num) {
		day14.Board board = new day14.Board();
		try {
			Bson filter = Filters.eq("_id", num);
			Document doc = this.boards.find().filter(filter).first();
			board.setNo(doc.getLong("_id"));
			board.setTitle(doc.getString("title"));
			board.setWriter(doc.getString("writer"));
			board.setContent(doc.getString("content"));
			board.setHit(doc.getLong("hit"));
			board.setRegdate(doc.getDate("reg date"));

			return board;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/*---------------------------------------------------------------------------------------------------*/

	// 게시판 삭제
	@Override
	public int deleteBoardOne(long num) {
		try {
			Bson filter = Filters.eq("_id", num);
			DeleteResult result = this.boards.deleteOne(filter);
			System.out.println(result.toString());
			if (result.getDeletedCount() == 1L) {
				return 1;
			}
			return 0;
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}

	}
}
package day14;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {

	public static void main(String[] args) {
		BoardDB bDB = new BoardDBImpl();

		/*-----------------게시판 글쓰기----------------------------------*/
		day14.Board b1 = new day14.Board();
		
		b1.setTitle("16일 실습 n차");
		b1.setWriter("junkue30");
		b1.setContent("오늘 하루는 실습을 진행했어요~");
		b1.setHit(345L);
		b1.setRegdate(new Date());
		
		int ret1 = bDB.insertBoardOne(b1);
		System.out.println(ret1);
		
		/*-----------------게시판조회(최신글순으로 10개씩, 페이지네이션)----------------------------------*/
		int i2 = 1;
		
		List<day14.Board> list2 = bDB.selectBoardList(i2);
		System.out.println(list2);
		
		/*-----------------게시판수정(제목, 내용만 변경)----------------------------------*/
		day14.Board b3 = new day14.Board();
		
		b3.setNo(12);
		b3.setTitle("제목 바꾸기");
		b3.setContent("짠");
	
		int ret3 = bDB.updateBoardOne(b3);
		System.out.println(ret3);
		
		/*-----------------게시판 1개조회----------------------------------*/
        int i4 = 13;
		day14.Board b4 = bDB.selectBoardOne(i4);
		System.out.println(b4);
		
		/*-----------------게시판 삭제----------------------------------*/
		long l = 15;
		
		int ret5 = bDB.deleteBoardOne(l);
		System.out.println(ret5);
		
		/*------------------------------------------------------------*/
           }
}
profile
시작은 미약하지만, 그 끝은 창대하리라

0개의 댓글