자바로 PC방 프로그램만들기

5초식 리플렉션을 이용한 리팩토링 완성ㅎ

ㅎㅎ 이것도 곧 올리겠습니다.

리플렉션을 어떻게 설명할까하다가.. 지쳐가지고 중간에 업로딩을 안했었거든요. ㅠㅠ 
제작에 꼭 필요한 부분은 아니지만, 리팩토링하다가 재밌어서 올려봅니다 ㅎㅎ\

3일내로 제작해서 올리겠습니다 (_ _)


리플렉션이란?


리플렉션이란,.. (저도 정확한 개념은 잘 모르고 그냥 말씀드립니다). 
하나의 클래스에서 다른 클래스의 정보를 알아낼 수 있는 개념입니다.
다른 클래스의 지도를 볼 수가 있는 것이죠. 또한 그 클래스로 만든 객체까지 주어준다면, 
그 객체들의 값을 바꿀 수도 있는 것입니다.

자세한 것은 일단 영상 보도록 하시겠습니다.

코드로 설명드리자면, 

import java.lang.reflect.Field;

public class RefUser {
    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
		//지도(클래스) 선언
		Class<?> clazz = RefObject.class;
		//지도에서 필드들을 받아와서 출력
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) 
			System.out.println(field.getName());
		
		//필드를 받아옴. clazz에서 getDeclaredField("필드명")해도 됨.
		Field field = fields[0];		
		//객체를 만들어서 객체값 변경
		RefObject refObject = new RefObject();
		field.setInt(refObject, 3);
		System.out.println("넘버 아이디는 :"+refObject.getNumId());
	}
}

여기서 참조되는 클래스는 뭐... 간단합니다;;

public class RefObject {
    private int numId;
	public int getNumId() {return numId;}
	public void setNumId(int numId) {this.numId = numId;}	
}

클래스와, 객체를 가지고서 clazz.getDeclaredField("필드명") 혹은 getDeclared~ 로 필드들을 받아오시는 것을 보실 수가 있습니다.

자, 이제 리팩토링을 적용해보도록 하겠습니다.

 

리플렉션을 이용한 리팩토링적용

여기서는 반복된 부분. 이부분들을 리플렉션을 이용하여서 이름값만을 가지고 Settings 클래스에서 값을 가져와서 불러들여 적용해보는 것을 해봅니다. 영상을 보도록 하겠습니다. 

setPanel(layeredPane).setBounds(Setting.bRectangle);
setPanel(backGround).setBounds(Setting.bpanRectangle);
setPanel(imgClock).setBounds(Setting.imgClock);
setPanel(clockMessage).setBounds(Setting.clockMessage);
setPanel(myStarPanel).setBounds(Setting.bpanRectangle);

ManageView 는 다음과 같습니다. (깃허브에는 더 정리된 것이 올라갑니다) 
 

package view;

import java.awt.Component;
import java.awt.Rectangle;
import java.lang.reflect.Field;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

import view.panel.ClockMessage;
import view.panel.ImgClock;
import view.panel.MyStarPanel;
import view.panel.PanImgload;
import asset.Setting;

@SuppressWarnings("serial")
public class ManageView extends JFrame {

    private JLayeredPane layeredPane = new JLayeredPane();
	//JPanels
	private JPanel backGround = new PanImgload("img/mainHud_back.png");
	private ImgClock imgClock = new ImgClock();
	private ClockMessage clockMessage = new ClockMessage();
	private MyStarPanel myStarPanel = new MyStarPanel();
	
	public ManageView() {
		//Configure this Frame
		setLayout(null);
		setVisible(true);
		setTitle("ManageView");
		setSize(Setting.bDimen);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLocation(Setting.locationX, Setting.locationY);
		
		//LayerdPanel and Component Setting , Finally add To this Frame
		/*
		setPanel(layeredPane).setBounds(Setting.bRectangle);
		setPanel(backGround).setBounds(Setting.bpanRectangle);
		setPanel(imgClock).setBounds(Setting.imgClock);
		setPanel(clockMessage).setBounds(Setting.clockMessage);
		setPanel(myStarPanel).setBounds(Setting.bpanRectangle);
		*/
		add(setJLayered(backGround, myStarPanel, imgClock, clockMessage));
		
		//Action Events
		//threadStart(imgClock, clockMessage, myStarPanel); 
	}
	
