!
NO: 1 2004-4-7 2004-4-10 Bob Wang Ver 0.4 2 2004-4-16 2004-4-16 Bob Wang Ver 0.5 3 2004-4-18 2004-4-18 Bob Wang Ver 0.51 4 2004-4-19 2004-4-28 Melthaw Zhang Ver 0.6 5 2004-4-19 2004-4-29 Bob Wang Ver 0.7 6 2004-4-19 2004-5-12 Orient Sun Ver 0.8 7 2004-4-19 2004-5-12 LishiFeng Ver 0.8 2 116
... 8... 9... 9...11... 12... 13... 13... 14... 14... 15... 15... 15... 16 UML... 16... 16... 19... 20... 20 (Behavior)... 20... 22... 24... 25... 25... 26 UML... 26 Case... 27... 27 Javadocs... 28... 28 3 116
... 30... 30... 30... 31... 31... 31... 33... 34... 34... 35... 36... 36... 37... 38... 39... 40... 40... 41... 42... 42... 42... 43... 43... 43... 44... 45... 46... 48... 48... 50 4 116
... 51... 53... 54... 55... 56... 57... 57... 57... 58... 58... 59... 59... 59... 60... 60... 61... 61... 61... 62 SRP... 62 - OCP... 64 Liskov (LSP)... 77 (DIP)... 79 ISP... 79... 81... 81 dx 83... 83... 83... 84 5 116
... 84... 85... 85... 85... 86... 86... 87... 87... 87... 88... 88... 89... 89... 89... 90... 90... 92 Java Packages... 92 Packages... 92 Dependencies... 93.jar Binary Components... 93 Principles of Package Design... 94 / The Release/Reuse Equivalency Principle (REP) 94 The Common Closure Principle (CCP)... 95 The Common Reuse Principle (CRP)... 95 The Acyclic Dependencies Principle (ADP)... 95 The Stable Dependencies Principle (SDP)... 95 The Stable Abstractions Principle (SAP)... 96... 97 Object Diagrams... 98 6 116
... 98 Active Objects... 99... 102 (State Diagrams)... 103... 103... 104... 105... 106... 107 SMC... 108 ICE...111...115 7 116
UML (notation) Fowler IT Conceptual Specification Implementation (Dog) (Animal) UML Figure 1-1 (generalization) Animal Dog Animal Dog Dog Animal Sparky 8 116
Animal Dog UML UML UML UML (static diagrams) (Dynamic diagrams) (Physical diagrams) Listing 1-1 Figure 1-2 (Class Diagram) Listing 1-1 TreeMap add get TreeMap TreeMapNode topname reference TreeMapNode TreeMapNode -- nodes TreeMapNode itskey itskey itskey Comparable itsvalue 9 116
(associations) 10 116
1 «interface» Comparable (interface) Listing 1-1 TreeMap TreeMapNode topnode TreeMap topnode Figure 1-3 (Object Diagram) (snapshot) itskey (links) Figure 1-3 nodes 11 116
Figure 1-4 (sequence diagram) TreeMap.add TreeMap add topnode (null) TreeMap TreeMapNode topnode TreeMap add topnode (guards) TreeMapNode (construction) 12 116
(data tokens) TreeMap activation add Figure 1-5 (collaboration diagram) treenode TreeMap.add (links) TreeMap.add 1 TreeMapNode.add 1.1 1.1 1 UML (finite state machines) Figure 1-6 Figure 1-6 Locked UnLocked coin pass 13 116
(transitions) Figure 1-6 Locked coin Unlocked Unlock Unlocked pass Locked Lock Unlocked coin Unlocked Thankyou Locked pass Locked Alarm UML [Fowler00]: UML Distilled, 2d. ed. Martin Fowler, Addison Wesley, 199? 14 116
UML UML UML (models) UML UML UML UML UML UML UML UML UML 15 116
UML UML UML UML UML UML UML UML UML UML Figure 2-1 LogiServlet Servlet UserDatabase LoginServlet HTTPRequest HTTPResponse UML Listing-2-1 UML 16 116
Figure 2-2 Figure 2-3 UML 17 116
UML (roadmaps) 18 116
Figure 2-4 Space Polyline Polyline LinearObject Lines LinearObject Points UML UML (Figure 2-5) 19 116
UML Case UML Web UML! UML UML 20 116
Button Dialler Button digit Dialler Dialler digit displaydigit Screen Dialler tone Speaker 21 116
Radio Screen ( ) Figure 2-6 (class) (association) UML (aggregation) (composition) (relationships) 22 116
Button Dialler Button Dialler Button Button Button Dialler Button Button Dialler (interface) Figure 2-8 Button (token) Button ButtonListener buttonpressed Button Dialler Button Figure 2-6 Dialler Button Dailler ButtonListener buttonpressed Dialler Button 23 116
ButtonDiallerAdapter ButtonListener buttonpress digit(n) Dialler digit Dialler ButtonDiallerAdapter Listing 2-2 24 116
Figure 2-9 Figure 2-6 Figure 2-10 5 5 UML UML 25 116
UML UML UML 26 116
UML Case UML case UML case UML case UML UML case IDE IDE CASE Cool UML IDE Case Case 27 116
UML 12 100 Java 25 200 UML ER wiki Javadocs Javadocs UML 5 UML Case UML case IDE UML Case UML 28 116
UML 29 116
UML Figure 3-1 Dialler Figure 3-2 - private # (protected) + (public) 30 116
UML Figure 3-3 Phone Button Phone Button Figure 3-3 15 button Phone Figure 3-4 PhoneBook PhoneNumber (*) Java Vector List HasA has Phonebook PhoneNumbers Hasa IsA 6 UML Figure 3-5 Employee 31 116
(inheritance) UML SalariedEmployee Emplyee Employee UML (base class) UML Java Java Figure 3-6 Figure 3-7 COM 32 116
Figure 3-8 ATM WithdrawTransaction CashDispenser CashDispenser UI WithDrawlUI PromptForAccount informcashdispenserempty 33 116
UI UI UI Listing 3-1 UML Figure 3-8 «interface» «interface» java «utility» «interface» «interface» java Figure 3-9 34 116
«utility» «utility» Booch Figure 3-10 «persistent» «C-API» «struct» «function» UML {abstract Figure 3-11 {abstract Figure 3-12 UML 35 116
{abstract {author=martin, date=20020429, file=shape.java, private UML {abstract UML java boolean (true) {abstract {abstract=true Figure 3-13 {abstract UML whole/part Figure 3-14 Figure 3-14 36 116
UML UML Figure 3-15 Figure 3-16 UML Java C++ (owner) (ward) UML Figure 3-17 37 116
Java java Figure 3-18 Address Address String Address Address String UML (multipicity) Figure 3-19 BinaryTreeNode 2 * 0..* 0 0..1 0 1 Java 1..* 1 3..5 3 5 0,2..5,9..* 38 116
Figure 3-20 UML «creates» (factory) «local» 39 116
«parameter» «delegates» UML PROXY DECORATOR COMPOSITE7 UML Java UML Figure 3-22 «anonymous» 40 116
Figure 3-23 Java weak soft phantom Figure 3-24 Figure 2-25 41 116
Java Figure 3-26 LoginServlet Employee empid Employee UML UML UML UML UML [Booch94]: Object Oriented Analysis and Design with Applications, Grady Booch, Benjamin Cummings, 1994 [GOF94]: Design Patterns, Gamma, Helm, Vlissides, Johnson, Addison Wesley, 1994 42 116
UML UML 1978 James Grenning Figure 4-1 (lifelines) 43 116
(data tokens ) (Time) LoginServlet (Activation) login login login getemployee e getemployee Employee e getemployee Employee EmployeeDB getemployee EmployeeDB Listing 4-1 Figure 4-2 ShapeFactory Listing 4-2 44 116
Java Figure 4-3 UML X X Listing 4-3 clear topnode (nil) TreeMap TreeNode UML Figure 4-4 45 116
46 116
Figure 4-5 UML Listing 4-4 Payroll Figure 4-5 Figure 4-6 Figure 4-6 47 116
Figure 4-7 Figure 4-8 48 116
(loop) if payemployee *[while id := idlist.next()] (guard) false UML java payemployee payemploy [payday] if ifpayday true CalculatePay,CalculateDedutions sendpayment UML (clunky?) Listing 4-4 49 116
OO Figure 4-9 caller callee telco (off hook) received dial tone (ringing) (playing ringback) Figure 4-10 50 116
Figure 4-10 (race condition) (asychronous message) Figure 4-11 UML 51 116
Listing 4-5 listing 4-6 Figure 4-11 Listing 4-5 Listing 4-6 Log logmessage LogText logmessage 52 116
UML Figure 4-12 53 116
T1 Log T1 Log T2 Listing 4-6 T2 (active objects) Figure 4-13: 54 116
Log logmessage Log Figure 4-14 Logger AsynchronousLogger Figure 4-15 logger Logger AsychronousLogger Logger Figure 4-16 55 116
5 6 90 56 116
(Use case) UML UML UML (stimulus) 57 116
(stimulus) Check Out Item : 1 UPC 2 3 4 UPC 58 116
UPC Code Not Read UPC UPC No UPC Code UPC UPC UPC Alistair Cockburn UML System Boundary Diagram Figure 5-1 (actor) (stimulus) 59 116
Java 60 116
UML UML UML UML 12 Rigidity (Fragility) (immobility) (Viscosity) (Needless Complexity) (Needless repetition) cut paste 61 116
(Opacity) UML (interface) (Polymorphism) OOPL [Martin2002] www.objectmmentor.com SRP GUI XML OO 62 116
Figure 6-1 XML SAX JDOM Employee Access Oracle Employee Employee Employee XML Employee XML EmployeeDatabase Employee Figure 6-2 UML Figure 6-3 Persistable Employee Employee Persistable Persistable Employee Figure 6-3 Persistable Employee PersistableEmployee Employee 63 116
- OCP ( ) Figure 6-4 EmployeeDB (facade) Employee (facade) API OCP EmployeeDB Employee Employee API Empoyee TheDatabase API (Unit test) Employee Employee Employee Employee (interface) Figure 6-5 API Empolyee API Employee 64 116
Employee OCP GUI MODEL-VIEW-CONTROLLER 30 GUI GUI API Terminate Terminate Terminate Terminate (terminated) Terminate 65 116
OCP GUI API OCP GUI Figure 6-6 OCP EmployeeTerminatorModel EmployeeTerminatorDialog GUI Terminate EmployeeTerminatorModel EmployeeTerminatorDialog EmployeeTerminatorModel EmployeeTerminatorController Listing 6-1 Listing 6-4 Java EmployeeTerminatorController selectionchanged terminate terminate employee EmployeeTerminatorDialog Listing 6-1 EmployeeTerminatorView.java import java.util.vector; public interface EmployeeTerminatorView { void enableterminate(boolean enable); void setemployeelist(vector employees); void clearselection(); Listing 6-2 EmployeeTerminatorController.java public interface EmployeeTerminatorController { public void selectionchanged(string employee); public void terminate(); EmployeeTerminatorModel 66 116
selectionchange Listing 6-3 EmployeeTerminatorModel.java import java.util.vector; public class EmployeeTerminatorModel implements EmployeeTerminatorController { private EmployeeTerminatorView view; private Vector employees; private String selectedemployee; public void initialize(vector employees,employeeterminatorview view) { this.employees = employees; this.view = view; view.setemployeelist(employees); view.clearselection(); view.enableterminate(false); // EmployeeTerminatorController interface public void selectionchanged(string employee) { view.enableterminate(employee!= null); selectedemployee = employee; public void terminate() { if (selectedemployee!= null) employees.remove(selectedemployee); view.setemployeelist(employees); view.clearselection(); view.enableterminate(false); EmployeeTerminatorDialog GUI EmployeeTerminatorView 67 116
Listing 6-4 EmployeeTerminatorDialog.java import javax.swing.*; import javax.swing.event.listselectionevent; import javax.swing.event.listselectionlistener; import java.awt.*; import java.awt.event.actionevent; import java.awt.event.actionlistener; import java.util.vector; public class EmployeeTerminatorDialog implements EmployeeTerminatorView { private JFrame frame; private JList listbox; private JButton terminatebutton; private EmployeeTerminatorController controller; private Vector employees; public static final String EMPLOYEE_LIST_NAME = "Employee List"; public static final String TERMINATE_BUTTON_NAME = "Terminate"; public void initialize(employeeterminatorcontroller controller) { this.controller = controller; initializeemployeelistbox(); initializeterminatebutton(); initializecontentpane(); private void initializeemployeelistbox() { listbox = new JList(); listbox.setname(employee_list_name); listbox.addlistselectionlistener(new ListSelectionListener() { public void valuechanged(listselectionevent e) { if (!e.getvalueisadjusting()) controller.selectionchanged( (String)listBox.getSelectedValue()); ); private void initializeterminatebutton() { terminatebutton = new JButton(TERMINATE_BUTTON_NAME); terminatebutton.disable(); 68 116
terminatebutton.setname(terminate_button_name); terminatebutton.addactionlistener( new ActionListener() { public void actionperformed(actionevent e) { controller.terminate(); ); private void initializecontentpane() { frame = new JFrame("Employee List"); frame.getcontentpane().setlayout(new FlowLayout()); frame.getcontentpane().add(listbox); frame.getcontentpane().add(terminatebutton); frame.getcontentpane().setsize(300, 600); frame.pack(); public Container getcontentpane() { return frame.getcontentpane(); public JFrame getframe() { return frame; // functions for EmployeeTerminatorView interface public void enableterminate(boolean enable) { terminatebutton.setenabled(enable); public void setemployeelist(vector employees) { this.employees = employees; listbox.setlistdata(employees); frame.pack(); public void clearselection() { listbox.clearselection(); 69 116
model dialog dialog controller model model clearselection Figure 6-7 model dialog clearselection dialog model setselection model dialog (unit test) ( Listing 6-5 Listing 6-6 ) OCP TestEmployeeTerminatorModel model EmployeeTerminatorView model view SELF SHUNT Listing 6-5 TestEmployeeTerminatorModel.java import junit.framework.testcase; import junit.swingui.testrunner; import java.util.vector; public class TestEmployeeTerminatorModel extends TestCase implements EmployeeTerminatorView { private boolean terminateenabled = true; private String selectedemployee; private Vector noemployees = new Vector(); private Vector threeemployees = new Vector(); private Vector employees = null; private EmployeeTerminatorModel m; 70 116
public static void main(string[] args) { TestRunner.main(new String[]{"TestEmployeeTerminatorModel"); public TestEmployeeTerminatorModel(String name) { super(name); public void setup() throws Exception { m = new EmployeeTerminatorModel(); threeemployees.add("bob"); threeemployees.add("bill"); threeemployees.add("robert"); public void teardown() throws Exception { public void testnoemployees() throws Exception { m.initialize(noemployees, this); assertequals(0, employees.size()); assertequals(false, terminateenabled); assertequals(null, selectedemployee); public void testthreeemployees() throws Exception { m.initialize(threeemployees, this); assertequals(3, employees.size()); assertequals(false, terminateenabled); assertequals(null, selectedemployee); public void testselection() throws Exception { m.initialize(threeemployees, this); m.selectionchanged("bob"); assertequals(true, terminateenabled); m.selectionchanged(null); assertequals(false, terminateenabled); public void testterminate() throws Exception { m.initialize(threeemployees, this); assertequals(3, employees.size()); selectedemployee = "Bob"; 71 116
m.selectionchanged("bob"); m.terminate(); assertequals(2, employees.size()); assertequals(null, selectedemployee); assertequals(false, terminateenabled); assert(employees.contains("bill")); assert(employees.contains("robert")); assert(!employees.contains("bob")); // EmployeeTerminatorView interface public void enableterminate(boolean enable) { terminateenabled = enable; public void setemployeelist(vector employees) { this.employees = (Vector) employees.clone(); public void clearselection() { selectedemployee = null; TestEmployeeTerminatorDialog SELF SHUNT TestTerminatorController dialog controller Listing 6-6 TestEmployeeTerminatorDialog.java import junit.framework.testcase; import junit.swingui.testrunner; import javax.swing.*; import java.awt.*; import java.util.hashmap; import java.util.vector; public class TestEmployeeTerminatorDialog extends TestCase implements EmployeeTerminatorController { private EmployeeTerminatorDialog terminator; 72 116
private JList list; private JButton button; private Container contentpane; private String selectedvalue = null; private int selectioncount = 0; private int terminations = 0; public static void main(string[] args) { TestRunner.main(new String[]{"TestEmployeeTerminatorDialog"); public TestEmployeeTerminatorDialog(String name) { super(name); public void setup() throws Exception { terminator = new EmployeeTerminatorDialog(); terminator.initialize(this); putcomponentsintomembervariables(); private void putcomponentsintomembervariables() { contentpane = terminator.getcontentpane(); HashMap map = new HashMap(); for (int i = 0; i < contentpane.getcomponentcount(); i++) { Component c = contentpane.getcomponent(i); map.put(c.getname(), c); list = (JList) map.get( EmployeeTerminatorDialog.EMPLOYEE_LIST_NAME); button = (JButton) map.get( EmployeeTerminatorDialog.TERMINATE_BUTTON_NAME); private void putthreeemployeesintoterminator() { Vector v = new Vector(); v.add("bob"); v.add("bill"); v.add("boris"); terminator.setemployeelist(v); public void testcreate() throws Exception { assertnotnull(contentpane); 73 116
assertequals(2, contentpane.getcomponentcount()); assertnotnull(list); assertnotnull(button); assertequals(false, button.isenabled()); public void testaddonename() throws Exception { Vector v = new Vector(); v.add("bob"); terminator.setemployeelist(v); ListModel m = list.getmodel(); assertequals(1, m.getsize()); assertequals("bob", m.getelementat(0)); public void testaddmanynames() throws Exception { putthreeemployeesintoterminator(); ListModel m = list.getmodel(); assertequals(3, m.getsize()); assertequals("bob", m.getelementat(0)); assertequals("bill", m.getelementat(1)); assertequals("boris", m.getelementat(2)); public void testenableterminate() throws Exception { terminator.enableterminate(true); assertequals(true, button.isenabled()); terminator.enableterminate(false); assertequals(false, button.isenabled()); public void testclearselection() throws Exception { putthreeemployeesintoterminator(); list.setselectedindex(1); assertnotnull(list.getselectedvalue()); terminator.clearselection(); assertequals(null, list.getselectedvalue()); public void testselectionchangedcallback() throws Exception { putthreeemployeesintoterminator(); list.setselectedindex(1); assertequals("bill", selectedvalue); assertequals(1, selectioncount); 74 116
list.setselectedindex(2); assertequals("boris", selectedvalue); assertequals(2, selectioncount); public void testterminatebuttoncallback() throws Exception { button.doclick(); assertequals(1, terminations); // implement EmployeeTerminatorController public void selectionchanged(string employee) { selectedvalue = employee; selectioncount++; public void terminate() { terminations++; OCP dialog model dialog model UI( ) UI dialog model model dialog RMI OCP Figure 6-6 FLIP-FLOP OCP OCP OCP test-first Listing 6-7 model model dialog 75 116
Listing 6-7 ShowEmployeeTerminator.java import java.awt.event.windowadapter; import java.awt.event.windowevent; import java.util.vector; public class ShowEmployeeTerminator { static Vector employees = new Vector(); static EmployeeTerminatorDialog dialog; public static void main(string[] args) { initializeemployeevector(); initializedialog(); rundialog(); private static void initializeemployeevector() { employees.add("bob"); employees.add("bill"); employees.add("robert"); private static void initializedialog() { EmployeeTerminatorModel model = new EmployeeTerminatorModel(); dialog = new EmployeeTerminatorDialog(); dialog.initialize(model); model.initialize(employees, dialog); private static void rundialog() { dialog.getframe().addwindowlistener( new WindowAdapter() { public void windowclosing(windowevent e) { for (int i = 0; i < employees.size(); i++) { String s = (String) employees.elementat(i); System.out.println(s); System.exit(0); ); dialog.getframe().setvisible(true); 76 116
Liskov (LSP) (subtypes) (base types) if instanceof LSP OCP LSP (base classs) instanceof (Downcast) Figure 6-8 Employee calcpay SalariedEmployee HourlyEmployee VolunteerEmployee calcpay 0 calcpay VolunteerEmployee calcpay calcpay 0 77 116
0 VolunteerEmployee calcpay calcpay UnpayableEmloyeeException try/catch Employee LSP VolunteerEmployee Employee if instanceof OCP LSP LSP 78 116
instanceof LSP VolunteerEmployee Volunteers calcpay Employee calcpay (DIP) A B ( ) Vector String DIP Vector String UML UML DIP ISP (fat class) 79 116
Figure 6-9 StudentEnrollment EnrollmentReportGenerator prepareinvoice postpayment AccountsReceivable getname getdate postpayment StudentEnrollment EnrollmentReportGenerator EnrollmentReportGenerator postpayment 80 116
Figure 6-10 StudentEnrollment 1 SRP 2 OCP 3 LSP 4 DIP 5 ISP OCP SRP ISP DIP (proactively) (reactively) (the sore spots) [Feathers2001]: The 'Self'-Shunt Unit Testing Pattern, Michael Feathers, May, 2001, 81 116
http://www.objectmentor.com/resources/articles/selfshunptrn.pdf [Martin2002]: The Principles, Patterns, and Practices of Agile Software Development, Robert C. Martin, Prentice Hall, 2002 2 82 116
dx Melthaw Zhang dx dx dx s use-case use-case user story story use-case use case N 83 116
story story 8 story 4 story story story 6 story story 5 6 7 story story story story story story 3 4 story story story story 7 story 5 5 7 3 15 7 84 116
story story 5 50 300 0.5 150 story 150 story story story 50 25 story 25 story story story 4 10 story 85 116
25 story. 20 story story 10 story story story story story 10 story 8 story 16 story story story 16 story 15 story 30 story story. story 23 story 23 story story 23 story story 86 116
. story story story. story dx 87 116
.. dx story QA user story use-case story dx 5 10 6 1 10 88 116
. API., dx dx dx check out check out check in check 89 116
in check out check in dx check in check in check in dx UML JAVA dx UML JAVA UML dx Martin UML sequence use-case. dx UML UML dx UML dx XP( ) XP dx [Kruchten1998]: The Rational Unified Process, Philippe Kruchten, Addison Wesley, 90 116
Reading, MA, 1998. [Fowler1999]: Refactoring, Martin Fowler, Addison Wesley, Reading, MA, 1999 [Martin1999]: RUP vs. XP, Robert C. Martin, 1999, http://www.objectmentor.com/resources/articles/rupvsxp.pdf [Beck1999]: Extreme Programming Explained, Kent Beck, Addison Wesley, Reading, MA, 1999 [Jeffries2000]: Extreme Programming Installed, Ron Jeffries, et. al, Addison Wesley, Upper Saddle River, NJ, 2000 6. [Beck1999], [Jeffries2000] 91 116
Orient Sun Java Java package.jar Java Packages Java packages (namespaces) Java.class class A.B.C.class A/B/C.class Java.class.java classpath UML UML Figure 8-1 Figure 8-2 92 116
contains Figure 8-3 Java import UML dependency Figure 8-4 import consultant-scheduler.consultantcalendar calendarutilities.calendar Java import.jar Binary Components.jar 93 116
UML Figure 8-5 CalendarRenderer Calendar Principles of Package Design [PPP2002] 1 94 116
SRP CCP CCP ISP CRP A B B C A C JDepend (see www.clarkware.com), 95 116
Figure 8-6 ( ) [PPP2002] OCP SAP SAP SDP SAP DIP DIP SDP SAP [PPP2002] 96 116
ADP build problems 2 2. see www.clarkware.com for just such a tool. 97 116
Object Diagrams Orient Sun UML (Snapshot) (GUI) Figure 9-1 Figure 9-2 Figure 9-1 Space Space 98 116
Active Objects Listing 9-1 SocketService socket socket 99 116
100 116
Figure 9-3 Figure 9-4 SocketService servicethread servicethread servicethread ServerRunner (Active Ojbect) start stop setpriority Thread Runnable Runnable Runnable 101 116
102 116
(State Diagrams) LiShiFeng UML FSMs FSMs (GUI) FSMs FSMs Figure 10-1 State Transition Diagram (STD) 103 116
Prompting for Login showloginscreen Prompting for Login hideloginscreen (Transitions) Prompting for Login login Validating User validateuser Figure 10-1 initial pseudo state Prompting for Login superstate Sending Password Failed Sending Password Succeeded OK Prompting for Login showloginscreen validateuser dsendpassword Login event / action Figure 10-2 entry exit Figure 10-2 FSM UML Figure 10-3 104 116
UML Figure 10-3 exit entry UML Figure 10-3 myaction exit entry Figure 10-1 FSM Figure 10-4 Figure 10-5 S3 pause Cancelable pause 105 116
entry exit Figure 10-6 FSM exit entry FSM Some State Sub entersuper entersub FSM Sub2 Some State exitsub2 exitsuper Sub Sub2 e2 exitsub entersub2 Figure 10-7 UML FMS FSM 106 116
FSM FSM FSMs STTs State Transition Tables STDs State Transition Diagrams Figure 10-8 STT Figure 10-9 107 116
STT STT Locked coin Unlocked Unlock Locked coin Unlocked Unlock Locked pass Locked Alarm Unlocked coin Unlocked Refund Unlocked pass Locked Lock 16 15 SMC STT C++ STT SMC SMC www.objectmentor.com Turnstile SMC Listing 10-1 smc.txt URL FSMName SMC Context SMC Listing 10-2 Context Listing 10-1 Turnstile.sm Context TurnStileContext 108 116
FSMName TurnStile Initial Locked { Locked { Coin Unlocked Unlock Pass Locked Alarm Unlocked { Coin Unlocked Thankyou Pass Locked Lock Listing 10-2 TurnStile.java (Generated) public class TurnStile extends TurnStileContext { private State itsstate; private static String itsversion = ""; private static Locked itslockedstate; private static Unlocked itsunlockedstate; public TurnStile() { itslockedstate = new Locked(); itsunlockedstate = new Unlocked(); itsstate = itslockedstate; public String getversion() { return itsversion; public String getcurrentstatename() { return itsstate.statename(); public void Pass() { itsstate.pass(); public void Coin() { itsstate.coin(); 109 116
private abstract class State { public abstract String statename(); public void pass() { FSMError("Pass", itsstate.statename()); public void coin() { FSMError("Coin", itsstate.statename()); private class Locked extends State { public String statename() { return "Locked"; public void pass() { Alarm(); itsstate = itslockedstate; public void coin() { Unlock(); itsstate = itsunlockedstate; private class Unlocked extends State { public String statename() { return "Unlocked"; public void pass() { Lock(); itsstate = itslockedstate; public void coin() { Thankyou(); itsstate = itsunlockedstate; FSM 110 116
ICE GUI Figure 10-10 FSM UML SMC Listing 10-3 111 116
Listing 10-3 ice.sm Context RootFSM Initial init FSMName RootFSMGen Version 042399 1528 rcm FSMGenerator smc.generator.java.smjavagenerator Pragma Package root { init { init login { login <displayloginscreen >hideloginscreen { login determiningusermode { cancel end { determiningusermode < { cleanupthumbnails checkuserstate { auto autobatch { manual gettingmanualbatch { createselector autobatch < { setuserauto displaythumbnailauto { manual gettingmanualbatch { createselector select gettingautobatch { createselector itemchanged * worktypeitemchanged redisplay * displaythumbnailauto exit end { gettingautobatch <getnextautobatch { nextbatchfound batchsplashauto { nobatchfound determiningusermode { nobatchdialog 112 116
gettingmanualbatch <isbatchavailable { batchesfound manualbatch { nobatchfound autobatch { manualbatch < { setusermanual displaythumbnailmanual { auto autobatch { refresh gettingmanualbatch { select batchsplashmanual selectmanualbatch redisplay * displaythumbnailmanual exit end { (processingbatch) >hidethumbnailscreen { ok * { cancel * { complete determiningusermode { completebatch cleanupbatch requeue determiningusermode { requeuebatch cleanupbatch reject determiningusermode { rejectbatch cleanupbatch assign * assignpage exit end requeuebatch processingautobatch : processingbatch { stop processingautobatchstopped { complete gettingautobatch { completebatch cleanupbatch reject gettingautobatch { rejectbatch cleanupbatch openpage pageautobatch { redisplay * displayautothumbnailprocessing processingautobatchstopped : processingbatch { complete determiningusermode { completebatch 113 116
cleanupbatch reject determiningusermode { rejectbatch cleanupbatch openpage pageautobatchstopped { stop processingautobatch { redisplay * displayautothumbnailprocessing processingmanualbatch : processingbatch { openpage pagemanualbatch { redisplay * displaymanualthumbnailprocessing (batchsplash) <displaybatchsplashscreen >hidebatchsplashscreen { batchsplashauto : batchsplash { ok processingautobatch {allmode initbatch displayautothumbnailprocessing complete gettingautobatch {completebatch hidethumbnailscreen batchsplashmanual : batchsplash { ok processingmanualbatch {allmode initbatch displaymanualthumbnailprocessing complete determiningusermode {completebatch hidethumbnailscreen (page) <displaypagescreen >hidepagescreen { assign * {assignpage redisplaypagescreen setzone * {assignzone redisplaypagescreen pageautobatch : page { goback processingautobatch displayautothumbnailprocessing 114 116
pageautobatchstopped : page { goback processingautobatchstopped displayautothumbnailprocessing pagemanualbatch : page { goback processingmanualbatch displaymanualthumbnailprocessing end <exitprogram { UML FSM FSM 115 116
116 116