1、基于面向对象的管理系统分析和设计摘要:面向对象(Object Oriented)作为目前应用最广的开发系统方法,其概念和应用扩展到了很宽的领域,比如数据库系统、交互式界面、应用平台、CAD技术、人工智能等领域。本文将以Bradshaw Marina为案例,采用三层设计方法,对其进行面向对象分析和设计,其中主要以用例图和类图为主。最后,给出Bradshaw Marina案例的图形界面图。关键字:OOA;OOD ;OOP;用例图;类图Management system based on object-oriented analysis and designS100101159 Yan Yu-lin
2、Abstract:OO (Object Oriented) is currently the most widely used as a development system method, the concepts and applications are applied to the very wide areas, such as database systems, interactive interface and application platform, CAD technology, artificial intelligence and so on. This article
3、will take the Bradshaw Marina as an example, using three-tier design to analysis and design about object-oriented, which mainly use case diagrams and class diagrams. Finally, the Bradshaw Marina will be given the graphical display.Key words:OOA;OOD;OOP;case diagrams ;class diagrams0 引言面向对象(Object Or
4、iented)作为目前应用最广的开发系统方法,而它的概念和应用已超越了程序设计和软件设计,并扩展到了很宽的领域,比如数据库系统、交互式界面、应用平台、CAD技术、人工智能等领域。1 面向对象简介面向对象方法是按人们通常的思维方式建立问题域的模型,设计尽可能自然地表现求解方法的软件。为了实现上述基本原则,必须建立直接表现组成问题域的事物以及这些事物间的相互联系的概念,还必须建立适应人们一般思维方式的描述范式。在面向对象的设计方法学中,对象(Object)和传递消息(Message passing)分别是表现事物及事物间相互联系的概念。类(Class)和继承(Inheritance)是适应人们一般
5、思维方式的描述范式。方法(Method)是允许作用在该类上的各种操作。这种对象、类、消息和方法的程序设计范式的基本点在于对象的封装性(Encapsulation)和继承性。通过封装能将对象的顶和对象的实现分开,通过继承能体现类与类之间的关系,以及由此带来的动态聚束(Dynamic binding)和实体的多态性(Polymorphism),从而构成了面向对象的基本特征1。1.1 面向对象的特征(1)对象唯一性每个对象都有自身唯一的标识,通过这种标识,可以到相应的对象。在对象的整个生命期中,它的标识都不改变,不同的对象不能有相同的标识。(2)抽象性抽象性是指将具有一致的数据结构(属性)和行为(操
6、作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。(3)继承性继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。在软件开发中,类的继承性使所建立的软件具有开放性、可扩充性,这是信息组织与分类的行之有效地方法,它简化了对象、类的创建工作量,增加了代码的可重性。采用继承性,提供了类的规范的等级结构。通过类的继承关系,使公共的特性能够共享,提高了软件的重用性
7、。(4)多态性多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。它允许每个对象以合适自身的方式去响应共同的消息,这增强了软件的灵活性和重用性。1.2 面向对象的要素(1)抽象抽象是指强调实体的本质、内在的属性。在系统开发中,抽象指的是在决定如何实现对象之前的对象的意义和行为。使用它可避免过早考虑一些细节。(2)封装性封装性是保护软件部件具有优良的模块性的基础。面向对象的类是封装良好的模块,类定义将其说明(用户可见的外部接口)与实现(用户不可见的内部实现)显式的分开,其内部实现按其具体定义的作用域提供保护,防
8、止了程序相互依赖性而带来的变动影响。(3)共享性在同一类中的共享,同一类中的对象有着相同数据结构,这些对象之间是结构、行为特征的共享关系;在同一应用中的共享,存在继承关系的各相似子类中,存在数据结构和行为的继承,使各相似子类共享共同的结构和行为;在不同应用中的共享,面向对象不仅允许在同一应用中共享信息,而且为未来目标的可重用设计准备了条件,通过类库这种机制和结构来实现不同应用中的信息共享。(4)强调对象结构1.3 面向对象应用简介随着20世纪80年代初期面向对象开发的逐步成熟,面向对象分析(OOA)和面向对象设计(OOD)脱颖而出。到90年代,由于应用的需要,统一建模语言(UML)逐步形成,它
9、不仅统一了Booch、OMT、OOSE方法的表示方法,而且对其作了进一步的发展,使UML成为一种定义良好、易于表达、功能强大且普遍使用的建模语言,用来对软件密集系统进行描述、构造、视化和文档编制。如今,它已融入了软件工程领域的新思想、新方法和新技术。在使用UML的面向对象开发中,面向对象分析(OOA)和面向对象设计(OOD)使用类图、用例图、序列图和状态图456。对于面向对象的开发,如图1显示了面向对象分析(OOA)、面向对象设计(OOD)和面向对象编程(OOP)的关联性。在本文中,将按照面向对象开发的三层设计,三层设计要求在一个面向对象系统中交互作用的对象的集合被分为3种类-问题域类、GUI
10、类和数据存取类,其中问题域类对基本的业务实体建模,GUI类提供用于数据输入和显示的用户界面,数据存取类提供数据存储和数据检索服务。在面向对象分析(OOA)期间,主要针对问题域类的分析;面向对象设计(OOD)主要涉及到添加与用户交互作用的GUI类和数据存取类,其中添加数据存取类的目的是使用数据库使对象持久。本文将使用Bradshaw Marina案例分析面向对象开发过程。图1 面向对象开发2 Bradshaw Marina案例分析和设计Bradshaw Marina是一家在某内陆湖上出租划艇和提供客轮的公司。该公司是该湖码头上有约350艘帆船,75艘汽艇。Bradshaw Marina希望能够拥
11、有自动化系统追踪其客户、它出租的划艇和船只、搜索船台信息以及添加船只服务记录等2。对于三层设计方法,首先将确定和指定问题域,即涉及用户工作的对象的类;指定了这些类之后,将定义GUI类如何用于允许用户问题域类交互作用;最后,将指定允许问题域类与数据库交互作用的数据存取类;这3层完成之后,我们将做一个完整的系统协同工作。如图2,用一个简单的处理系统显示这3层。用户与图形用户界面交互作用通常会构成窗口,这些窗口包含GUI对象,如菜单、按钮、文本框和标签。用户单击鼠标并按键即可是系统响应。用户不会直接与问题域对象交互作用;但是,GUI对象会与基于用户操作的问题域对象交互作用。通过将用户界面从问题域类中
12、分离出来,这能让我们集中于独立于用户界面的问题域上3。图2 三层设计中的3层创建新的问题域对象时,需要使用某数据库管理功能使对象保持不变。存储与对象有关的信息以使它们保持持久,而所需的过程与问题域类相分离,方法是为各个问题域类定义单独的数据存取类来处理数据存取详细信息。通过将数据存取详细信息与问题域类分离,这能让我们集中到独立于数据库的问题域类中。分离GUI类、问题域类和数据存取类支持创建松耦合系统组件的目的。松耦合组件有着对其他组件影响最小的情况下对某些组件进行修改。例如,更改系统使用的数据库管理系统将只需要修改数据存取类,而不用修改GUI类或问题域类。同样,修改用户界面将不需要修改数据存取
13、类。因此,三层设计方法更容易维护和增强系统,独立的组件更易于重用。OOA过程的第一步是标识系统范围内的用例。涉及到客户感兴趣的主要事件包括:当客户租赁船台时、当客户购买新船只时等。由于这些事件涉及到客户、船只和船台,因此用例也主要针对客户、船只和船台。例如涉及客户的用例可能包括添加新客户和保留客户信息。当他或她租赁船台时就会添加新客户,每次客户修改地址或电话号码时都保留客户信息。同样,涉及租约的用例包括租赁船台、续签船台租约和转租。涉及船只的用例包括新添新船只和保留船只信息。另外,系统还应保留相关船台和包含船台的码头的有关信息。最后,系统将需要处理查询和报表。如图3所示。图3 Bradshaw
14、 Marina用例图其中,多个场景可与一个用例相关联;而码头一个场景可能是向现有客户出租船台,而另一个场景可能是向新客户出租船台。此外,另一个场景可能是按年度像客户出租船台,其他场景可能是按年度向客户出租船台。在给出涉及现有客户、新客户、年度船台租约和每日船台租约的情况,一个用例的场景最终可能决定如下:(a)按年度向现有客户出租船台(b)按年度向新客户出租船台(c)按日向现有客户出租船台(d)按日向新客户出租船台当标识了用例和场景后,即可研究在用例中涉及到的问题域类。根据该公司的需求,我们可分有客户、船只、租约、船台和码头主要类。首先,关于码头和船台的情况。有时用户会询问有关码头的情况,而且他
15、们有时会谈到船台。其中,Bradshaw Marina将码头定义为船只拥有者在其上行走以达到其船只的整个浮动结构;另一方面,船台被定义为可将船只停泊在此的码头上的一个船位。在这里的船只可连接在一起,这里也是客户租赁的地方。因此,船台不是一种特殊的码头;它是单独与码头相关的事物。这只是一个用来强调了解有关用户及其工作情况的示例。进一步分析初始类。例如,Bradshaw Marina有2钟船只帆船和汽艇;有2种船台:普通的和有顶的;有2种租约:年租约和日租约。这样,对类进行改进以显示将需要继承的一般化/特殊化层次结构,如图4所示。由于船只必须是帆船或汽艇,因此Boat类是一个抽象类,代表它只用来继
16、承。Lease类也是一个抽象类,因为任何租约必须是日租约或年租约。另一方面,船台可以是普通船台,也可以是有顶的船台。有顶的船台是一种特殊的普通船台,因此Slip类是具体类。当继续对问题域建模时,即可开始列出以上各有关类的更为具体的信息内容块-属性。确定所有船只均有state registration number、length、manufacturer和model year。帆船具有其他属性:a keel depth、number of sails和motor type。汽艇具有不同的其他属性:number of engines和fuel type。包含Sailboat和Powerboat子类
17、的原因是因为不同的属性混合在一起。另外,船台用船台号来标识。Bradshaw具有各种宽度和长度的船台,一些船台有顶,而且需要顶的高度。某些有顶的船台有一个门,该门可以关闭以保护船只。帆船不能使用有顶的船台,因为它们的桅杆很高。由于需要用所有的租约来存储租金、起始日期和终止日期,因此这些是Lease类的属性。可以按月支付年租金,而且需要跟踪欠款;日租金必须提前支付,所以不需要用来存储欠款,不过需要知道日租约的天数。其中,年租金和日租金的计算方式不同,年租金基于船台宽度;但日租金基于天数。因此每个租约的calculateFee方法不同且显示为各个子类的方法以显示此不同之处。图4 一般化/特殊化层次
18、结构(继承)的类在确定船只、船台和租约这些类的属性和方法之后,再分析其他类Customer和Dock的属性和方法。通过标识和建模类之间的关联关系即可完成类图。如图5所示,是问题域类的完整类图。其中,该类图中不包含完整的属性和方法,只是包含重要的属性和方法。类与类之间的线代表它们之间有关联,其中“1”表示一个,“1.*”表示多个,“0.1”表示可选的关联。例如,某船只随时可指定给某船台,每个船台可包含一艘船只,因此即使未将船只指定给船台,Bradshaw也可能具有与船只有关的信息;一位客户可以拥有一艘船,但一艘船必须由一位客户拥有,而且必须只由一位客户拥有,因此即使客户尚不拥有船只,客户也可以租
19、赁船台,但Bradshaw可没有保留一艘没有拥有者船只的信息。客户随时可以租赁船台,而且船台随时可以由客户来租赁。Lease类作为客户和船台之间关联的副产品,因此Lease被称为关联类且被附加到带有虚线的关联上。对于序列图和状态图在这就不详加说了。图5 Bradshaw Marina最终的类图3 调试结果在对Bradshaw Marina案例分析之后,按照类图对主要类编写类定义,其中类定义的结构由类头、属性和方法组成。然后就对GUI的开发,提供图形用户界面,以便用户可以输入和显示数据。再对于数据存取进行开发,主要提供数据存储和检索服务,使对象持久性;有2种方法用来达到持久:属性存储和对象存储,
20、属性存储涉及从要使其持久的实例中检索属性值,然后将这些值写入一个文件中;对象存储涉及使用一种称为对象串行化的技术将整个实例写入一个文件中。最后,将问题域、GUI类和数据存取类合并,形成完整的系统模块。调试部分显示图如图6所示。图6(a) 主菜单图6(b) 添加客户yan界面图6(c) 给客户添加船界面图6(d) 寻找客户yan信息界面4 结语以上只是简洁地介绍了面向对象分析(OOA)、面向对象设计(OOD)和面向对象编程(OOP)过程,而实际过程较复杂,还将涉及迭代和应用开发等。本文主要以三层设计方式为基准,并对面向对象分析过程详细分析,特别是对类图的分析;之后,通过用户与GUI类实例交互作用
21、,GUI实例与问题域类实例交互作用,问题域类实例与处理存储和从文件或数据库中检索数据的数据存取类交互作用;最终以图形用户界面形式显示。参考文献:1陈富赞.面向对象模型管理方法的研究及应用J.系统工程理论与实践,1999,11(6):10-13.2E.Reed Doke,John W.Satzinger,Susan Rebstock Williams著,李万红等译.Java面向对象应用程序开发J.北京:清华大学出版社,2003.3罗宣中.手把手教你开发管理信息系统 D.北京清华大学出版社.2003,312 356.4施昊华,张朝辉.UML 面向对象结构设计与应用M.北京: 国防工业出版社, 20
22、03.9.5刘丰,冷英男.基于UML 的一个应用软件建模实例 J .计算机与现代化, 2004, (10) :132 -134.6Joseph Schuler著,李虎等译.UML基础、案例与应用M .北京:人民邮电出版社,2003.附录部分代码:(1)MainMenu.javaimport java.awt.*;import javax.swing.*;import java.awt.event.*;public class MainMenu extends JFrame implements ActionListenerCustomer customers;JButton findCusto
23、merButton,addCustomerButton,closeButton;public MainMenu() Container c=this.getContentPane(); c.setLayout(new GridLayout(2,1); JPanel lowerPanel=new JPanel();/create logo Font defaultFont=c.getFont(); JLabel logoLabel=new JLabel(,SwingConstants.CENTER); logoLabel.setForeground(Color.red); logoLabel.s
24、etFont(new Font(TimesRoman,Font.ITALIC,36); logoLabel.setText(Bradshaw Marina); c.add(logoLabel); findCustomerButton=new JButton(Find a Customer); addCustomerButton=new JButton(Add a Customer); closeButton=new JButton(Close); lowerPanel.add(findCustomerButton); lowerPanel.add(addCustomerButton); low
25、erPanel.add(closeButton); c.add(lowerPanel);/register frame as listener for events addCustomerButton.addActionListener(this); findCustomerButton.addActionListener(this); closeButton.addActionListener(this); this.setSize(300,200); this.setTitle(Main Menu); this.setVisible(true); customers.initialize(
26、); this.addWindowListener ( new WindowAdapter() public void windowClosing(WindowEvent event) shutDown(); ); public void actionPerformed(ActionEvent e) if(e.getSource()=findCustomerButton) findCustomer(); if(e.getSource()=addCustomerButton) addCustomer(); if(e.getSource()=closeButton) shutDown(); pri
27、vate void findCustomer() FindCustomer findCustomerFrame=new FindCustomer(this); findCustomerFrame.setSize(300,200); findCustomerFrame.setTitle(Find A Customer); findCustomerFrame.setVisible(true); this.setVisible(false); private void addCustomer() AddCustomer addCustomerFrame=new AddCustomer(this);
28、addCustomerFrame.setSize(300,200); addCustomerFrame.setTitle(Add A Customer); addCustomerFrame.setVisible(true); this.setVisible(false); public void shutDown()System.exit(0);public static void main(String args)MainMenu frame=new MainMenu();(2)Customer.javaimport java.util.Vector;public class Custome
29、r private String name;private String address;private String phoneNo;private Boat boat; /关联boatstatic Vector customers;public Customer(String aName,String anAddress,String aPhoneNo) setName(aName); setAddress(anAddress); setPhoneNo(aPhoneNo); customers.add(this); public void setName(String newName)na
30、me=newName; public void setAddress(String newAddress)address=newAddress; public void setPhoneNo(String newPhoneNo)phoneNo=newPhoneNo; public void setBoat(Boat aBoat)boat=aBoat;public String getName()return name;public String getAddress()return address;public String getPhoneNo()return phoneNo;public
31、Boat getBoat()return boat;public String tellAboutSelf() String info; info=Cusromer name=+getName()+,Address=+getAddress()+,Phone Number+getPhoneNo();return info; /初始化public static void initialize() customers=new Vector(); Customer aCustomer; aCustomer=new Customer(Eleanor,Atlanta,123-4567); aCustome
32、r=new Customer(Mike,Boston,467-1234); aCustomer=new Customer(John,St.Louis,765-4321); aCustomer=new Customer(Dave,Atlanta,321-4567); aCustomer=new Customer(Brian,Boston,467-1234); aCustomer=new Customer(Dan,St.Louis,587-4321); public static Vector getAll()return customers;/public static void main(St
33、ring args)/System.out.println(customers);(3)Boat.javaimport java.util.Vector;public class Boat private String stateRegistrationNo;private double length;private String manufacturer;private int year;private Customer customer; /添加Customerstatic Vector boats;public Boat(String aStateRegistrationNo,doubl
34、e aLength,String aManufacturer,int aYear) setStateRegistrationNo(aStateRegistrationNo); setLength(aLength); setManufacturer(aManufacturer); setYear(aYear); /关联Boat到Customerpublic void assignBoatToCustomer(Customer aCustomer) setCustomer(aCustomer); customer.setBoat(this); public String tellAboutSelf
35、() String boatDetails; boatDetails=I am Boat stateregnumber+getStateRegistrationNo()+length+getLength ()+Manufacturer+getManufacturer()+Year+getYear(); String customerDetails=n and Owner is+customer.getName()+living in+customer.getAddress()+with phone+customer.getPhoneNo(); return boatDetails+custom
36、erDetails; /set methodspublic void setStateRegistrationNo(String aStateRegistrationNo)stateRegistrationNo=aStateRegistrationNo; public void setLength(double aLength)length=aLength; public void setManufacturer(String aManufacturer)manufacturer=aManufacturer; public void setYear(int aYear)year=aYear;p
37、ublic void setCustomer(Customer aCustomer)customer=aCustomer;/get methodspublic String getStateRegistrationNo()return stateRegistrationNo;public double getLength()return length;public String getManufacturer()return manufacturer;public int getYear()return year;public Customer getCustomer()return cust
38、omer;/添加public static void initialize(Vector customers) boats=new Vector(); Customer aCustomer; Boat aBoat; Sailboat aSailboat; Powerboat aPowerboat; aSailboat=new Sailboat(MO34561,28,Tartan,1998,4.11,2,Diesel); aSailboat=new Sailboat(MO98765,28,J-Boat,1986,5.0,4,Diesel); aSailboat=new Sailboat(MO12
39、345,26,Ranger,1976,74.5,7,Outboard); aPowerboat=new Powerboat(MO445566,30,Bayliner,1996,2,Gas); aPowerboat=new Powerboat(MO223344,28,Tracker,2001,1,Gas); aPowerboat=new Powerboat(MO4567812,19,Ranger,2001,1,Gas); for(int i=0;iboats.size();i+) aCustomer=(Customer)customers.get(i); aBoat=(Boat)boats.ge
40、t(i); aBoat.assignBoatToCustomer(aCustomer); (4)AddCustomer.javaimport java.awt.*;import javax.swing.*;import java.awt.event.*;public class AddCustomer extends JFrame implements ActionListenerMainMenu parentMenu;JTextField customerNameText,customerAddressText,customerPhoneText;JButton addBoatButton,
41、clearButton,closeButton;Customer aCustomer;String customerName,customerAddress,customerPhone;public AddCustomer(MainMenu menu) parentMenu=menu; Container c=this.getContentPane(); c.setLayout(new GridLayout(3,1); JPanel centerPanel=new JPanel(new GridLayout(3,2); JPanel lowerPanel=new JPanel(new Flow
42、Layout(); JLabel logoLabel=new JLabel(,SwingConstants.CENTER); logoLabel.setForeground(Color.red); logoLabel.setFont(new Font(TimesRoman,Font.ITALIC,36); logoLabel.setText(Bradshaw Marina); c.add(logoLabel); customerNameText=new JTextField(); customerAddressText=new JTextField(); customerPhoneText=n
43、ew JTextField(); centerPanel.add(new JLabel(Name:,SwingConstants.RIGHT); centerPanel.add(customerNameText); centerPanel.add(new JLabel(Address:,SwingConstants.RIGHT); centerPanel.add(customerAddressText); centerPanel.add(new JLabel(Phone:,SwingConstants.RIGHT); centerPanel.add(customerPhoneText); c.
44、add(centerPanel); addBoatButton=new JButton(Add Boat); clearButton=new JButton(Clear); closeButton=new JButton(Close); lowerPanel.add(addBoatButton); lowerPanel.add(clearButton); lowerPanel.add(closeButton); c.add(lowerPanel); addBoatButton.addActionListener(this); clearButton.addActionListener(this
45、); closeButton.addActionListener(this); this.setSize(300,200); this.setTitle(Add A Customer); this.setVisible(true); this.addWindowListener ( new WindowAdapter() public void windowClosing(WindowEvent event) shutDown(); ); public void actionPerformed(ActionEvent e) if(e.getSource()=addBoatButton) addCustomer(); if(e.getSource()=clearButton) clearForm(); if(e.getSource()=closeButton) shutDown(); public void addCustomer() AddBoat addBoatWindow=new AddBoat(this,aCustomer); addBoatWindow.setSize(550,350); addBoatWindow.setTitle(Add a Boat for this Customer); addBoatWindow