	public void setRectangles(Class<?> clazz, Object instance, Class<?> targetClass, Object target) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException{
		Object tempObject = null;
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			System.out.println("필드 :" + field.getName());
			System.out.println("세팅클래스에서 받아온 값은"+targetClass.getDeclaredField(field.getName()).get(target));
			tempObject = field.get(instance);
			
			if(tempObject instanceof JComponent){
				Rectangle rectangle = (Rectangle) targetClass.getDeclaredField(field.getName()).get(target);
				((JComponent) tempObject).setBounds(rectangle);
				((JComponent) tempObject).setOpaque(false);
				((JComponent) tempObject).setLayout(null);
			}
			if(tempObject instanceof Runnable){
				new Thread((Runnable) tempObject).start();
			}
		}
	}
	

	public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
		ManageView manageView = new ManageView();
		manageView.setRectangles(ManageView.class, manageView, Setting.class, Setting.getInstance());
	}

	// Setting inner Methods
	private JComponent setPanel(JComponent panel) {
		panel.setLayout(null);
		panel.setOpaque(false);
		return panel;
	}
	private JLayeredPane setJLayered(Component...components) {
		int i = 0;
		for (Component component : components)
			layeredPane.add(component, new Integer(i++));
		return layeredPane;
	}
	private void threadStart(Runnable...target) {
		for (Runnable runnable : target)
			new Thread(runnable).start();
	}

	// TODO 계속 들어감

}

Settings 에는 다음소스를 넣어주세요.

// ManageView 에 들어갈 것들
    public static Rectangle layeredPane = bRectangle;
	public static Rectangle backGround = bRectangle;
	public static Rectangle myStarPanel = bRectangle;

	// singleTone
	private static Setting instance = new Setting();

	public static Setting getInstance() {
		return instance;
	}

	private Setting() {
	}

zip 소스코드는 여기서 https://github.com/arahansa/pcbang/archive/2.zip 다운받으실 수 있습니다. 

댓글

댓글 본문
  1. 아라한사
    2014년의 마지막 날이네요. 새해 복 많이 받으세요.
  2. 아라한사
    먼저 관심 감사드리구요.

    MYSQL 기초는 이고잉님이 강의를 잘 만드셨지 않을까요?
    ex ) http://opentutorials.org......467
    database 를 다루는 방법에는 여러가지가 있는데,

    자바의 객체지향 메소드처럼, 쉽게 데이터베이스를 다루는 방법들도 존재합니다. ORM 이라고 불리우구요.
    예를 들어서 일정 객체를 저장할때는 insert into 테이블 이름 values (' ' ) 이런 것들을 일일이 적고 db접속하고 sql 문을 execute 하는데 비해서

    ORM 에서는 ORM의클래스.SAVE(객체명) 이렇게 메서드로 객체를 전달만 해줘도 됩니다.
    또 클래스에 데이터베이스 매핑 정보를 적어두면 일일이 create table ( 블라블라 ) 이런 것을 안해도 됩니다.

    ORM에 대한 강좌로 http://opentutorials.org......281 를 적어두었습니다.
    아직 미완이지만 달려보겠습니다. 감사합니다.
    대화보기
    • 이분최소프로그래머
      그리고.. mysql 다루기가 힘들어서 그런데 그쪽 강좌도 부탁드려도 될까 부탁드려봅니당..

      대충 기초만이라도 좋습니다!
    • 이분최소프로그래머
      강좌 너무 감사드립니다 꾸준히 올려주시면.. 감사하겠습니다

      아마 댓글 없이 그냥 보고가는 사람이 훨씬 많을테니 그점 염두하셔서 실망하지마시고

      열시미 강좌해주시면 감사하겠습니다
    버전 관리
    아라한사
    현재 버전
    선택 버전
    graphittie 자세히 보기