三层架构

首先我们来看一看用DOS编写一下两个典型程序:

1.计算方程aX2+bX+c=0的解

2.有一个字母"C"从屏幕上方自由下落,当它落到屏幕底部时如果用户按相应的键盘则可以得分,否则不得分

    七十年代以来,随着面向对象的编程思想逐渐深入人心,尤其到了Windows出现以后整个编程思路几乎完全转变到面向对象的方式了。全面的讨论Windows的面向对象的机制可能需要几十万字的叙述,这里我们没有必要了解所有的细节尤其是一些底层的东西,我们只需要了解那些封装好的对象的特性和运作机制-这也恰恰是面向对象的编程方式的最大的优点,大家需要时时记得这一点,我们只需要了解有那些对象,这些对象有那些合理的特性合理的逻辑关系和特殊的运行机制,即对象的属性(Property)、方法(Methord)、事件(Events)。

    其实Windows本身就是一个由许多子窗口对象构成的对象。不妨简单地将窗口看作带有边界的矩形区域。也许已经了解几种不同类型的窗口: 例如: Wlndows95 的“资源管理器”窗口、文字处理程序中的文档窗口或者弹出提示有约会信息的对话框。除了这些最普通的窗口外,实际上还有许多其它类型的窗口。命令按钮是一个窗口。图标、文本框、选项按钮和菜单条也都是窗口。 Microsoft Windows 操作系统通过给每一个窗口指定一个唯一的标识号(窗口句柄或hWnd)来管理所有的窗口。

    操作系统连续地监视每一个窗口的活动或事件的信号。事件可以通过诸如单击鼠标或按下按键的操作而产生,也可以通过程序的控制而产生,甚至可以由另一个窗口的操作而产生。 每发生一次事件,将引发一条消息发送至操作系统。操作系统处理该消息并广播给其它窗口。然后,每一个窗口才能根据自身处理该条消息的指令而采取适当的操作(例如,当窗口解除了其它窗口的覆盖时,重显自身窗口)。 可以想像,处理各种窗口-事件和消息的所有可能的组合将有惊人的工作量。幸运的是, Visual Basic 使您摆脱了所有的低层消息处理。许多消息由Visual Basic自动处理了,其它的作为事件过程由编程者自行处理。这样可以快速创建强大的应用程序而毋需处理不必要的细节。

    事件驱动模型在传统的或“过程化”的应用程序中,应用程序自身控制了执行哪一部分代码和按何种顺序执行代码。从第一行代码执行程序并按应用程序中预定的路径执行, 必要时调用过程。 在事件驱动的应用程序中,代码不是按照预定的路径执行,而是在响应不同的事件时执行不同的代码片段。事件可以由用户操作触发,也可以由来自操作系统或其它应用程序的消息触发,甚至由应用程序本身的消息触发。这些事件的顺序决定了代码执行的顺序,因此应用程序每次运行时所经过的代码的路径都是不同的。 因为事件的顺序是无法预测的,所以在代码中必须对执行时的“各种状态”作一定的假设。当作出某些假设时(例如,假设在运行来处理某一输入字段的过程之 前,该输入字段必须包含确定的值),应该组织好应用程序的结构,以确保该假设始终有效(例如,在输入字段中有值之前禁止使用启动该处理过程的命令按钮)。 在执行中代码也可以触发事件。例如,在程序中改变文本框中的文本将引发文本框的Change事件。如果Change事件中包含有代码,则将导致该代码的执行。 如果原来假设该事件仅能由用户的交互操作所触发,则可能会产生意料之外的结果。正因为这一原因,所以在设计应用程序时理解事件驱动模型并牢记在心是非常重要的。

   Visual Basic 的窗体和控件是具有自己的属性、方法和事件的对象。可以把属性看作一个对象的性质,把方法看作对象的动作,把事件看作对象的响应。日常生活中的对象,如小孩玩的气球同样具有属性、方法和事件。气球的属性包括可以看到的一些性质,如它的直径和颜色。其它一些属性描述气球的状态(充气的或未充气的)或不可见的性质,如它的寿命。通过定义,所有气球都具有这些属性;这些属性也会因气球的不同而不同。
