자바 코드 재 활용 기능 및 컨 텍스트 재 활용
두 가지 유형의 재 활용 코드 가 있 습 니 다.저 는 재 활용 유형 이 라 고 부 릅 니 다.
두 번 째 유형 은 상하 문 중용,즉 서로 다른 기능 이나 조작 코드 가 같은 상하 문 사이 에서 같은 상하 문 을 중용 코드 로 봉 하 는 것 이다.반전 을 통제 하 는 데 점점 인 기 를 끌 고 있 지만 흔 치 않다.그리고 상하 문 중용 은 명확 하 게 묘사 되 지 않 았 기 때문에 기능 중용 처럼 체계적으로 사용 되 지 않 았 다.나 는 네가 이 문장 을 다 본 후에 변화 가 있 기 를 바란다.
기능 재 활용
기능 재 활용 은 가장 흔히 볼 수 있 는 재 활용 유형 이다.그것 은 어떤 조작 명령 을 실행 하 는 재 활용 이다.다음 두 가지 방법 은 모두 데이터베이스 에서 데 이 터 를 읽 는 것 입 니 다.
public List readAllUsers(){
Connection connection = null;
String sql = "select * from users";
List users = new ArrayList();
try{
connection = openConnection();
PreparedStatement statement = connection.prepareStatement(sql);
ResultSet result = statement.executeQuery();
while(result.next()){
//
User user = new User();
user.setName (result.getString("name"));
user.setEmail(result.getString("email"));
users.add(user);
// END
}
result.close();
statement.close();
return users;
}
catch(SQLException e){
//ignore for now
}
finally {
//ignore for now
}
}
public List readUsersOfStatus(String status){
Connection connection = null;
String sql = "select * from users where status = ?";
List users = new ArrayList();
try{
connection = openConnection();
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, status);
ResultSet result = statement.executeQuery();
while(result.next()){
//
User user = new User();
user.setName (result.getString("name"));
user.setEmail(result.getString("email"));
users.add(user);
// END
}
result.close();
statement.close();
return users;
}
catch(SQLException e){
//ignore for now
}
finally {
//ignore for now
}
}
경험 이 있 는 개발 자 들 에 게 는 재 활용 가능 한 코드 를 곧 발견 할 수 있 을 것 이다.위의 코드 에서'재 활용 코드'를 설명 하 는 곳 은 같 기 때문에 재 활용 할 수 있 습 니 다.이것 은 사용자 기록 을 사용자 인 스 턴 스 에 읽 는 작업 입 니 다.이 줄 코드 를 자신 들 의 방법 에 봉인 할 수 있 습 니 다.예 를 들 어:
// readUser
private User readUser(ResultSet result) throws SQLException {
User user = new User();
user.setName (result.getString("name"));
user.setEmail(result.getString("email"));
users.add(user);
return user;
}
현재 상기 두 가지 방법 에서 readUser()방법 을 호출 합 니 다.(아래 예제 에 서 는 첫 번 째 방법 만 표시 합 니 다)
public List readAllUsers(){
Connection connection = null;
String sql = "select * from users";
List users = new ArrayList();
try{
connection = openConnection();
PreparedStatement statement = connection.prepareStatement(sql);
ResultSet result = statement.executeQuery();
while(result.next()){
users.add(readUser(result))
}
result.close();
statement.close();
return users;
}
catch(SQLException e){
//ignore for now
}
finally {
//ignore for now
}
}
readUser()방법 도 자신의 클래스 에서 수정자 private 로 숨 길 수 있 습 니 다.이상 은 기능 재 활용 에 관 한 내용 입 니 다.기능 재 활용 은 특정한 조작 을 수행 하 는 명령 을 방법 이나 클래스 를 통 해 재 활용 하 는 목적 을 달성 하 는 것 이다.
매개 변수 화 조작
때때로,당신 은 한 조 의 조작 을 다시 사용 하 기 를 원 하지만,이 조작 들 은 사용 하 는 어느 곳 에서 도 완전히 같 지 않다.예 를 들 어 readAllUsers()와 readUsers OfStatus()방법 은 모두 연결 을 열 고 문 구 를 준비 하여 실행 하고 결과 집합 에 반복 적 으로 접근 하 는 것 이다.유일한 차이 점 은 readUsers OfStatus()가 Prepared Statement 에 인 자 를 설정 해 야 한 다 는 것 이다.우 리 는 모든 조작 을 readUserList()방법 으로 밀봉 할 수 있다.다음 과 같다.
private List readUserList(String sql, String[] parameters){
Connection connection = null;
List users = new ArrayList();
try{
connection = openConnection();
PreparedStatement statement = connection.prepareStatement(sql);
for (int i=0; i < parameters.length; i++){
statement.setString(i, parameters[i]);
}
ResultSet result = statement.executeQuery();
while(result.next()){
users.add(readUser(result))
}
result.close();
statement.close();
return users;
}
catch(SQLException e){
//ignore for now
}
finally {
//ignore for now
}
}
현재 우 리 는readAllUsers()
와readUsersOfStatus()
에서readUserList(...)
방법 을 호출 하고 서로 다른 조작 매개 변 수 를 지정 합 니 다.
public List readAllUsers(){
return readUserList("select * from users", new String[]{});
}
public List readUsersWithStatus(String status){
return readUserList("select * from users", new String[]{status});
}
나 는 네가 다른 더 좋 은 방법 을 찾 아서 중용 기능 을 실현 하고 그들의 매개 변 수 를 더욱 잘 사용 할 수 있 을 것 이 라 고 믿는다.문맥 재 활용
상하 문장의 중용 과 기능 중용 은 약간 다르다.상하 문 중용 은 일련의 지령 의 중용 으로 각종 서로 다른 조작 은 항상 이 지령 들 사이 에서 진행 된다.다양한 행동 전과 뒤의 문 구 를 반복 적 으로 사용 한 다 는 얘 기다.따라서 상하 문 중용 은 통상 적 으로 컨트롤 스타일 류 의 반전 을 초래 할 수 있다.상하 문 중용 은 이상 처리,연결 과 사무 생명주기 관리,흐름 교체 와 닫 기,그리고 많은 일반적인 상하 문 조작 에 매우 효과 적 인 방법 이다.
여기 에는 두 가지 방법 이 있 는데 모두 InputStream 으로 만 든 것 이다.
public void printStream(InputStream inputStream) throws IOException {
if(inputStream == null) return;
IOException exception = null;
try{
int character = inputStream.read();
while(character != -1){
System.out.print((char) character); //
character = inputStream.read();
}
}
finally {
try{
inputStream.close();
}
catch (IOException e){
if(exception == null) throw e;
}
}
}
public String readStream(InputStream inputStream) throws IOException {
StringBuffer buffer = new StringBuffer(); //
if(inputStream == null) return;
IOException exception = null;
try{
int character = inputStream.read();
while(character != -1){
buffer.append((char) character); //
character = inputStream.read();
}
return buffer.toString(); //
}
finally {
try{
inputStream.close();
}
catch (IOException e){
if(exception == null) throw e;
}
}
}
두 가지 방법 과 흐름 의 조작 은 다르다.그러나 이 를 둘 러 싼 문맥 은 같다.컨 텍스트 코드 가 교체 되 고 InputStream 을 닫 습 니 다.상기 코드 에 서 는 주석 표 시 를 사용 하 는 것 을 제외 하고 모두 문맥 코드 입 니 다.위 에서 보 듯 이 문맥 은 이상 처리 와 관련 되 고 교체 후 흐름 을 정확하게 닫 도록 보장 합 니 다.이러한 오류 처리 와 자원 방출 코드 를 한 번 또 한 번 작성 하 는 것 은 번 거 롭 고 실수 하기 쉽다.오류 처리 와 정확 한 연결 처 리 는 JDBC 업무 에서 더욱 복잡 하 다.코드 를 한 번 만 들 고 어디서 든 반복 해서 사용 하 는 것 이 쉬 울 것 입 니 다.
다행히도 상하 문 을 봉인 하 는 방법 은 간단 하 다.컨 텍스트 클래스 를 만 들 고 공공 컨 텍스트 를 넣 습 니 다.상하 문 사용 에서 서로 다른 조작 지령 을 조작 인터페이스 에 추상 화한 다음 에 모든 조작 을 이 조작 인 터 페 이 스 를 실현 하 는 클래스 에 봉 하여(여기 서 조작 클래스 라 고 부른다)이 조작 클래스 의 실례 를 상하 문 에 삽입 하면 된다.조작 류 의 인 스 턴 스 를 매개 변수 로 문맥 대상 에 전달 하 는 구조 함수 나 조작 류 의 인 스 턴 스 를 매개 변수 로 문맥 에 전달 하 는 구체 적 인 집행 방법 으로 완성 할 수 있다.
위 예제 들 을 문맥 과 조작 인터페이스 로 나 누 는 방법 을 보 여 준다.StreamProcessor(조작 인터페이스)를 매개 변수 로 StreamProcessor Context 에 전달 하 는 processStream()방법.
//
public interface StreamProcessor {
public void process(int input);
}
//
public class StreamProcessorContext{
// StreamProcessor
public void processStream(InputStream inputStream, StreamProcessor processor) throws IOException {
if(inputStream == null) return;
IOException exception = null;
try{
int character = inputStream.read();
while(character != -1){
processor.process(character);
character = inputStream.read();
}
}
finally {
try{
inputStream.close();
}
catch (IOException e){
if(exception == null) throw e;
throw exception;
}
}
}
}
다음 예제 와 같이 StreamProcessor Context 류 를 사용 하여 스 트림 내용 을 출력 할 수 있 습 니 다.
FileInputStream inputStream = new FileInputStream("myFile");
// StreamProcessor
new StreamProcessorContext()
.processStream(inputStream, new StreamProcessor(){
public void process(int input){
System.out.print((char) input);
}
});
또는 아래 와 같이 입력 흐름 내용 을 읽 고 문자 시퀀스 에 추가 합 니 다.
public class StreamToStringReader implements StreamProcessor{
private StringBuffer buffer = new StringBuffer();
public StringBuffer getBuffer(){
return this.buffer;
}
public void process(int input){
this.buffer.append((char) input);
}
}
FileInputStream inputStream = new FileInputStream("myFile");
StreamToStringReader reader = new StreamToStringReader();
new StreamProcessorContext().processStream(inputStream, reader);
// do something with input from stream.
reader.getBuffer();
보시 다시 피 서로 다른 StreamProcessor 인 터 페 이 스 를 삽입 하여 대류 작업 을 수행 합 니 다.StreamProcessor Context 가 완전히 실현 되면 닫 히 지 않 은 흐름 에 대한 고민 은 영원히 없 을 것 입 니 다.상하 문장의 중용 은 매우 강해 서 흐름 처리 이외 의 많은 다른 환경 에서 사용 할 수 있다.하나의 뚜렷 한 용례 는 데이터베이스 연결 과 사 무 를 정확하게 처리 하 는 것 이다
open - process - commit()/rollback() - close()
.다른 용례 는 NIO 채널 처리 와 임계 구역 의 스 레 드 동기 화lock() - access shared resource - unlock()
이다.또한 API 의 검사 이상 을 검사 하지 않 은 이상 으로 변환 할 수 있 습 니 다.자신의 항목 에서 문맥 에 맞 는 코드 를 찾 을 때 다음 작업 모드 를 찾 으 십시오.
문맥 을 템 플 릿 으로 하 는 방법
가끔 은 문맥 에 여러 개의 플러그 인 점 이 있 기 를 바 랄 때 가 있 습 니 다.문맥 이 많은 작은 절차 로 구성 되 고 문맥 의 모든 절 차 를 사용자 정의 할 수 있 기 를 원한 다 면 문맥 을 템 플 릿 방법 으로 구현 할 수 있 습 니 다.템 플 릿 방법 은 GOF 디자인 모델 의 일종 이다.기본적으로 템 플 릿 방법 은 알고리즘 이나 협 의 를 일련의 절차 로 나눈다.하나의 템 플 릿 방법 은 보통 하나의 기본 클래스 로 이 루어 지고 알고리즘 이나 프로 토 콜 의 모든 단계 에 하나의 방법 을 제공 합 니 다.모든 절 차 를 사용자 정의 하려 면 확장 템 플 릿 방법 기본 클래스 를 만 들 고 사용자 정의 절 차 를 다시 쓰 는 방법 이 필요 합 니 다.
아래 의 예 는 템 플 릿 방법 으로 이 루어 진 JdbcContext 입 니 다.하위 클래스 는 사용자 정의 행동 을 제공 하기 위해 연결 의 열 림 과 닫 기 를 다시 쓸 수 있 습 니 다.추상 적 이기 때문에 프로 세 스 레코드(ResultSet result)방법 을 처음부터 끝까지 다시 써 야 합 니 다.이 방법 은 상하 문 에 속 하지 않 는 동작 을 제공 합 니 다.JdbcContext 를 사용 하 는 상황 에 따라 동작 이 다 릅 니 다.이 예 는 완벽 한 JdbcContext 가 아니다.이것 은 상하 문 을 실현 할 때 템 플 릿 을 어떻게 사용 하 는 지 보 여 주 는 데 만 사 용 됩 니 다.
public abstract class JdbcContext {
DataSource dataSource = null;
// DataSource
public JdbcContext() {
}
public JdbcContext(DataSource dataSource){
this.dataSource = dataSource;
}
protected Connection openConnection() throws SQLException{
return dataSource.getConnection();
}
protected void closeConnection(Connection connection) throws SQLException{
connection.close();
}
// processRecord(ResultSet result)
protected abstract processRecord(ResultSet result) throws SQLException ;
public void execute(String sql, Object[] parameters) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet result = null;
try{
connection = openConnection();
statement = connection.prepareStatement(sql);
for (int i=0; i < parameters.length; i++){
statement.setObject(i, parameters[i]);
}
result = statement.executeQuery();
while(result.next()){
processRecord(result);
}
}
finally {
if(result != null){
try{
result.close();
}
catch(SQLException e) {
/* ignore */
}
}
if(statement != null){
try{
statement.close();
}
catch(SQLException e) {
/* ignore */
}
}
if(connection != null){
closeConnection(connection);
}
}
}
}
사용자 목록 의 하위 클래스 를 읽 기 위해 jdbc Context 를 확장 합 니 다.
public class ReadUsers extends JdbcContext{
List users = new ArrayList();
public ReadUsers(DataSource dataSource){
super(dataSource);
}
public List getUsers() {
return this.users;
}
protected void processRecord(ResultSet result){
User user = new User();
user.setName (result.getString("name"));
user.setEmail(result.getString("email"));
users.add(user);
}
}
ReadUsers 클래스 를 어떻게 사용 하 는 지:
ReadUsers readUsers = new ReadUsers(dataSource);
readUsers.execute("select * from users", new Object[0]);
List users = readUsers.getUsers();
ReadUsers 클래스 가 연결 풀 에서 연결 을 가 져 오고 사용 한 후에 이 연결 풀 로 돌려 보 내야 한다 면 재 작성openConnection()
과closeConnection(Connection connection)
방법 으로 연결 을 삽입 할 수 있 습 니 다.방법 을 통 해 조작 코드 를 다시 쓰 는 방법 에 주의 하 세 요.JdbcContext 의 하위 클래스 재 작성 processRecord 방법 은 특별한 기록 처 리 를 제공 합 니 다.StreamContext 예제 에서 조작 코드 는 단독 대상 에 봉 하여 방법 적 매개 변수 로 제공 합 니 다.조작 인터페이스 StreamProcessor 의 대상 을 매개 변수 로 StreamContext 류
processStream(...)
에 전달 하 는 방법 을 실현 합 니 다.상하 문 을 실시 할 때 너 는 이 두 가지 기술 을 사용 할 수 있다.JdbcContext 류 는 조작 인 터 페 이 스 를 실현 하 는 ConnectionOpener 와 ConnectionCloser 대상 을 매개 변수 로 execute 방법 이나 구조 함수 의 매개 변수 로 전달 할 수 있다.개인 적 으로 저 는 단독 조작 대상 과 조작 인 터 페 이 스 를 사용 하 는 것 을 더 좋아 합 니 다.그 이 유 는 두 가지 가 있 습 니 다.우선,조작 코드 가 단원 테스트 를 단독으로 진행 하기 쉽 도록 한다.그 다음 에 조작 코드 를 여러 문맥 에서 다시 사용 할 수 있 게 한다.물론 조작 코드 도 코드 의 여러 위치 에서 사용 할 수 있 지만 이것 은 장점 일 뿐이다.여기 서 우 리 는 문맥 을 다시 사용 하려 는 것 이지 다시 사용 하려 는 것 이 아니다.
종결 어
지금 너 는 이미 두 가지 다른 코드 를 다시 사용 하 는 방법 을 보 았 다.전형 적 인 기능 재 활용 과 흔 하지 않 은 문맥 재 활용.문맥 의 재 활용 이 기능 재 활용 처럼 보편화 되 기 를 바 랍 니 다.문맥 재 활용 은 API 의 바 텀 디 테 일(예 를 들 어 JDBC,IO 또는 NIO API 등)에서 코드 를 추상 화 할 수 있 는 매우 유용 한 방법 이다.특히 API 에 관리 해 야 할 자원(열 고 닫 기,가 져 오고 되 돌려 주 는 등)이 포함 되 어 있다 면.
persistence/ORM API,Mr.Persister 는 상하 문 재사 용 을 이용 하여 자동 연결 과 사무 생명주기 관 리 를 실현 한다.이렇게 하면 사용 자 는 연결 을 정확하게 열거 나 닫 거나 제출 하거나 스크롤 백 하 는 것 을 영원히 걱정 하지 않 아 도 된다.Mr.Persister 는 사용자 가 작업 을 삽입 할 수 있 는 컨 텍스트 를 제공 합 니 다.이 상하 문 들 은 열 고 닫 고 제출 하고 스크롤 백 하 는 것 을 책임 집 니 다.
유행 하 는 Spring 프레임 워 크 는 대량의 상하 문 중용 을 포함한다.예 를 들 어 Springs JDBC 추상.Spring 개발 자 들 은 컨 텍스트 를'반전 제어'로 재 활용 했다.이것 은 Spring 프레임 워 크 가 사용 하 는 유일한 반전 제어 유형 이 아니다.Spring 의 핵심 특성 은 bean 공장 이나'응용 프로그램 컨 텍스트'를 주입 하 는 것 입 니 다.의존 주입 은 또 다른 제어 반전 이다.
위 에서 말 한 것 은 소 편 이 소개 한 자바 코드 재 활용 기능 과 문맥 재 활용 입 니 다.여러분 께 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.