[211119] 교육 19일차

oxllz·2022년 1월 31일
0

교육

목록 보기
15/41

Frame

import java.awt.Frame;
//
public class Test164 {
	public static void main( String[] args ) {
		Frame f = new Frame();
		f.setSize( 600, 360 );
		f.setVisible( true );
	}
}
class XFrame extends Frame {
	public XFrame() {
		setSize( 600, 360 );
		setVisible( true );
	}
}
//
public class Test165 {
	public static void main( String[] args ) {
		new XFrame();
	}
}


상속과 생성자 함수로 같은 동작 구현


class XCanvas extends Canvas {
	public XCanvas() {
		setSize( 500, 200 );
		setBackground( Color.YELLOW );
	}
	//
	public void paint( Graphics g ) {
		Graphics2D g2 = (Graphics2D)g;
		//
		g2.setColor( Color.BLACK );
		g2.drawRect( 10, 10, 50, 50 );
		// 나중에 그린게 이전에 그린거 덮어버린다 ... 
		g2.setColor( Color.GREEN );
		g2.fillRect( 40, 40, 100, 100 );
	}
}
//
class XFrame extends Frame {
	public XFrame() {
		Panel p1 = new Panel();
		p1.add( new XCanvas() );
		//
		Panel p2 = new Panel();
		p2.add( new TextField( 24 ) );
		p2.add( new Button("Click") );
		//
		add( p1 , BorderLayout.CENTER );
		add( p2 , BorderLayout.SOUTH );
		//
		setSize( 600, 360 );
		setVisible( true );
	}
}
//
public class Test166 {
	public static void main( String[] args ) {
		new XFrame();
	}
}


Canvas : 선을 긋고 그림을 그리고 이미지를 보여주는 등의 역할을 수행하는 클래스.


Observer Pattern

// 유연한 교체를 위한 코드 
interface IFuelObs {
	public void onFuelChange( int fuel );
}
//
class Car {
	// 유연한 교체를 위한 코드 시작
	private IFuelObs obs = null;
	public void setFuelObs( IFuelObs o ) { 
		obs = o; 
	}
	// 유연한 교체를 위한 코드 끝
	private int fuel = 3;
	public void drive() {
		fuel--;
		// 유연한 교체를 위한 코드 
		if( obs != null ) {
			obs.onFuelChange( fuel );
		}
		// 유연한 교체를 위한 코드 
		System.out.println("연료 1L 소모");
	}
}
// 연료의 변화가 생기면 잔량을 찍어주는 클래스
class FuelGauge implements IFuelObs {
	public void onFuelChange( int fuel ) {
		System.out.println(">>" + fuel );
	}
}
//
public class Test168 {
	public static void main( String[] args ) {
		Car car = new Car();
		// car.setFuelObs( new FuelGauge() );
		car.setFuelObs( new FuelBomb() );
		//
		car.drive();
		car.drive();
		//
		car.setFuelObs( null );
		car.drive();
	}
}
//
class FuelBomb implements IFuelObs {
	public void onFuelChange( int fuel ) { 
		if( fuel == 1 ) {
			System.out.println("폭탄터짐");
			System.exit(0);
		}
	}
}

연료의 상황을 체크하는 코드를 넣되 유연하게 교체가능하도록 만들 수 없을까?
연료계 역할의 클래스를 등록하면 Car 와 연동되다가 필요 없을 경우 빼거나 교체 할 수 있다. ( FuelGauge, FuelBomb )

Car 와 FuelGauge 는 별도의 클래스로 만들었다.
둘 다 IFuelObs 를 이용하는데

Car의 상태가 변경되는 것을 Gauge 에 통보하고 있다.
이러한 설계 기법을 관찰자 패턴 ( Observer Pattern ) 이라고 한다.

  • 관찰대상의 변화를 관찰자에게 통보하는데 이 둘은 별도로 분리되고 교체가능하게 연결된다.
  • 관찰자는 교체가능하고 , 관찰 대상의 상황에 맞는 코드는 쉽게 변경될 수 있다

FuelGauge -> FuelBomb 관찰자를 교체해도 잘 동작한다!

class XCanvas extends Canvas {
	public XCanvas() {
		setSize( 500, 200 );
		setBackground( Color.YELLOW );
	}
}
//
class XFrame extends Frame {
	public XFrame() {
		Panel p1 = new Panel();
		p1.add( new XCanvas() );
		//
		Button btn = new Button("Click");
		btn.addActionListener( new Apple() );
		//
		Panel p2 = new Panel();
		p2.add( new TextField( 24 ) );
		p2.add( btn );
		//
		add( p1 , BorderLayout.CENTER );
		add( p2 , BorderLayout.SOUTH );
		//
		setSize( 600, 360 );
		setVisible( true );
	}
}
//
class Apple implements ActionListener {
	public void actionPerformed(ActionEvent e) {
		System.out.println("Apple::actionPerformed");
	}
}
//
public class Test169 {
	public static void main( String[] args ) {
		new XFrame();
	}
}

Button : 관찰 대상
Apple : 관찰자( implements ActionListener )
이 둘 사이는 ActionListener 라는 인터페이스로 느슨하게 연결되어 있고 Button 의 Action 상황이 벌어지면 addActionListener 로 등록된 관찰자가 오버라이딩하는 actionPerformed 가 호출되게 되는 설계이다.

0개의 댓글