System Patterns - Session

Similar documents
Microsoft PowerPoint - 06-Chapter09-Event.ppt

<C0DAB7E120C7D5BABB2E687770>

오버라이딩 (Overriding)

Microsoft PowerPoint - 04-UDP Programming.ppt

PowerPoint Presentation

Cluster management software

PowerPoint 프레젠테이션

자바GUI실전프로그래밍2_장대원.PDF

<4D F736F F F696E74202D20C1A63139C0E520B9E8C4A120B0FCB8AEC0DA28B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

Chap12

Microsoft PowerPoint - ÀÚ¹Ù08Àå-1.ppt

rmi_박준용_final.PDF

<4D F736F F F696E74202D20C1A63233C0E520B1D7B7A1C7C820C7C1B7CEB1D7B7A1B9D628B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

PowerPoint Presentation

05-class.key

01-OOPConcepts(2).PDF

Microsoft PowerPoint - 14주차 강의자료

gnu-lee-oop-kor-lec10-1-chap10

제8장 자바 GUI 프로그래밍 II

ch09

07 자바의 다양한 클래스.key

<4D F736F F F696E74202D20C1A63230C0E520BDBAC0AE20C4C4C6F7B3CDC6AE203128B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

<4D F736F F F696E74202D20C1A63138C0E520C0CCBAA5C6AE20C3B3B8AE28B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

JAVA PROGRAMMING 실습 08.다형성

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

12-file.key

gnu-lee-oop-kor-lec06-3-chap7

5장.key

10장.key

JMF3_심빈구.PDF

09-interface.key

02 C h a p t e r Java

비긴쿡-자바 00앞부속

PowerPoint Presentation

PowerPoint Presentation

fundamentalOfCommandPattern_calmglow_pattern_jstorm_1.0_f…

PowerPoint Presentation

자바 프로그래밍

PowerPoint Presentation

신림프로그래머_클린코드.key

PowerPoint Presentation

(8) getpi() 함수는정적함수이므로 main() 에서호출할수있다. (9) class Circle private double radius; static final double PI= ; // PI 이름으로 로초기화된정적상수 public

11장.key

쉽게 풀어쓴 C 프로그래밍

제11장 프로세스와 쓰레드

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

PowerPoint Presentation

Spring Data JPA Many To Many 양방향 관계 예제

Microsoft PowerPoint - 2강

9장.key

JAVA PROGRAMMING 실습 09. 예외처리

PowerPoint 프레젠테이션

PowerPoint Presentation

쉽게 풀어쓴 C 프로그래밍