气球还具有本身所固有的方法和动作。如:充气方法(用氦气充满气球的动作),放气方法(排出气球中的气体)和上升方法(放手让气球飞
在ASP.NET中面向对象的编程思想    [ 日期:2004-05-11 ]   [ 来自: ][收藏此页]
首先,我们还是来谈一下面向对象的编程思想吧。我想现在的主流编程思想无非两种:结构与面向对象。以前,在ASP中我们完全采用的是结构化思想。现在,asp.net可以完全支持面向对象的编程思想,这不得不说是一个质上的飞跃。

记得我在大约半年前给大家写过一篇<<面向对象从人造地球谈起>>,当时是由于看到一本小说的启发,发现任何东西都可以用面向对象的思想来看。我现在还是简单谈一下吧,面向对象无非就是把世间万物当做一个类,要想使用类做事,就必须创建类的实例。这很好理简,比方人是一个类,我们总不能说叫人去做事吧(这样没有针对性),我们往往说叫张三 or 李四去,这张三 or 李四就是人这个类的一个实例。这就是对象的概念。再讲一下就是事件与动作,举个例子:起风了,下雨了,收衣服了。起风了,下雨了是事件,这个事件会激发收衣服这个动作,这个动作的执行者就是对象。如果大家学过SQL Server的触发器,我想对这一点思想会更清楚。面向对象还比较重要的就是继承(Inherits)与多态。这很好理解,比方,张三会收衣服,张三生的儿子继承了张三的特点,也会收衣服,这就是继承,而且说不定张三的儿子还会开车,这就是多态。

好了,对于面向对象理解我就说这么一点,还是说一下在asp.net中如何用面向对象的观点来编程吧。我们在编web程序时,通常要要处理:UI(用户界面,也就是数据的显示)与代码(如何处理数据的Code(代码)。为了达到UI与Code的完全分开,我们把UI当作一个对象,Code当作另我一个对象。当然我们要研究这两个对象的关系,还记得我们在编ASP程序时把同一段代码Copy到很多页面,看来code是父类了,UI是子类了。不过他们都是从 System.Web.UI.Page继承过来。理清了类的关系,我们不难理解代码UI与Code分开的思想了。
关系图:
引入名称空间:using System.Web.UI
父类 page→ 很多子类Code(*.cs文件)→很多子子类 UI(*.aspx文件)

因为我主要是想大家了解这种编程思想,所以我只举一个简单的例子,我想大家有了思想,再就是多找实例来看了。

文件两个:
UI类: default.aspx 主要用来显示数据,用天DataGrid控件
Code类: default.aspx.cs 主要用来建立数据联接、查询、绑定数据于DataGrid控件的
        里面我创建了自己的namespace名叫vagrant,以及类MyVagrant
数据库: data,里面有一个关系表student

为了说明default.aspx类是从default.aspx.cs 继承过来的,需要在default.aspx申明:
<%@ Page language="c#" Codebehind="default.aspx.cs" Inherits="vagrant.MyVagrant" %>
Codebehind表明父类的源文件,Inherits="vagrant.MyVagrant" 表明该文件是从哪个类继承下来的。

现在给出源文件
default.aspx代码:

<%@ Page language="c#" Codebehind="default.aspx.cs" Inherits="vagrant.MyVagrant" %>
<HTML>
<HEAD>
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<asp:datagrid id="MyDataGrid" runat="server"
style="Z-INDEX: 101; LEFT: 197px; POSITION: absolute; TOP: 48px"
BorderStyle="Ridge" GridLines="None" BorderWidth="2px" BorderColor="White"
BackColor="White" CellPadding="3" CellSpacing="1" Width="494px" Height="143px">
<HeaderStyle Font-Bold="True" HorizontalAlign="Center" ForeColor="#E7E7FF" VerticalAlign="Middle" BackColor="4A3C8C" />
<ItemStyle HorizontalAlign="Center" ForeColor="Black" VerticalAlign="Middle" BackColor="#DEDFDE" />
</asp:datagrid>
</form>
</body>
</HTML>

default.aspx.cs 文件代码 注意:需要编译
/*
功能说明:default.aspx.cs用来将UI与源代码分开,此为代码部分,需要编译
Created By vagrant
2001.10.17
个人主页:http://www.weavedream.net
*/


//引入必须的名称空间
using System;
using System.Data;
using System.Data.SqlClient; //引入使用SQL数据库所必须的名称空间
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace vagrant //创建自己的名称空间
{

public class MyVagrant :Page //我的类MyVagrant是从类System.Web.UI.Page类继承过来的
{
protected DataGrid MyDataGrid;


private void Page_Load(object sender, System.EventArgs e)//页面装载初始化,可检查页面是不是第一次被处理
{

// 第一步:建立数据库联接,用面向对象的观点就是创建一个SQL数据库联接对象的实例,并初始化
SqlConnection MyConnection=new SqlConnection("Server=(local);DataBase=data;UID=sa;PWD=;");

//第二步:读取数据库,来面向对象的观点就是创建一个查询对象的实例,并初始化
SqlDataAdapter MyCommand=new SqlDataAdapter("select * from student",MyConnection);

//:第三步:存储数据 
DataSet ds=new DataSet();
MyCommand.Fill (ds,"vagrant");
// 第四步:绑定数据
MyDataGrid.DataSource =ds.Tables ["vagrant"].DefaultView
MyDataGrid.DataBind ();

}


}
}

标签:
存储过程和触发器到底是个什么玩意?
 
我在数据库课程里学过存储过程和触发器,但是不知道他们在编程时到底用来做什么?

最佳答案
存储过程相当于打包好的sql语法,可以包含复杂的sql操作,在程序调用时只要执行该存储过程,一句话就可以完成复杂的数据库操作.
触发器是也是打包好的sql语法,只不过执行它的条件是当被设定改触发器的表有变化的时候.比如我可以写一个触发器,设定它在插入一笔数据到这个表里的时候,去同步另一个表.那么在程序里我只要做到往数据库里插一笔数据,那么另一个表就可以同时被更新.
用存储过程和数据库的好处是,可以充分利用数据库资源,减少程序代码,程序员的工作将更简便,写出来的代码也更简洁明了.当然要真正明白程序在做什么,还是要到存储过程和触发器里面看明白.
呵呵,这些都是本人自身体会,你可以有选择的看看.


提问者对于答案的评价:
说的都不错,我就是要那种通俗易懂的解释,这样才能解决我的困惑,这个答案比较通俗易懂
评价已经被关闭 目前有 1 个人评价
     好
100% (1) 不好
0% (0)

其他回答共 1 条
触发器是一种特殊类型的存储过程。主要是通过事件进行触发而被执行的,而存储过程可以通过存储过程名字而被直接调用。当对某一表进行诸如UPDATE、 INSERT、 DELETE 这些操作时,SQL Server 就会自动执行触发器所定义的SQL 语句,从而确保对数据的处理必须符合由这些SQL 语句所定义的规则。
触发器的主要作用就是其能够实现由主键和外键所不能保证的复杂的参照完整性和数据的一致性。除此之外,触发器还有其它许多不同的功能:
(1) 强化约束(Enforce restriction)
触发器能够实现比CHECK 语句更为复杂的约束。

(2) 跟踪变化Auditing changes
触发器可以侦测数据库内的操作,从而不允许数据库中未经许可的指定更新和变化。

(3) 级联运行(Cascaded operation)。
触发器可以侦测数据库内的操作,并自动地级联影响整个数据库的各项内容。例如,某个表上的触发器中包含有对另外一个表的数据操作(如删除,更新,插入)而该操作又导致该表上触发器被触发。
(4) 存储过程的调用(Stored procedure invocation)。
为了响应数据库更新触,发器可以调用一个或多个存储过程,甚至可以通过外部过程的调用而在DBMS( 数据库管理系统)本身之外进行操作。
由此可见,触发器可以解决高级形式的业务规则或复杂行为限制以及实现定制记录等一些方面的问题。例如,触发器能够找出某一表在数据修改前后状态发生的差异,并根据这种差异执行一定的处理。此外一个表的同一类型(INSERT、 UPDATE、 DELETE)的多个触发器能够对同一种数据操作采取多种不同的处理。
总体而言,触发器性能通常比较低。当运行触发器时,系统处理的大部分时间花费在参照其它表的这一处理上,因为这些表既不在内存中也不在数据库设备上,而删除表和插入表总是位于内存中。可见触发器所参照的其它表的位置决定了操作要花费的时间长短。

第7章  存储过程和触发器

主要知识点:存储过程类型;存储过程的创建、执行、修改和删除;触发器概述;触发器的创建、修改和删除
教学目的:了解存储过程类型;了解触发器;掌握存储过程和触发器的创建、修改和删除
重点:存储过程和触发器的创建
难点:利用T-SQL语言创建存储过程和触发器
教学学时:8学时
教学形式与手段:4学时多媒体教学+4学时实践
教学内容:

7.1存储过程
存储过程是一种数据库对象,将执行计划存储在数据库的服务器中。它的运行速度比独立运行同样的程序要快。
7.1.1存储过程类型
1、系统存储过程
存储在master数据库中,以sp_为前缀。可以在其他数据库中对其进行调用。
2、用户自定义存储过程
由用户创建并能完成某一特定功能的存储过程。或称本地存储过程。包括临时存储
过程、远程存储过程、扩展存储过程。
临时存储过程又包括局部的和全局的临时存储过程,前者在过程名的前面带#,后者
在过程名的前面带##。全局临时存储过程对所有用户都可见。
     扩展存储过程的前缀是xp_ 。 
7.1.2创建存储过程
存储过程的三个组成部分:
(1)所有的输入参数以及传给调用者的输出参数;
(2)被执行的针对数据库的操作语句,包括调用其他存储过程的语句;
(3)返回给调用者的状态值,以指明调用是成功还是失败。
 1、T-SQL创建存储过程的基本语法格式:
CREATE   PROC[EDURE]  存储过程名称  参数定义
AS  SQL语句
例7.1创建存储过程,实现查询所有学生信息的功能。
Create proc  proc_7_1
As
Select  *   From  xsqk
思考:创建存储过程,实现查询所有学生的学号、姓名、所选课程号、课程名、成绩及学分信息的功能。

例7.2创建存储过程proc_7_2,要求实现根据学生学号,产生不同结果,如果该学生信息不存在,则显示“无此学号的学生!”,否则返回该学生的基本信息。
Create   proc   proc_7_2
@sno  char(8)
As
If exists(Select *  From  xsqk  where  学号= @sno)
select  *  From  xsqk   where   学号= @sno
Else
print  ‘无此学号的学生!’
思考:创建存储过程testproc2,实现根据学生的学号,查询此学生的学号、姓名、所选课程号、课程名、成绩及学分等信息。
说明:
(1)在一个批处理中,Create procedure语句不能与其他SQL语句合并在一起。
(2)数据库所有者具有默认的创建存储过程的权限。
(3)存储过程作为数据库对象其命名必须符合命名规则。
(4)只能在当前数据库中创建属于当前数据库的存储过程。
(5)一个存储过程的最大尺寸为128M。
7.1.3执行存储过程
语句格式:
EXECUTE   存储过程名称  参数值
例7.3执行例7.1的存储过程。
exec   proc_7_1
例7.4执行例7.2的存储过程,查询学号为“02020101”学生的基本信息。
exec   proc_7_2    ‘02020101’
或  exec  proc_7_2   @sno= ‘02020101’
例7.5在学生成绩库中创建存储过程proc_7_t1,要求实现如下功能:产生计算机0203班学生的选课情况列表,其中包括学号、姓名、性别、课程号、课程名称、学分等。并调用此存储过程,显示执行结果。
create proc  proc_7_t1
as
Select  xsqk.学号, 姓名, 性别, xskc.课程号, 课程名, xskc.学分
    From  xsqk, xscj, xskc
    Where  xsqk.学号 = xscj.学号
     and  xscj.课程号 = xskc.课程号
        and  班级 = ‘计算机0203’
例7.6在学生成绩库中创建存储过程proc_7_t2,要求实现如下功能:根据学生学号,如果此学生存在,则产生该生的课程成绩列表,其中包括学号、课程号、课程名称、成绩、学分等;如果此学生不存在,则显示“无此学生!”。并调用此存储过程,显示“02020101”学生的课程成绩情况。
create proc  proc_7_t2    @sno  char(8)
as
if  exists(select  * from  xsqk  where  学号=@sno
       Select  学号, xscj.课程号, 课程名, 成绩, xskc.学分
       From  xscj, xskc
       Where  xscj.课程号 = xskc.课程号
        and  学号= @sno
   else
     print   ‘无此学生!’
7.1.4修改存储过程
语法格式:
ALTER   PROCEDURE   存储过程名称  参数定义
AS SQL语句
例7.7修改在例7.5中已创建的存储过程proc_7_t1,要求在显示列中加入成绩列。
alter proc  proc_7_t1
as
Select  xsqk.学号, 姓名, 性别, xskc.课程号, 课程名,
           xskc.学分,  成绩
    From  xsqk, xscj, xskc
    Where  xsqk.学号 = xscj.学号
     and  xscj.课程号 = xskc.课程号
        and  班级 = ‘计算机0203’
7.1.5删除存储过程
语法格式:
DROP   PROC[EDURE]   存储过程名称
例7.8删除存储过程proc_7_1。
drop  proc   proc_7_1
一般地,在用T-SQL命令创建存储过程时,总是先确定要创建的存储过程是否已经存在,如果存在,那么就删除重建。我们可以用如下语句实现:
If   exists( select  name   from   sysobjects
           where  name = ‘proc_7_1’   and   type = ‘P’)
     drop  proc  proc_7_1
7.2触发器
触发器是一种特殊类型的存储过程,当表中数据被修改时,SQL Server自动执行触发器中定义的T-SQL语句。使用触发器可以实施更为复杂的数据完整性约束。
7.2.1触发器概述
触发器的概念及作用
触发器是一种特殊类型的存储过程,主要通过事件进行触发执行的。
主要作用:实现由主键和外键所不能保证的参照完整性和数据的一致性;强化约束;跟踪变化;级联运行;存储过程的调用。
触发器的种类
AFTER触发器  只有对表执行某一操作这后,才能被触发。可以为表的同一操作定义多个触发器,其触发次序可使用sp_settriggerorder来完成。
INSTEAD OF触发器  并不执行其所定义的操作而仅是执行触发器本身,对同一操作只能定义一个instead of 触发器。
INSERTED和DELETED临时表
触发器代码最强大的功能之一是能够比较记录的新旧版本,用户可以根据记录的改变适时地做出决定。
插入一行时,INSERTED表保存了一份插入行的拷贝。
删除一行时,DELETED表保存了删除行的拷贝。
更新一行时,INSERTED表中保存了一份新行的拷贝,
                DELETED表中保存了一份旧行的拷贝。
可以使用这两个临时的驻留内存的表测试某些数据修改的效果及设置触发器操作的条件,便不能直接对这两个临时表中的数据进行更改。
7.2.2创建触发器
用T-SQL命令创建
语法格式:
CREATE TRIGGER  触发器名称
ON  表或视图
{ FOR | AFTER | INSTEAD OF }
{[DELETE],[INSERT],[UPDATE]}
AS  SQL语句  

CTEATE TRIGGER 语句必须是批处理的第一个语句;
表的所有者具有创建触发器的默认权限,表的所有者不能把该权限传给其他用户;
  触发器是数据库对象,其命名必须符合命名规则。
  尽管在触发器的SQL语句中可以参照其他数据库中的对象,但是,触发器只能创建在当前数据库中。
一个触发器只能对应一个表,这是由触发器的机制决定的。
7.2.3修改触发器
1、修改触发器的名字
sp_rename   触发器原名称,新名称
2、修改触发器正文
使用T-SQL命令
语法格式:ALTER   TRIGGER   触发器名称
                  ON  表或视图
                  { FOR | AFTER | INSTEAD OF }
                  {[DELETE],[INSERT],[UPDATE]}
                  AS  SQL语句
7.2.4删除触发器
语法格式:
DROP   TRIGGER   触发器名称
如果删除触发器所在的表时,系统将自动删除与该表相关的触发器。

习题:
1、 学生成绩管理数据库中创建一个无参的存储过程实现以下功能:将至少有一门课成绩不及格的学生的学号和姓名查找出来。并执行该存储过程。
2、 学生情况表(xsqk)中创建触发器xsqk_trigger1,实现如下功能:当在学生情况表(xsqk)
中输入一个学生的记录时,根据学生课程表(xskc)中已存在的所有课程,自动在学生成绩表(xscj)中生成该生所有课程的初始记录,成绩栏为0,学分为该课程在学生课程表(xskc)中的学分。

 


面向对象的编程思想:最新李建


----------------------------------------------------------
面向对象(Object Oriented,OO)是当前计算机界关心的重点,它是90年代软件开发方法的主流。面向对象的概念和应用已超越了程序设计和软件开发,扩展到很宽的范围。如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。 谈到面向对象,这方面的文章非常多。但是,明确地给出对象的定义或说明对象的定义的非常少——至少我现在还没有发现。其初,“面向对象”是专指在程序设计中采用封装、继承、抽象等设计方法。可是,这个定义显然不能再适合现在情况。面向对象的思想已经涉及到软件开发的各个方面。如,面向对象的分析(OOA,object Oriented Analysis),面向对象的设计(OOD,ObjECt Oriented DESign)、以及我们经常说的面向对象的编程实现(OOP,Object Oriented Programming)。许多有关面向对象的文章都只是讲述在面向对象的开发中所需要注意的问题或所采用的比较好的设计方法。看这些文章只有真正懂得什么是对象,什么是面向对象,才能最大程度地对自己有所裨益。这一点,恐怕对初学者甚至是从事相关工作多年的人员也会对它们的概念模糊不清。 面向对象是当前计算机界关心的重点,它是90年代软件开发方法的主流。面向对象的概念和应用已超越了程序设计和软件开发,扩展到很宽的范围。如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。 一、传统开发方法存在问题 1.软件重用性差 重用性是指同一事物不经修改或稍加修改就可多次重复使用的性质。软件重用性是软件工程追求的目标之一。 2.软件可维护性差 软件工程强调软件的可维护性,强调文档资料的重要性,规定最终的软件产品应该由完整、一致的配置成分组成。在软件开发过程中,始终强调软件的可读性、可修改性和可测试性是软件的重要的质量指标。实践证明,用传统方法开发出来的软件,维护时其费用和成本仍然很高,其原因是可修改性差,维护困难,导致可维护性差。 3.开发出的软件不能满足用户需要 用传统的结构化方法开发大型软件系统涉及各种不同领域的知识,在开发需求模糊或需求动态变化的系统时,所开发出的软件系统往往不能真正满足用户的需要。 用结构化方法开发的软件,其稳定性、可修改性和可重用性都比较差,这是因为结构化方法的本质是功能分解,从代表目标系统整体功能的单个处理着手,自顶向下不断把复杂的处理分解为子处理,这样一层一层的分解下去,直到仅剩下若干个容易实现的子处理功能为止,然后用相应的工具来描述各个最低层的处理。因此,结构化方法是围绕实现处理功能的“过程”来构造系统的。然而,用户需求的变化大部分是针对功能的,因此,这种变化对于基于过程的设计来说是灾难性的。用这种方法设计出来的系统结构常常是不稳定的 ,用户需求的变化往往造成系统结构的较大变化,从而需要花费很大代价才能实现这种变化。 二、面向对象的基本概念 (1)对象。 对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。 (2)对象的状态和行为。 对象具有状态,一个对象用数据值来描述它的状态。 对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为。 对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中 (3)类。 具有相同或相似性质的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象。 类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。 类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。 (4)类的结构。 在客观世界中有若干类,这些类之间有一定的结构关系。通常有两种主要的结构关系,即一般--具体结构关系,整体--部分结构关系。 ①一般——具体结构称为分类结构,也可以说是“或”关系,或者是“is a”关系。 ②整体——部分结构称为组装结构,它们之间的关系是一种“与”关系,或者是“hAS a”关系。 (5)消息和方法。 对象之间进行通信的结构叫做消息。在对象的操作中,当一个消息发送给某个对象时,消息包含接收对象去执行某种操作的信息。发送一条消息至少要包括说明接受消息的对象名、发送给该对象的消息名(即对象名、方法名)。一般还要对参数加以说明,参数可以是认识该消息的对象所知道的变量名,或者是所有对象都知道的全局变量名。 类中操作的实现过程叫做方法,一个方法有方法名、参数、方法体。消息传递如图10-1所示。 二、面向对象的特征 (1)对象唯一性。 每个对象都有自身唯一的标识,通过这种标识,可找到相应的对象。在对象的整个生命期中,它的标识都不改变,不同的对象不能有相同的标识。 (2)分类性。 分类性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。 (3)继承性。 继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。 继承性是面向对象程序设计语言不同于其它语言的最重要的特点,是其他语言所没有的。 在类层次中,子类只继承一个父类的数据结构和方法,则称为单重继承。 在类层次中,子类继承了多个父类的数据结构和方法,则称为多重继承。 在软件开发中,类的继承性使所建立的软件具有开放性、可扩充性,这是信息组织与分类的行之有效的方法,它简化了对象、类的创建工作量,增加了代码的可重性。 采用继承性,提供了类的规范的等级结构。通过类的继承关系,使公共的特性能够共享,提高了软件的重用性。 (4)多态性(多形性) 多态性使指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。 多态性允许每个对象以适合自身的方式去响应共同的消息。 多态性增强了软件的灵活性和重用性。 三、面向对象的要素 (1)抽象。 抽象是指强调实体的本质、内在的属性。在系统开发中,抽象指的是在决定如何实现对象之前的对象的意义和行为。使用抽象可以尽可能避免过早考虑一些细节。 类实现了对象的数据(即状态)和行为的抽象。 (2)封装性(信息隐藏)。 封装性是保证软件部件具有优良的模块性的基础。 面向对象的类是封装良好的模块,类定义将其说明(用户可见的外部接口)与实现(用户不可见的内部实现)显式地分开,其内部实现按其具体定义的作用域提供保护。 对象是封装的最基本单位。封装防止了程序相互依赖性而带来的变动影响。面向对象的封装比传统语言的封装更为清晰、更为有力。 (3)共享性 面向对象技术在不同级别上促进了共享 同一类中的共享。同一类中的对象有着相同数据结构。这些对象之间是结构、行为特征的共享关系。 在同一应用中共享。在同一应用的类层次结构中,存在继承关系的各相似子类中,存在数据结构和行为的继承,使各相似子类共享共同的结构和行为。使用继承来实现代码的共享,这也是面向对象的主要优点之一。 在不同应用中共享。面向对象不仅允许在同一应用中共享信息,而且为未来目标的可重用设计准备了条件。通过类库这种机制和结构来实现不同应用中的信息共享。 4.强调对象结构而不是程序结构 四、面向对象的开发方法 目前,面向对象开发方法的研究已日趋成熟,国际上已有不少面向对象产品出现。面向对象开发方法有Coad方法、BOoch方法和OMT方法等。 1.Booch方法 Booch最先描述了面向对象的软件开发方法的基础问题,指出面向对象开发是一种根本不同于传统的功能分解的设计方法。面向对象的软件分解更接近人对客观事务的理解,而功能分解只通过问题空间的转换来获得。 2.Coad方法 Coad方法是1989年Coad和YouRDOn提出的面向对象开发方法。该方法的主要优点是通过多年来大系统开发的经验与面向对象概念的有机结合,在对象、结构、属性和操作的认定方面,提出了一套系统的原则。该方法完成了从需求角度进一步进行类和类层次结构的认定。尽管Coad方法没有引入类和类层次结构的术语,但事实上已经在分类结构、属性、操作、消息关联等概念中体现了类和类层次结构的特征。 3.OMT方法 OMT方法是1991年由JAMes Rumbaugh等5人提出来的,其经典著作为“面向对象的建模与设计”。 该方法是一种新兴的面向对象的开发方法,开发工作的基础是对真实世界的对象建模,然后围绕这些对象使用分析模型来进行独立于语言的设计,面向对象的建模和设计促进了对需求的理解,有利于开发得更清晰、更容易维护的软件系统。该方法为大多数应用领域的软件开发提供了一种实际的、高效的保证,努力寻求一种问题求解的实际方法。 4.UML(Unified Modeling Language)语言 软件工程领域在1995年~1997年取得了前所未有的进展,其成果超过软件工程领域过去15年的成就总和,其中最重要的成果之一就是统一建模语言(UML)的出现。UML将是面向对象技术领域内占主导地位的标准建模语言。 UML不仅统一了Booch方法、OMT方法、OOSE方法的表示方法,而且对其作了进一步的发展,最终统一为大众接受的标准建模语言。UML是一种定义良好、易于表达、功能强大且普遍适用的建模语言。它融入了软件工程领域的新思想、新方法和新技术。它的作用域不限于支持面向对象的分析与设计,还支持从需求分析开始的软件开发全过程。 五、面向对象的模型 ·对象模型 对象模型表示了静态的、结构化的系统数据性质,描述了系统的静态结构,它是从客观世界实体的对象关系角度来描述,表现了对象的相互关系。该模型主要关心系统中对象的结构、属性和操作,它是分析阶段三个模型的核心,是其他两个模型的框架。 1.对象和类 (1) 对象。 对象建模的目的就是描述对象。 (2) 类。 通过将对象抽象成类,我们可以使问题抽象化,抽象增强了模型的归纳能力。 (3) 属性。 属性指的是类中对象所具有的性质(数据值)。 (4) 操作和方法。 操作是类中对象所使用的一种功能或变换。类中的各对象可以共享操作,每个操作都有一个目标对象作为其隐含参数。 方法是类的操作的实现步骤。 2.关联和链 关联是建立类之间关系的一种手段,而链则是建立对象之间关系的一种手段。 (1) 关联和链的含义。 链表示对象间的物理与概念联结,关联表示类之间的一种关系,链是关联的实例,关联是链的抽象。 (2) 角色。 角色说明类在关联中的作用,它位于关联的端点。 (3) 受限关联。 受限关联由两个类及一个限定词组成,限定词是一种特定的属性,用来有效的减少关联的重数,限定词在关联的终端对象集中说明。 限定提高了语义的精确性,增强了查询能力,在现实世界中,常常出现限定词。 (4) 关联的多重性。 关联的多重性是指类中有多少个对象与关联的类的一个对象相关。重数常描述为“一”或“多”。 图10-8表示了各种关联的重数。小实心圆表示“多个”,从零到多。小空心圆表示零或一。没有符号表示的是一对一关联。 3.类的层次结构 (1) 聚集关系。 聚集是一种“整体-部分”关系。在这种关系中,有整体类和部分类之分。聚集最重要的性质是传递性,也具有逆对称性。 聚集可以有不同层次,可以把不同分类聚集起来得到一颗简单的聚集树,聚集树是一种简单表示,比画很多线来将部分类联系起来简单得多,对象模型应该容易地反映各级层次,图10-10表示一个关于微机的多极聚集。 (2)一般化关系。 一般化关系是在保留对象差异的同时共享对象相似性的一种高度抽象方式。它是“一般---具体”的关系。一般化类称为你类,具体类又能称为子类,各子类继承了交类的性质,而各子类的一些共同性质和操作又归纳到你类中。因此,一般化关系和继承是同时存在的。一般化关系的符号表示是在类关联的连线上加一个小三角形,如图10-11 4.对象模型 (1)模板。模板是类、关联、一般化结构的逻辑组成。 (2)对象模型。 对象模型是由一个或若干个模板组成。模板将模型分为若干个便于管理的子块,在整个对象模型和类及关联的构造块之间,模板提供了一种集成的中间单元,模板中的类名及关联名是唯一的。 ·动态模型 动态模型是与时间和变化有关的系统性质。该模型描述了系统的控制结构,它表示了瞬间的、行为化的系统控制性质,它关心的是系统的控制,操作的执行顺序,它表示从对象的事件和状态的角度出发,表现了对象的相互行为。该模型描述的系统属性是触发事件、事件序列、状态、事件与状态的组织。使用状态图作为描述工具。它涉及到事件、状态、操作等重要概念。 1.事件 事件是指定时刻发生的某件事。 2.状态 状态是对象属性值的抽象。对象的属性值按照影响对象显著行为的性质将其归并到一个状态中去。状态指明了对象对输入事件的响应。 3.状态图 状态图是一个标准的计算机概念,他是有限自动机的图形表示,这里把状态图作为建立动态模型的图形工具。 状态图反映了状态与事件的关系。当接收一事件时,下一状态就取决于当前状态和所接收的该事件,由该事件引起的状态变化称为转换。 状态图是一种图,用结点表示状态,结点用圆圈表示;圆圈内有状态名,用箭头连线表示状态的转换,上面标记事件名,箭头方向表示转换的方向。 ·功能模型 功能模型描述了系统的所有计算。功能模型指出发生了什么,动态模型确定什么时候发生,而对象模型确定发生的客体。功能模型表明一个计算如何从输入值得到输出值,它不考虑计算的次序。功能模型由多张数据流图组成。数据流图用来表示从源对象到目标对象的数据值的流向,它不包含控制信息,控制信息在动态模型中表示,同时数据流图也不表示对象中值的组织,值的组织在对象模型中表示。图10-15给出了一个窗口系统的图标显示的数据流图。 数据流图中包含有处理、数据流、动作对象和数据存储对象。 1.处理 数据流图中的处理用来改变数据值。最低层处理是纯粹的函数,一张完整的数据流图是一个高层处理。 2.数据流 数据流图中的数据流将对象的输出与处理、处理与对象的输入、处理与处理联系起来。在一个计算机中,用数据流来表示一中间数据值,数据流不能改变数据值。 3.动作对象 动作对象是一种主动对象,它通过生成或者使用数据值来驱动数据流图。 4.数据存储对象 数据流图中的数据存储是被动对象,它用来存储数据。它与动作对象不一样,数据存储本身不产生任何操作,它只响应存储和访问的要求。 六、面向对象的分析 面向对象分析的目的是对客观世界的系统进行建模。本节以上面介绍的模型概念为基础,结合“银行网络系统”的具体实例来构造客观世界问题的准确、严密的分析模型。 分析模型有三种用途:用来明确问题需求;为用户和开发人员提供明确需求;为用户和开发人员提供一个协商的基础,作为后继的设计和实现的框架。 (一) 面向对象的分析 系统分析的第一步是:陈述需求。分析者必须同用户一块工作来提炼需求,因为这样才表示了用户的真实意图,其中涉及对需求的分析及查找丢失的信息。下面以“银行网络系统”为例,用面向对象方法进行开发。银行网络系统问题陈述: 设计支持银行网络的软件,银行网络包括人工出纳站和分行共享的自动出纳机。每个分理处用分理处计算机来保存各自的帐户,处理各自的事务;各自分理处的出纳站与分理处计算机通信,出纳站录入帐户和事务数据;自动出纳机与分行计算机通信,分行计算机与拨款分理处结帐,自动出纳机与用户接口接受现金卡,与分行计算机通信完成事务,发放现金,打印收据;系统需要记录保管和安全措施;系统必须正确处理同一帐户的并发访问;每个分处理为自己的计算机准备软件,银行网络费用根据顾客和现金卡的数目分摊给各分理处。图10-18给出银行网络系统的示意图。 (二)建立对象模型 首先标识和关联,因为它们影响了整体结构和解决问题的方法,其次是增加属性,进一步描述类和关联的基本网络,使用继承合并和组织类,最后操作增加到类中去作为构造动态模型和功能模型的副产品。 1.确定类 构造对象模型的第一步是标出来自问题域的相关的对象类,对象包括物理实体和概念。所有类在应用中都必须有意义,在问题陈述中,并非所有类都是明显给出的。有些是隐含在问题域或一般知识中的。 按图10-19所示的过程确定类 查找问题陈述中的所有名词,产生如下的暂定类。 软件 银行网络 出纳员 自动出纳机 分行 分处理 分处理计算机 帐户 事务 出纳站 事务数据 分行计算机 现金卡 用户 现金 收据 系统 顾客 费用 帐户数据 访问 安全措施 记录保管 根据下列标准,去掉不必要的类和不正确的类。 (1) 冗余类:若两个类表述了同一个信息 ,保留最富有描述能力的类。如"用户"和"顾客"就是重复的描述,因为"顾客"最富有描述性,因此保留它。 (2) 不相干的类:除掉与问题没有关系或根本无关的类。例如,摊派费用超出了银行网络的范围。 (3) 模糊类:类必须是确定的,有些暂定类边界定义模糊或范围太广,如"记录保管"就模糊类,它是"事务"中的一部分。 (4) 属性:某些名词描述的是其他对象的属性,则从暂定类中删除。如果某一性质的独立性很重要,就应该把他归属到类,而不把它作为属性。 (5) 操作:如果问题陈述中的名词有动作含义,则描述的操作就不是类。但是具有自身性质而且需要独立存在的操作应该描述成类。如我们只构造电话模型,"拨号"就是动态模型的一部分而不是类,但在电话拨号系统中,"拨号"是一个重要的类,它日期、时间、受话地点等属性。 在银行网络系统中,模糊类是"系统"、"安全措施"、"记录保管"、"银行网络"等。属于属性的有:"帐户数据"、"收据"、"现金"、"事务数据"。属于实现的如:"访问"、"软件"等。这些均应除去。 2.准备数据字典 为所有建模实体准备一个数据字典。准确描述各个类的精确含义,描述当前问题中的类的范围,包括对类的成员、用法方面的假设或限制。 3.确定关联 两个或多个类之间的相互依赖就是关联。一种依赖表示一种关联,可用各种方式来实现关联,但在分析模型中应删除实现的考虑,以便设计时更为灵活。关联常用描述性动词或动词词组来表示,其中有物理位置的表示、传导的动作、通信、所有者关系、条件的满足等。从问题陈述中抽取所有可能的关联表述,把它们记下来,但不要过早去细化这些表述。 下面是银行网络系统中所有可能的关联,大多数是直接抽取问题中的动词词组而得到的。在陈述中,有些动词词组表述的关联是不明显的。最后,还有一些关联与客观世界或人的假设有关,必须同用户一起核实这种关联,因为这种关联在问题陈述中找不到。 银行网络问题陈述中的关联: ·银行网络包括出纳站和自动出纳机; ·分行共享自动出纳机; ·分理处提供分理处计算机; ·分理处计算机保存帐户; ·分理处计算机处理帐户支付事务; ·分理处拥有出纳站; ·出纳站与分理处计算机通信; ·出纳员为帐户录入事务; ·自动出纳机接受现金卡; ·自动出纳机与用户接口; ·自动出纳机发放现金; ·自动出纳机打印收据; ·系统处理并发访问; ·分理处提供软件; ·费用分摊给分理处。 隐含的动词词组: ·分行由分理处组成; ·分理处拥有帐户; ·分行拥有分行计算机; ·系统提供记录保管; ·系统提供安全; ·顾客有现金卡。 基于问题域知识的关联: ·分理处雇佣出纳员; ·现金卡访问帐户。 使用下列标准去掉不必要和不正确的关联: (1) 若某个类已被删除,那么与它有关的关联也必须删除或者用其它类来重新表述。在例中,我们删除了"银行网络",相关的关联也要删除。 (2) 不相干的关联或实现阶段的关联:删除所有问题域之外的关联或涉及实现结构中的关联。如"系统处理并发访问"就是一种实现的概念。 (3) 动作:关联应该描述应用域的结构性质而不是瞬时事件,因此应删除"自动出纳机接受现金卡","自动出纳机与用户接口"等。 (4) 派生关联:省略那些可以用其他关联来定义的关联。因为这种关联是冗余的。银行网络系统的初步对象图如图10-20所示。其中含有关联。 4.确定属性 属性是个体对象的性质,属性通常用修饰性的名词词组来表示.形容词常常表示具体的可枚举的属性值,属性不可能在问题陈述中完全表述出来,必须借助于应用域的知识及对客观世界的知识才可以找到它们。只考虑与具体应用直接相关的属性,不要考虑那些超出问题范围的属性。首先找出重要属性,避免那些只用于实现的属性,要为各个属性取有意义的名字。按下列标准删除不必要的和不正确的属性: (1) 对象:若实体的独立存在比它的值重要,那么这个实体不是属性而是对象。如在邮政目录中,"城市"是一个属性,然而在人口普查中,"城市"则被看作是对象。在具体应用中,具有自身性质的实体一定是对象。 (2) 定词:若属性值取决于某种具体上下文,则可考虑把该属性重新表述为一个限定词。 (3) 名称:名称常常作为限定词而不是对象的属性,当名称不依赖于上下文关系时,名称即为一个对象属性,尤其是它不惟一时。 (4) 标识符:在考虑对象模糊性时,引入对象标识符表示,在对象模型中不列出这些对象标识符,它是隐含在对象模型中,只列出存在于应用域的属性。 (5) 内部值:若属性描述了对外不透明的对象的内部状态,则应从对象模型中删除该属性。 (6) 细化:忽略那些不可能对大多数操作有影响的属性。 5.使用继承来细化类 使用继承来共享公共机构,以次来组织类,可以用两种方式来进行。 (1) 自底向上通过把现有类的共同性质一般化为父类,寻找具有相似的属性,关系或操作的类来发现继承。例如"远程事务"和"出纳事务"是类似的,可以一般化为"事务"。有些一般化结构常常是基于客观世界边界的现有分类,只要可能,尽量使用现有概念。对称性常有助于发现某些丢失的类。 (2) 自顶向下将现有的类细化为更具体的子类。具体化常常可以从应用域中明显看出来。应用域中各枚举字情况是最常见的具体化的来源。例如:菜单,可以有固定菜单,顶部菜单,弹出菜单,下拉菜单等,这就可以把菜单类具体细化为各种具体菜单的子类。当同一关联名出现多次且意义也相同时,应尽量具体化为相关联的类,例如"事务"从"出纳站"和"自动出纳机"进入,则"录入站"就是"出纳站"和"自动出纳站"的一般化。在类层次中,可以为具体的类分配属性和关联。各属性和都应分配给最一般的适合的类,有时也加上一些修正。 应用域中各枚举情况是最常见的具体化的来源。 6.完善对象模型 对象建模不可能一次就能保证模型是完全正确的,软件开发的整个过程就是一个不断完善的过程。模型的不同组成部分多半是在不同的阶段完成的,如果发现模型的缺陷,就必须返回到前期阶段去修改,有些细化工作是在动态模型和功能模型完成之后才开始进行的。 (1) 几种可能丢失对象的情况及解决办法: ·同一类中存在毫无关系的属性和操作,则分解这个类,使各部分相互关联; ·一般化体系不清楚,则可能分离扮演两种角色的类 ·存在无目标类的操作,则找出并加上失去目标的类; ·存在名称及目的相同的冗余关联,则通过一般化创建丢失的父类,把关联组织在一起。 (2) 查找多余的类。 类中缺少属性,操作和关联,则可删除这个类。 (3)查找丢失的关联。 丢失了操作的访问路径,则加入新的关联以回答查询。 (4) 网络系统的具体情况作如下的修改: ①现金卡有多个独立的特性。把它分解为两个对象:卡片权限和现金卡。 a.卡片权限:它是银行用来鉴别用户访问权限的卡片,表示一个或多个用户帐户的访问权限;各个卡片权限对象中可能具有好几个现金卡,每张都带有安全码,卡片码,它们附在现金卡上,表现银行的卡片权限。 b.现金卡:它是自动出纳机得到表示码的数据卡片,它也是银行代码和现金卡代码的数据载体。 ②"事务"不能体现对帐户之间的传输描述的一般性,因它只涉及一个帐户,一般来说,在每个帐户中,一个"事务"包括一个或多个"更新",一个"更新"是对帐户的一个动作,它们是取款,存款,查询之一。一个"更新"中所有"更新"应该是一个原子操作。 ③"分理处"和"分离处理机"之间,"分行"和"分行处理机"之间的区别似乎并不影响分析,计算机的通信处理实际上是实现的概念,将"分理处计算机"并入到"分理处",将"分行计算机"并入到"分行"。 (三)建立动态模型 1.准备脚本 动态分析从寻找事件开始,然后确定各对象的可能事件顺序。在分析阶段不考虑算法的执行,算法是实现模型的一部分。 2.确定事件 确定所有外部事件。事件包括所有来自或发往用户的信息、外部设备的信号、输入、转换和动作,可以发现正常事件,但不能遗漏条件和异常事件。 3.准备事件跟踪表 把脚本表示成一个事件跟踪表,即不同对象之间的事件排序表,对象为表中的列,给每个对象分配一个独立的列。 4.构造状态图 对各对象类建立状态图,反映对象接收和发送的事件,每个事件跟踪都对应于状态图中一条路径。 (四)建立功能建模 功能模型用来说明值是如何计算的,表明值之间的依赖关系及相关的功能,数据流图有助于表示功能依赖关系,其中的处理应于状态图的活动和动作,其中的数据流对应于对象图中的对象或属性。 1.确定输入值、输出值 先列出输入、输出值,输入、输出值是系统与外界之间的事件的参数。 2.建立数据流图 数据流图说明输出值是怎样从输入值得来的,数据流图通常按层次组织。 (五)确定操作 在建立对象模型时,确定了类、关联、结构和属性,还没有确定操作。只有建立了动态模型和功能模型之后,才可能最后确定类的操作。 七、面向对象的设计 面向对象设计是把分析阶段得到的需求转变成符合成本和质量要求的、抽象的系统实现方案的过程。从面向对象分析到面向对象设计,是一个逐渐扩充模型的过程。 瀑布模型把设计进一步划分成概要设计和详细设计两个阶段,类似地,也可以把面向对象设计再细分为系统设计和对象设计。系统设计确定实现系统的策略和目标系统的高层结构。对象设计确定解空间中的类、关联、接口形式及实现操作的算法。 (一)面向对象设计的准则 1.模块化 面向对象开发方法很自然地支持了把系统分解成模块的设计原则:对象就是模块。它是把数据结构和操作这些数据的方法紧密地结合在一起所构成的模块。 2.抽象 面向对象方法不仅支持过程抽象,而且支持数据抽象。 3.信息隐藏 在面向对象方法中,信息隐藏通过对象的封装性来实现。 4.低耦合 在面向对象方法中,对象是最基本的模块,因此,耦合主要指不同对象之间相互关联的紧密程度。低耦合是设计的一个重要标准,因为这有助于使得系统中某一部分的变化对其它部分的影响降到最低程度。 5.高内聚 (1)操作内聚。 (2)类内聚。 (3)一般——具体内聚。 (二)面向对象设计的启发规则 1.设计结果应该清晰易懂 使设计结果清晰、易懂、易读是提高软件可维护性和可重用性的重要措施。显然,人们不会重用那些他们不理解的设计。 要做到: (1)用词一致。 (2)使用已有的协议。 (3)减少消息模式的数量。 (4)避免模糊的定义。 2.一般——具体结构的深度应适当 3.设计简单类 应该尽量设计小而简单的类,这样便以开发和管理。为了保持简单,应注意以下几点: (1)避免包含过多的属性。 (2)有明确的定义。 (3)尽量简化对象之间的合作关系。 (4)不要提供太多的操作。 4.使用简单的协议 一般来说,消息中参数不要超过3个。 5.使用简单的操作 面向对象设计出来的类中的操作通常都很小,一般只有3至5行源程序语句,可以用仅含一个动词和一个宾语的简单句子描述它的功能 6.把设计变动减至最小 通常,设计的质量越高,设计结果保持不变的时间也越长。即使出现必须修改设计的情况,也应该使修改的范围尽可能小。(三)系统设计 系统设计是问题求解及建立解答的高级策略。必须制定解决问题的基本方法,系统的高层结构形式包括子系统的分解、它的固有并发性、子系统分配给硬软件、数据存储管理、资源协调、软件控制实现、人机交互接口。 1.系统设计概述 设计阶段先从高层入手,然后细化。系统设计要决定整个结构及风格,这种结构为后面设计阶段的更详细策略的设计提供了基础。 (1)系统分解。 系统中主要的组成部分称为子系统,子系统既不是一个对象也不是一个功能,而是类、关联、操作、事件和约束的集合。 (2)确定并发性。 分析模型、现实世界及硬件中不少对象均是并发的。 (3)处理器及任务分配。 各并发子系统必须分配给单个硬件单元,要么是一个一般的处理器,要么是一个具体的功能单元。 (4)数据存储管理。 系统中的内部数据和外部数据的存储管理是一项重要的任务。通常各数据存储可以将数据结构、文件、数据库组合在一起,不同数据存储要在费用、访问时间、容量及可靠性之间做出折衷考虑。 (5)全局资源的处理。 必须确定全局资源,并且制定访问全局资源的策略。 (6)选择软件控制机制。 分析模型中所有交互行为都表示为对象之间的事件。系统设计必须从多种方法中选择某种方法来实现软件的控制。 (7)人机交互接口设计。 设计中的大部分工作都与稳定的状态行为有关,但必须考虑用户使用系统的交互接口。 2.系统结构的一般框架 3.系统分解——建立系统的体系结构 可用的软件库以及程序员的编程经验。 通过面向对象分析得到的问题域精确模型,为设计体系结构奠定了良好的基础,建立了完整的框架。 4.选择软件控制机制 软件系统中存在两种控制流,外部控制流和内部控制流。 5.数据存储管理 数据存储管理是系统存储或检索对象的基本设施,它建立在某种数据存储管理系统之上,并且隔离了数据存储管理模式的影响。 6.设计人机交互接口 在面向对象分析过程中,已经对用户界面需求作了初步分析,在面向对象设计过程中,则应该对系统的人机交互接口进行详细设计,以确定人机交互的细节,其中包括指定窗口和报表的形式、设计命令层次等项内容。 (四)对象设计 1.对象设计概述 2.三种模型的结合 (1)获得操作。 (2)确定操作的目标对象。 3.算法设计 4.优化设计 5.控制的实现 6.调整继承 7.关联的设计 八、面向对象的实现 (一)程序设计语言 1.选择面向对象语言 采用面向对象方法开发软件的基本目的和主要优点是通过重用提高软件的生产率。因此,应该优先选用能够最完善、最准确地表达问题域语义的面向对象语言。 在选择编程语言时,应该考虑的其他因素还有:对用户学习面向对象分析、设计和编码技术所能提供的培训操作;在使用这个面向对象语言期间能提供的技术支持;能提供给开发人员使用的开发工具、开发平台,对机器性能和内存的需求,集成已有软件的容易程度。 2.程序设计风格 (1)提高重用性。 (2)提高可扩充性。 (3)提高健壮性。 (二)类的实现 在开发过程中,类的实现是核心问题。在用面向对象风格所写的系统中,所有的数据都被封装在类的实例中。而整个程序则被封装在一个更高级的类中。在使用既存部件的面向对象系统中,可以只花费少量时间和工作量来实现软件。只要增加类的实例,开发少量的新类和实现各个对象之间互相通信的操作,就能建立需要的软件。 一种方案是先开发一个比较小、比较简单的来,作为开发比较大、比较复杂的类的基础。 (1)“原封不动”重用。 (2)进化性重用。 一个能够完全符合要求特性的类可能并不存在。 (3)“废弃性”开发。 不用任何重用来开发一个新类。 (4)错误处理。 一个类应是自主的,有责任定位和报告错误。 (三)应用系统的实现 应用系统的实现是在所有的类都被实现之后的事。实现一个系统是一个比用过程性方法更简单、更简短的过程。有些实例将在其他类的初始化过程中使用。而其余的则必须用某种主过程显式地加以说明,或者当作系统最高层的类的表示的一部分。 在C++和C中有一个mAIn( )函数,可以使用这个过程来说明构成系统主要对象的那些类的实例。 (四)面向对象测试 (1)算法层。 (2)类层。 测试封装在同一个类中的所有方法和属性之间的相互作用。 (3)模板层。 测试一组协同工作的类之间的相互作用。 (4)系统层。 把各个子系统组装成完整的面向对象软件系统,在组装过程中同时进行测试。 九、面向对象和基于对象的区别 很多人没有区分“面向对象”和“基于对象”两个不同的概念。面向对象的三大特点(封装,继承,多态)却一不可。通常“基于对象”是使用对象,但是无法利用现有的对象模板产生新的对象类型,继而产生新的对象,也就是说“基于对象”没有继承的特点。而“多态”表示为父类类型的子类对象实例,没有了继承的概念也就无从谈论“多态”。现在的很多流行技术都是基于对象的,它们使用一些封装好的对象,调用对象的方法,设置对象的属性。但是它们无法让程序员派生新对象类型。他们只能使用现有对象的方法和属性。所以当你判断一个新的技术是否是面向对象的时候,通常可以使用后两个特性来加以判断。“面向对象”和“基于对象”都实现了“封装”的概念,但是面向对象实现了“继承和多态”,而“基于对象”没有实现这些,的确很饶口。 从事面向对象编程的人按照分工来说,可以分为“类库的创建者”和“类库的使用者”。使用类库的人并不都是具备了面向对象思想的人,通常知道如何继承和派生新对象就可以使用类库了,然而我们的思维并没有真正的转过来,使用类库只是在形式上是面向对象,而实质上只是库函数的一种扩展。 面向对象是一种思想,是我们考虑事情的方法,通常表现为我们是将问题的解决按照过程方式来解决呢,还是将问题抽象为一个对象来解决它。很多情况下,我们会不知不觉的按照过程方式来解决它,而不是考虑将要解决问题抽象为对象去解决它。有些人打着面向对象的幌子,干着过程编程的勾当。

 

三层架构:李建


传统两层结构
  在过去应用系统开发过程中,CLIENT/SERVER体系结构得到了广泛的应用 。其特点是,应用程序逻辑通常分布在客户和服务器两端,客户端发出数据资源访问请求,服务器端将结果返回客户端。但CLIENT/SERVER结构存在着很多体系结构上的问题,比如:当客户端数目激增时,服务器端的性能会因为负载过重而大大衰减;一旦应用的需求发生变化,客户端和服务器端的应用程序都需要进行修改,给应用维护和升级带来了极大的不便;大量的数据传输增加了网络的负载等等。
三层结构介绍
  所谓三层体系结构,是在客户端与数据库之间加入了一个"中间层",也叫组件层。这里所说的三层体系,不是指物理上的三层,不是简单地放置三台机器就是三层体系结构,也不仅仅有B/S应用才是三层体系结构,三层是指逻辑上的三层,即使这三个层放置到一台机器上。
  三层体系的应用程序将业务规则、数据访问、合法性校验等工作放到了中间层进行处理。通常情况下,客户端不直接与数据库进行交互,而是通过COM/DCOM通讯与中间层建立连接,再经由中间层与数据库进行交互。
Microsoft.NET 为三层结构做的准备
  Microsoft .NET Framework是微软推出的一套下一代开发平台。.NET 基于开发人员的角度来说它是一个公共平台的类库(FCL),包含了近100 个命名空间(namespace)的近5000个类,想想看这是多的强大,还包括一个公共语言运行库(CLR)。因为只要符合.NET的公共运行规范(CLS的语言都可以 使用它提供的强大的类,并编译为微软的中间语言(MSIL),在其他的应用中就可以当作一个组件来调用。同时享受公共运行库带来的一切好处: 垃圾自动回收(GC)、实时编译(JIT)、跨语言互动、跨平台。 .NET 还可比喻是操作系统提供给开发人员的面向对像的API。 ASP.net是.net中的一部分。它最大的优点除了是编译执行速度快外,我觉得最大的优点是页面和代码分离的编写方式,再加上.net库提供的支持事件的各种WEB控件,以及.NET公共平台的类库(FCL),和以前编写网页方式相比可谓是一场革命。转载:http://industry.ccidnet.com/art/294/20030526/47418_1.html
三层架构图如下:
       CIOCPServer
         ||
         ||
      CCutomHPServer
         ||
         ||
       CTestServer
以后我们要讨论的就是这个看上去并不复杂的三层架构图,下面就此架构图中的主要类进行简要说明。
  CIOCPServer:
  完成端口服务器基本通信类,它使用winnt/2000/xp平台特有完成端口特性,对通信模型进行封装,向它的派生类提供以下基本扩展接口(可被重载的虚函数):
  1、有客户端连接时的处理接口;
  2、客户端断开时的处理接口;
  3、从客户端收完数据后的处理接口;
  4、向客户端发送完数据后的处理接口;
  5、网络通信及服务器处理出现错误时的处理接口。
  CCustomHPServer:
  典型的高性能服务器类,CIOCPServer是其基类之一(之一?难道还有另外的基类,回答是:当然,呵呵,别急,后面会介绍),此类在CIOCPServer的基础上,封装了三个数据队列及三类处理线程,介绍如下:
  1、接收数据包队列及接收线程:用于存放刚收到的数据包,此数据包还没有进行逻辑意义上的拆解,接收线程从此队列中取出数据包,并将其形成一个逻辑意义上完整的数据包加入到“处理数据包队列”中;
  2、处理数据包队列及逻辑处理线程:已经拆解成了逻辑意义上的数据包,逻辑处理线程对此类数据包进行逻辑解析,这里就是服务器的主要逻辑部分,有的数据包在处理完成后,可能是需要向客户端返回处理结果的,此时就需要逻辑线程在处理完成后将返回结果的数据包放入“发送数据包队列”中;
  3、发送数据包队列及发送线程:待发送的数据包队列,由发送线程根据数据包里的客户端套接字发送给特定客户端。
  CTestServer:
  此类是一个测试类,主要用于演示如何在CCustomHPServer的基础上派生一个真正的应用服务器,并用于说明它需要重载实现CCustomHPServer的哪些重要虚函数。
  基于以上的结构,我们的服务器通信模型,可以一层一层地实现,一层一层的测试。在CIOCPServer中,它本身是不带有任何数据队列的,所有的网络数据都是即来即处理,没有保存数据,实现的是即时响应。在CIOCPServer里,有两类重要线程:AcceptThread线程和WorkerThread线程。其中,AccetpThread线程使用Accept或AcceptEx函数来接收客户端的连接请求,并实现客户端socket与完成端口句柄的绑定,“有客户端连接时的处理接口”就是在这里封装的;而WorkerThread线程是我们在完成端口中常说的“工作者线程”,它由get函数触发工作,除“有客户端连接时的处理接口”之外的其它接口,都在这里进行封装。
通上面可以看出三层架构中,对每一层的分工非常明确。通过这个实习项目,我第一次接触三层架构,它给我的第一感觉就是易于维护,在实际开发中代码层次分得很清楚,开发起来效率高。其它方面我可能还不是很清楚。以后用多了可能慢慢就会深入了解。
 

三层架构是:表现层:HTML,asp,aspx
逻辑层:dll
数据层:数据库服务器

再谈:李建
  查看文章   
ASP.NET三层架构思想2007-04-24 19:44三层结构”是“外观层”、“商业逻辑层”、“数据库层”

假设以这样的结构制作一个留言板,那么应该是:

     # 留言板页面的外观代码都存放在 .aspx 文件中

     # 当用户点击页面上的提交按钮时,先将文本信息传递给一个 LeaveWord 类对象

     (LeaveWord 类的定义被封装到“商业逻辑层”)

     # 之后让这个对象执行 Post() 将留言信息发送到数据库


用一个简单的代码就是:

     <textarea id="Content" runat ="server"></textarea>
     <input type="button" id="Post" runat ="server" />

     // ----------------------------------------
     // 在外观层,当用户点击发送按钮后
     // ----------------------------------------
     private void Post_ServerClick(object sender, EventArgs e)
     {
         LeaveWord lword=new LeaveWord();
         lword.Content=Content.Value;
         lword.Post();
     }

     // ----------------------------------------
     // 在商业逻辑层,定义 LeaveWord 类
     // ----------------------------------------
     public class LeaveWord
     {
         public string Content;

         public void Post()
         {
             new LWordData().Post(this.Content);
         }
     }

     // ----------------------------------------
     // 数据库层,定义发送方法
     // ----------------------------------------
     public class LWordData
     {
         public void Post(string content)
         {
             // 打开数据库,将 content 插入到表中
         }
     }

这样,外观层就不必费心数据库操作了...


理解基本正确.但是数据层已经只是数据库的操作,不应该和业务有任何关系,你可以参考SqlHelper.cs
提醒一点,系统的"层"是对代码的一种逻辑划分,并不是一定要三层,假设你的系统很简单,就一个页面,那一层就可以,如果系统很复杂,也可能是n层.
差不离了,核心就是外层绝对不会涉及任何数据处理,他的任务是设置界面,获取数据,输出数据
业务层最重要,所有数据处理在这里,如何运用外层提供的数据处理业务
数据库层一般都建议调用存储过程,返回数据集或其他所需数据;.net的那两个例子很好,多学习一下.
一个原则:
上层调下层
上层对下层是不可见的
设计时,表现层只调用逻辑层,表现层主要是取得页面的数据传到逻辑层,和把从逻辑层得到的数据显示到页面上。
逻辑层负责把数据加工整理传到数据层和把从数据层取得的数据加工
数据层就只负责把数据对数据库操作

业务逻辑层 就是给上层和下层下达命令和调节行为的中间

 

再谈三层架构:李建最好的要好好看呀!

 

今天利用实验课简单实现了系统三层架构模式:表示层、业务逻辑层和数据访问层。

林其浓.rar

什么是三层结构
关键词: 三层结构                                          

随着Internet越来越广泛的应用,原来基于局域网的企业网开始采用Internet技术构筑和改建自己的企业网,即Intranet。于是,一种新兴的体系结构Browser/Server应运而生,并获得飞速发展,成为众多厂家争相采用的新型体系结构。本质上,Browser/Server也是一种Client/Server结构,它是一种由传统的二层Client/Server结构发展而来的三层Client/Server结构在Web上应用的特例。
在Browser/Server的系统中,用户可以通过浏览器向分布在网络上的许多服务器发出请求。Browser/Server结构极大的简化了客户机的工作,客户机上只需安装、配置少量的客户端软件即可, 服务器将担负更多的工作,对数据库的访问和应用程序的执行将在服务器上完成。
在Browser/Server三层体系结构下,表示层(Presentatioon)、功能层(Business Logic)、数据层(Data Service)被割成三个相对独立的单元:
第一层 表示层:Web浏览器
在表示层中包含系统的显示逻辑,位于客户端。它的任务是由Web浏览器向网络上的某一Web服务器提出服务请求,Web服务器对用户身份进行验证后用HTTP协议把所需的主页传送给客户端,客户机接受传来的主页文件,并把它显示在Web浏览器上。
第二层 功能层:具有应用程序扩展功能的Web服务器
在功能层中包含系统的事务处理逻辑,位于Web服务器端。它的任务是接受用户的请求,首先需要执行相应的扩展应用程序与数据库进行连接,通过SQL等方式向数据库服务器提出数据处理申请,而后等数据库服务器将数据处理的结果提交给Web服务器,再由Web服务器传送回客户端。
第三层 数据层:数据库服务器
在数据层中包含系统的数据处理逻辑,位于数据库服务器端。它的任务是接受Web服务器对数据库操纵的请求,实现对数据库查询、修改、更新等功能,把运行结果提交给Web服务器。
仔细分析不难看出,三层的Browser/Server体系结构是把二层Client/Server结构的事务处理逻辑模块从客户机的任务中分离出来,由单独组成的一层来负担其任务,这样客户机的压力大大减轻了,把负荷均衡地分配给了Web服务器,于是由原来的两层的Client/server结构转变成三层的Browser/Server结构。这种三层体系结构如下图所示。

 

这种结构不仅把客户机从沉重的负担和不断对其提高的性能的要求中解放出来,也把技术维护人员从繁重的维护升级工作中解脱出来。由于客户机把事务处理逻辑部分分给了功能服务器,使客户机一下子"苗条"了许多,不再负责处理复杂计算和数据访问等关键事务,只负责显示部分,所以维护人员不再为程序的维护工作奔波于每个客户机之间,而把主要精力放在功能服务器上程序的更新工作。这种三层结构层与层之间相互独立,任何一层的改变不影响其它层的功能。它从根本上改变了传统的二层Client/Server体系结构的缺陷,它是应用系统体系结构中一次深刻的变革。
两种体系结构的对比
Browser/Server体系结构与Client/Server体系结构相比不仅具有Client/Server体系结构的全部优点,而且又有Clinet/Server体系结构所不具备的独特优势:
开放的标准:
Client/Server所采用的标准只要在内部统一就可,它的应用往往是专用的。Browser/Server所采用的标准都是开放的、非专用的,是经过标准化组织所确定的而非单一厂商所制定,保证了其应用的通用性和跨平台性。
较低的开发和维护成本:
Client/Server的应用必须开发出专用的客户端软件,无论是安装、配置还是升级都需要在所有的客户机上实施,极大地浪费了人力和物力。Browser/Server的应用只需在客户端装有通用的浏览器即可,维护和升级工作都在服务器端进行,不需对客户端进行任何改变,故而大大降低了开发和维护的成本。
使用简单,界面友好:
Client/Server用户的界面是由客户端软件所决定的,其使用的方法和界面各不相同,每推广一个Client/Server系统都要求用户从头学起,难以使用。Browser/Server用户的界面都统一在浏览器上,浏览器易于使用、界面友好,不须再学习使用其它的软件,一劳永逸的解决了用户的使用问题。
客户端消肿:
Client/Server的客户端具有显示与处理数据的功能,对客户端的要求很高,是一个"胖"客户机。Browser/Server的客户端不再负责数据库的存取和复杂数据计算的等任务,只需要其进行显示,充分发挥了服务器的强大作用,这样就大大的降低了对客户端的要求,客户端变得非常"瘦"。
系统灵活:
Client/Server系统的三部分模块中有一部分需改变就要关联到其它模块的变动,使系统极难升级。Browser/Server系统的三部分模块各自相对独立,其中一部分模块改变时其它模块不受影响,系统改进变得非常容易,且可以用不同厂家的产品来组成性能更佳的系统。
保障系统的安全性:
在Client/Server系统中由于客户机直接与数据库服务器进行连接,用户可以很轻易的改变服务器上的数据,无法保证系统的安全性。Browser/Server系统在客户机与数据库服务器之间增加了一层Web服务器,使两者不再直接相连,客户机无法直接对数据库操纵,有效地防止用户的非法入侵。
三层的Browser/Server体系结构具有许多传统Client/Server体系结构不具备的优点,而且又紧密的结合了Internet/Intranet技术,是技术发展的大势所趋,它把应用系统带入了一个崭新的发展时代

 
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值