public class FlowLayoutPractice extends JFrame { public FlowLayoutPractice() { super("flowlayout Practice"); this. Container contentpane = getcontentp

슬라이드 1

Microsoft PowerPoint - java1-lab5-ImageProcessorTestOOP.pptx

Spring Boot/JDBC JdbcTemplate/CRUD 예제

Microsoft Word - java18-1-final-answer.doc

Microsoft PowerPoint - ÀÚ¹Ù08Àå-2.ppt

<4D F736F F F696E74202D20C1A63236C0E520BED6C7C3B8B428B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

슬라이드 1

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

슬라이드 1

Cluster management software

Design Issues

교육자료

Microsoft PowerPoint - Lect04.pptx

Java ~ Java program: main() class class» public static void main(string args[])» First.java (main class ) /* The first simple program */ public class

PowerPoint 프레젠테이션

Network Programming

Java Programing Environment

Microsoft PowerPoint - Java7.pptx

어댑터뷰

PowerPoint Presentation

JMF2_심빈구.PDF

No Slide Title

쉽게 풀어쓴 C 프로그래밍

10-Java Applet

gnu-lee-oop-kor-lec11-1-chap15

쉽게 풀어쓴 C 프로그래밊

Microsoft PowerPoint - RMI.ppt

(Microsoft PowerPoint - LZVNQBAJWGTC.ppt [\310\243\310\257 \270\360\265\345])

중간고사

mytalk

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

Microsoft Word - EEL2 Lab4.docx

JTable과 MVC(Model-View-Controller) 구조 - 모델-뷰-컨트롤러구조는데이터의저장과접근에대한제공은모델이담당하고, 화면표시는뷰, 이벤트의처리는컨트롤러가하도록각역할을구분한구조이다. 즉, 역할의분담을통하여상호간의영향을최소화하고각요소의독립성을보장하여독자

파일로입출력하기II - 파일출력클래스중에는데이터를일정한형태로출력하는기능을가지고있다. - PrintWriter와 PrintStream을사용해서원하는형태로출력할수있다. - PrintStream은구버전으로가능하면 PrintWriter 클래스를사용한다. PrintWriter

PowerPoint 프레젠테이션

자바로

(Microsoft PowerPoint - java1-lecture11.ppt [\310\243\310\257 \270\360\265\345])

OOP 소개

<4D F736F F F696E74202D20C1A63234C0E520C0D4C3E2B7C228B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

Microsoft PowerPoint - 13_UMLCoding(2010).pptx

Microsoft Word - java19-1-final-answer.doc

JAVA PROGRAMMING 실습 05. 객체의 활용

ilist.add(new Integer(1))과 같이 사용하지 않고 ilist.add(1)과 같이 사용한 것은 자바 5.0에 추가된 기본 자료형과 해당 객체 자료 형과의 오토박싱/언박싱 기능을 사용한 것으로 오토박싱이란 자바 컴파일러가 객체를 요구하는 곳에 기본 자료형

A Tour of Java IV

Transcription:

다양한수준의설계패턴존재 객체지향프로그래밍에서, 클래스설계시활용할수있음. 일반개발자는새로운설계패턴을작성하기보다는이미정리되어있는설계패턴을활용하는것이바람직함 GoF (Gang of Four) 에서 23 개의설계패턴을 3 가지유형으로분류

Creational Pattern 객체를생성하는데관련된패턴들 객체가생성되는과정에유연성을높이고, 코드의유지가쉬워진다. Structural Pattern 프로그램의구조에관련된패턴들 프로그램내의자료구조나인터페이스구조등프로그램의구조를설계하는데많이활용될수있는패턴들 Behavioral Pattern 반복적으로사용되는객체들의상호작용을패턴화해놓은것

Creational Structural Behavioral Abstract Factory Prototype Singleton Factory Method Builder Adapter Bridge Composite Decorator Flyweight Façade Proxy Chain of Responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template Method Visitor

용도 관찰대상의상태가변화했을때관찰자에게통지 상태변화에따른처리를기술할때효과적으로활용

추상클래스

public interface Observer { public abstract void update(numbergenerator generator); import java.util.vector; import java.util.iterator; public abstract class NumberGenerator { private Vector observers = new Vector(); // Observer들을보관 public void addobserver(observer observer) { // Observer를추가 observers.add(observer); public void deleteobserver(observer observer) { // Observer를삭제 observers.remove(observer); public void notifyobservers() { // Observer에통지 Iterator it = observers.iterator(); while (it.hasnext()) { Observer o = (Observer)it.next(); o.update(this); public abstract int getnumber(); // 수를취득한다. public abstract void execute(); // 수를생성한다. 자신을관찰하는 observer 자신의내용이갱신되었으니, 이를반영해달라고, observer 모두에게전달하는 method

import java.util.random; public class RandomNumberGenerator extends NumberGenerator { private Random random = new Random(); // 난수발생기 private int number; // 현재의수 public int getnumber() { // 수를취득한다. return number; public void execute() { for (int i = 0; i < 20; i++) { number = random.nextint(50); notifyobservers(); public class DigitObserver implements Observer { public void update(numbergenerator generator) { System.out.println("DigitObserver:" + generator.getnumber()); try { Thread.sleep(100); catch (InterruptedException e) { 0~49 범위의난수를발생 NumberGenerator 의 getnumber 메소드를이용하여변경된내용을출력

public class GraphObserver implements Observer { public void update(numbergenerator generator) { System.out.print("GraphObserver:"); int count = generator.getnumber(); for (int i = 0; i < count; i++) { System.out.print("*"); System.out.println(""); try { Thread.sleep(100); catch (InterruptedException e) { NumberGenerator 의 getnumber 메소드를이용하여변경된내용을출력 public class Main { public static void main(string[] args) { NumberGenerator generator = new RandomNumberGenerator(); Observer observer1 = new DigitObserver(); Observer observer2 = new GraphObserver(); generator.addobserver(observer1); generator.addobserver(observer2); generator.execute();

용도 실행하고싶은메소드의 history 관리 매크로명령을정의하고자할때 동일한명령을반복해서실행

package command; public interface Command { public abstract void execute(); 다수의 Command 를모아두기위한것 Command 필드에보관되어있는각인스터의 execute 메소드를호출 package command; import java.util.stack; import java.util.iterator; public class MacroCommand implements Command { // 명령의집합 private Stack commands = new Stack(); // 실행 public void execute() { Iterator it = commands.iterator(); while (it.hasnext()) { ((Command)it.next()).execute(); // 추가 public void append(command cmd) { if (cmd!= this) { commands.push(cmd); // 최후의명령을삭제 public void undo() { if (!commands.empty()) { commands.pop(); // 젂부삭제 public void clear() { commands.clear();

package drawer; public interface Drawable { public abstract void draw(int x, int y); package drawer; import command.command; import java.awt.point; public class DrawCommand implements Command { // 그림그리는대상 protected Drawable drawable; // 그림그리기를실행할대상 private Point position; // 생성자 public DrawCommand(Drawable drawable, Point position) { this.drawable = drawable; this.position = position; // 실행이위치에점을그려라 public void execute() { drawable.draw(position.x, position.y); package drawer; import command.*; import java.util.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class DrawCanvas extends Canvas implements Drawable { private Color color = Color.red; // 그림그리는색 private int radius = 6; // 그림그리기를할점의변경 private MacroCommand history; // 이력 // 생성자 public DrawCanvas (int width, int height, MacroCommand history) { setsize(width, height); setbackground(color.white); this.history = history; // 이력젂체를다시그리기 public void paint(graphics g) { history.execute(); // 그리기 public void draw (int x, int y) { Graphics g = getgraphics(); g.setcolor(color); g.filloval(x - radius, y - radius, radius * 2, radius * 2);

import command.*; import drawer.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Main extends JFrame implements ActionListener, MouseMotionListener, WindowListener { // 그림그리기이력 private MacroCommand history = new MacroCommand(); // 그림그리기영역 private DrawCanvas canvas = new DrawCanvas(400, 400, history); // 제거버튼 private JButton clearbutton = new JButton("clear"); // 생성자 public Main(String title) { super(title); this.addwindowlistener(this); canvas.addmousemotionlistener(this); // 마우스클리리스터의설정 clearbutton.addactionlistener(this); // Box buttonbox = new Box(BoxLayout.X_AXIS); buttonbox.add(clearbutton); Box mainbox = new Box(BoxLayout.Y_AXIS); mainbox.add(buttonbox); mainbox.add(canvas); getcontentpane().add(mainbox); // ActionListener 용 public void actionperformed(actionevent e) { if (e.getsource() == clearbutton) { history.clear(); canvas.repaint(); // MouseMotionListener 용 public void mousemoved(mouseevent e) { public void mousedragged(mouseevent e) { Command cmd = new DrawCommand(canvas, e.getpoint()); history.append(cmd); cmd.execute(); // WindowListener 용 public void windowclosing(windowevent e) { System.exit(0); public void windowactivated(windowevent e) { public void windowclosed(windowevent e) { public void windowdeactivated(windowevent e) { public void windowdeiconified(windowevent e) { public void windowiconified(windowevent e) { public void windowopened(windowevent e) { public static void main(string[] args) { new Main("Command Pattern Sample"); pack(); setvisible(true);

용도 어떤요구가발행하였을때, 그요구를처리할 object 를바로결정할수없는경우에는, 다수의 object 를 chain 으로연결하여, 그 object chain 을차례로방문하면서, 목적에맞는 object 를결정 요구하는측 과 처리하는측 의연결을약화 Coupling 을낮추는역할

다음책임자 (object) 를보관해두었다가스스로처리할수없는요구가발생하면다음책임자에게넘김

public class Trouble { private int number; public Trouble(int number) { this.number = number; // 트러블번호 // 트러블의생성 public int getnumber() { // 트러블번호를얻는다. return number; public String tostring() { return "[Trouble " + number + "]"; // 트러블의문자열표현 False 이면 다음 object 에 ( 책임을 ) 넘김 final method => overriding 불가 public abstract class Support { private String name; private Support next; public Support(String name) { this.name = name; // 트러블해결자의이름 // 떠넘기는곳 // 트러블해결자의생성 public Support setnext(support next) { // 떠넘길곳을설정 this.next = next; return next; public final void support(trouble trouble) { // 트러블해결순서 if (resolve(trouble)) { done(trouble); else if (next!= null) { next.support(trouble); else { fail(trouble); public String tostring() { return "[" + name + "]"; // 문자열표현 protected abstract boolean resolve(trouble trouble); // 해결용메소드 protected void done(trouble trouble) { // 해결 System.out.println(trouble + " is resolved by " + this + "."); protected void fail(trouble trouble) { // 미해결 System.out.println(trouble + " cannot be resolved.");

public class NoSupport extends Support { public NoSupport(String name) { super(name); public class OddSupport extends Support { public OddSupport(String name) { super(name); // 생성자 protected boolean resolve(trouble trouble) { // 해결용메소드 return false; // 자신은아무처리도하지않는다. public class LimitSupport extends Support { private int limit; // 이번호미만이면해결할수있다. public LimitSupport(String name, int limit) { // 생성자 super(name); this.limit = limit; protected boolean resolve(trouble trouble) { // 해결용메소드 if (trouble.getnumber() < limit) { return true; else { return false; protected boolean resolve(trouble trouble) { if (trouble.getnumber() % 2 == 1) { return true; else { return false; public class SpecialSupport extends Support { // 해결용메소드 private int number; // 이번호만해결할수있다. public SpecialSupport(String name, int number) { // 생성자 super(name); this.number = number; protected boolean resolve(trouble trouble) { if (trouble.getnumber() == number) { return true; else { return false; // 해결용메소드

public class Main { public static void main(string[] args) { Support alice = new NoSupport("Alice"); Support bob = new LimitSupport("Bob", 100); Support charlie = new SpecialSupport("Charlie", 429); Support diana = new LimitSupport("Diana", 200); Support elmo = new OddSupport("Elmo"); Support fred = new LimitSupport("Fred", 300); // chain 의형성 alice.setnext(bob).setnext(charlie).setnext(diana).setnext(elmo).setnext(fred); // 다양한트러블발생 for (int i = 0; i < 500; i += 33) { alice.support(new Trouble(i));

용도 mediator 역할을수행 모듞행동을수행하기이젂에 조정자 의결정이있어야하며, 조정자 의판단은각멤버에게내려짐

public interface Mediator { public abstract void createcolleagues(); public abstract void colleaguechanged(colleague colleague); public interface Colleague { public abstract void setmediator(mediator mediator); public abstract void setcolleagueenabled(boolean enabled); import java.awt.button; public class ColleagueButton extends Button implements Colleague { private Mediator mediator; public ColleagueButton(String caption) { super(caption); public void setmediator(mediator mediator) { // Mediator 를보관 this.mediator = mediator; public void setcolleagueenabled(boolean enabled) { // Mediator 가유효 / 무효를지시한다. setenabled(enabled); import java.awt.textfield; import java.awt.color; import java.awt.event.textlistener; import java.awt.event.textevent; public class ColleagueTextField extends TextField implements TextListener, Colleague { private Mediator mediator; public ColleagueTextField(String text, int columns) { // 생성자 super(text, columns); public void setmediator(mediator mediator) { // Mediator를보관 this.mediator = mediator; public void setcolleagueenabled(boolean enabled) { // Mediator가유효 / 무효를지시한다. setenabled(enabled); setbackground(enabled? Color.white : Color.lightGray); public void textvaluechanged(textevent e) { // 문자열이변하면 Mediator에게통지 mediator.colleaguechanged(this);

import java.awt.checkbox; import java.awt.checkboxgroup; import java.awt.event.itemlistener; import java.awt.event.itemevent; public class ColleagueCheckbox extends Checkbox implements ItemListener, Colleague { private Mediator mediator; public ColleagueCheckbox(String caption, CheckboxGroup group, boolean state) { // 생성자 super(caption, group, state); public void setmediator(mediator mediator) { // Mediator 를보관 this.mediator = mediator; public void setcolleagueenabled(boolean enabled) { // Mediator 가유효 / 무효를지시한다. setenabled(enabled); public void itemstatechanged(itemevent e) { // 상태가변하면 Mediator 에게통지 mediator.colleaguechanged(this); public class Main { static public void main(string args[]) { new LoginFrame("Mediator Sample");

import java.awt.frame; import java.awt.label; import java.awt.color; import java.awt.checkboxgroup; import java.awt.gridlayout; import java.awt.event.actionlistener; import java.awt.event.actionevent; public class LoginFrame extends Frame implements ActionListener, Mediator { private ColleagueCheckbox checkguest; private ColleagueCheckbox checklogin; private ColleagueTextField textuser; private ColleagueTextField textpass; private ColleagueButton buttonok; private ColleagueButton buttoncancel; // 생성자 // Colleague 들을생성해서배치한후에표시를실행한다. public LoginFrame(String title) { super(title); setbackground(color.lightgray); // 레이아웃매니저를사용해서 4*2 의그리드를만듞다. setlayout(new GridLayout(4, 2)); // Colleague 들의생성 createcolleagues(); // 배치 add(checkguest); add(checklogin); add(new Label("Username:")); add(textuser); add(new Label("Password:")); add(textpass); add(buttonok); add(buttoncancel); // 유효 / 무효의초기지정 colleaguechanged(checkguest); // 표시 pack(); show(); // Colleague 들을생성한다. public void createcolleagues() { // 생성 CheckboxGroup g = new CheckboxGroup(); checkguest = new ColleagueCheckbox("Guest", g, true); checklogin = new ColleagueCheckbox("Login", g, false); textuser = new ColleagueTextField("", 10); textpass = new ColleagueTextField("", 10); textpass.setechochar('*'); buttonok = new ColleagueButton("OK"); buttoncancel = new ColleagueButton("Cancel"); // Mediator 의세트 checkguest.setmediator(this); checklogin.setmediator(this); textuser.setmediator(this); textpass.setmediator(this); buttonok.setmediator(this); buttoncancel.setmediator(this); // Listener 의세트 checkguest.additemlistener(checkguest); checklogin.additemlistener(checklogin); textuser.addtextlistener(textuser); textpass.addtextlistener(textpass); buttonok.addactionlistener(this); buttoncancel.addactionlistener(this); // Colleague로부터의통지로각 Colleague의유효 / 무효를판정한다. public void colleaguechanged(colleague c) { if (c == checkguest c == checklogin) { if (checkguest.getstate()) { // Guest 모드 textuser.setcolleagueenabled(false); textpass.setcolleagueenabled(false); buttonok.setcolleagueenabled(true); else { // Login 모드 textuser.setcolleagueenabled(true); userpasschanged(); else if (c == textuser c == textpass) { userpasschanged(); else { System.out.println("colleagueChanged:unknown colleague = " + c); // textuser 또는 textpass의변경이있었다. // 각 Colleague의유효 / 무효를판정한다. private void userpasschanged() { if (textuser.gettext().length() > 0) { textpass.setcolleagueenabled(true); if (textpass.gettext().length() > 0) { buttonok.setcolleagueenabled(true); else { buttonok.setcolleagueenabled(false); else { textpass.setcolleagueenabled(false); buttonok.setcolleagueenabled(false); public void actionperformed(actionevent e) { System.out.println("" + e); System.exit(0);

용도 데이터구조안에많은요소가저장되어있고, 각요소들에대해서여러가지유형의 처리 를수행할경우에활용 데이터구조와처리를분리 데이터구조내부를 traversal 하는 visitor 를나타내는클래스를준비해서그클래스에게처리를일임함. 새로운처리를추가하고자할때에는새로운 visitor 를생성

public abstract class Visitor { public abstract void visit(file file); public abstract void visit(directory directory); public interface Acceptor { public abstract void accept(visitor v); import java.util.iterator; public abstract class Entry implements Acceptor { public abstract String getname(); // 이름을얻는다. public abstract int getsize(); // 사이즈를얻는다. public Entry add(entry entry) throws FileTreatmentException { // 엔트리를추가 throw new FileTreatmentException(); public Iterator iterator() throws FileTreatmentException { // Iterator의생성 throw new FileTreatmentException(); public String tostring() { // 문자열표현 return getname() + " (" + getsize() + ")"; public class File extends Entry { private String name; private int size; public File(String name, int size) { this.name = name; this.size = size; public String getname() { return name; public int getsize() { return size; public void accept(visitor v) { v.visit(this); import java.util.iterator; import java.util.vector; public class Directory extends Entry { private String name; // 디렉토리의이름 private Vector dir = new Vector(); // 디렉토리엔트리의집합 public Directory(String name) { // 생성자 this.name = name; public String getname() { // 이름을얻는다. return name; public int getsize() { // 사이즈를얻는다. int size = 0; Iterator it = dir.iterator(); while (it.hasnext()) { Entry entry = (Entry)it.next(); size += entry.getsize(); return size; public Entry add(entry entry) { // 엔트리의추가 dir.add(entry); return this; public Iterator iterator() { // Iterator의생성 return dir.iterator(); public void accept(visitor v) { // 방문자를받아들임 v.visit(this);

import java.util.iterator; public class ListVisitor extends Visitor { private String currentdir = ""; 는디렉토리명 public void visit(file file) { 다. System.out.println(currentdir + "/" + file); // 현재주목하고있 // 파일을방문했을때호출된 public void visit(directory directory) { // 디렉토리를방문했을때호출된다. System.out.println(currentdir + "/" + directory); String savedir = currentdir; currentdir = currentdir + "/" + directory.getname(); Iterator it = directory.iterator(); while (it.hasnext()) { Entry entry = (Entry)it.next(); entry.accept(this); currentdir = savedir; public class FileTreatmentException extends RuntimeException { public FileTreatmentException() { public FileTreatmentException(String msg) { super(msg); public class Main { public static void main(string[] args) { try { System.out.println("Making root entries..."); Directory rootdir = new Directory("root"); Directory bindir = new Directory("bin"); Directory tmpdir = new Directory("tmp"); Directory usrdir = new Directory("usr"); rootdir.add(bindir); rootdir.add(tmpdir); rootdir.add(usrdir); bindir.add(new File("vi", 10000)); bindir.add(new File("latex", 20000)); rootdir.accept(new ListVisitor()); System.out.println(""); System.out.println("Making user entries..."); Directory Kim = new Directory("Kim"); Directory Lee = new Directory("Lee"); Directory Kang = new Directory("Kang"); usrdir.add(kim); usrdir.add(lee); usrdir.add(kang); Kim.add(new File("diary.html", 100)); Kim.add(new File("Composite.java", 200)); Lee.add(new File("memo.tex", 300)); Kang.add(new File("game.doc", 400)); Kang.add(new File("junk.mail", 500)); rootdir.accept(new ListVisitor()); catch (FileTreatmentException e) { e.printstacktrace();

용도 Instance 작성을하위 class 에게위임 Instance 를만드는방법은상위 class 에서결정하지만, 구체적인 class 의이름까지는정하지않음 Instance 를생성을위한 framework 과실제로 instance 를생성하는 class 를분리함

package framework; public abstract class Product { public abstract void use(); package framework; public abstract class Factory { public final Product create(string owner) { Product p = createproduct(owner); registerproduct(p); return p; protected abstract Product createproduct(string owner); protected abstract void registerproduct(product product); package idcard; import framework.*; public class IDCard extends Product { private String owner; IDCard(String owner) { System.out.println(owner + " 의카드를만듭니다."); this.owner = owner; public void use() { System.out.println(owner + " 의카드를만듭니다."); public String getowner() { return owner; package idcard; import framework.*; import java.util.*; public class IDCardFactory extends Factory { private Vector owners = new Vector(); protected Product createproduct(string owner) { return new IDCard(owner); protected void registerproduct(product product) { owners.add(((idcard)product).getowner()); public Vector getowners() { return owners;

import framework.*; import idcard.*; public class Main { public static void main(string[] args) { Factory factory = new IDCardFactory(); Product card1 = factory.create(" 홍길동 "); Product card2 = factory.create(" 이순신 "); Product card3 = factory.create(" 강감찬 "); card1.use(); card2.use(); card3.use();