精华内容
下载资源
问答
  • JVM成神之路-Java对象模型

    千次阅读 2018-07-23 15:01:17
    在jvm的内存结构中,对象保存在堆中,而我们在对对象进行操作时,其实操作的是对象的引用。 Java对象包含三个部分 一个Java对象可以分为三部分存储在内存中,分别是:对象头(Header)、实例数据(Instance Data)和...

    首先我们要知道:

    在jvm的内存结构中,对象保存在堆中,而我们在对对象进行操作时,其实操作的是对象的引用。

    Java对象包含三个部分

    一个Java对象可以分为三部分存储在内存中,分别是:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

    1. 对象头(包含锁状态标志,线程持有的锁等标志)
    2. 实例数据
    3. 对齐填充

    oop-klass model(hotspot jvm中的对象模型)

    Java虚拟机的底层是使用c++实现,而jvm并没有根据一个Java的实例对象去创建对应的c++对象,而是设计了一个oop-klass model ;

    1. OOP(Ordinary Object Pointer):普通对象指针; 表示一个实例信息
    2. Klass:描述对象实例的具体类型, 含了元数据和方法信息
    3. 创建目的:不想让每个对象中都含有一个vtable(虚函数表)

    类就是一类事物的抽象概括。

    OOP体系:

    1. OOPs模块中包含了多个子模块,每个子模块对应一个类型,每一个类型的OOP都代表一个在JVM内部使用的特定对象的类型。
    2. 在Java程序运行过程中,每创建一个新的对象,在JVM内部就会相应的创建一个对应类型的OOP对象。

    代码:

    1. typedef class oopDesc* oop;

    // 定义了oop共同的基类,其他的类型都是它的子类

    1. typedef class instanceOopDesc* instanceOop;

    /* 表示一个Java类型实例,每当我们new一个对象时,

    JVM都会创建一个instanceOopDesc */

    1. typedef class methodOopDesc* methodOop;

    // 表示一个Java方法

    1. typedef class constMethodOopDesc* constMethodOop;

    // 表示一个Java方法中的不变信息

    1. typedef class MethodDataOopDesc* methodDataOop;

    // 记录性能信息的数据结构

    1. typedef class arrayOopDesc* arrayOop;

    /* 定义了数组oops的抽象基类,下面两个类相当于此类的子类,

    new一个数组时会建立此对象*/

    1. typedef class objArrayOopDesc* objArrayOop;

    // 表示持有一个oops数组,对应存储对象的数组

    1. typedef class typeArrayOopDesc* typeArrayOop;

    // 表示容纳基本类型的数组,对应存储基本类型的数组

    1. typedef class constantPoolOopDesc* constantPoolOop;

    // 表示在class文件中描述的常量池

    1. typedef class constantPoolCacheOopDesc* constantPoolCacheOop;

    // 常量池缓存

    1. typedef class klassOopDesc* klassOop;

    // 描述一个与Java类对等的C++类

    1. typedef class markOopDesc* markOop;

    // 表示对象头

    OopDesc结构:

    class oopDesc {

     friend class VMStructs;

            private:

    /*

    * 实际上也是代表了instanceOopDesc、arrayOopDesc和OopDesc

    * 包含了markOop _mark和union_matadata两部分

    */

    volatile markOop _mark; // 保存锁标记、gc分代等信息

    union _metadata { wideKlassOop _klass; // 普通指针,

    // 压缩类指针,和普通指针都指向instanceKlass 对象

    narrowOop _compressed_klass; } _metadata;

    private:

     // 实例数据保存的位置

    void* field_base(int offset) const;

    jbyte* byte_field_addr(int offset) const;

    jchar* char_field_addr(int offset) const;

    jboolean* bool_field_addr(int offset) const;

    jint* int_field_addr(int offset) const;

    jshort* short_field_addr(int offset) const;

    jlong* long_field_addr(int offset) const;

    jfloat* float_field_addr(int offset) const;

    jdouble* double_field_addr(int offset) const;

    address* address_field_addr(int offset) const; }

    /* instanceOopDesc和arrayOopDesc都直接继承了oopDesc,

    都没有增加其他的数据结构 */

    class instanceOopDesc : public oopDesc {

    }

    class arrayOopDesc : public oopDesc { }

    1. 职能:表示对象的实例数据,不含任何虚函数
    2. 对象在内存中的基本形式就是oop
    3. 对象所属的类也是一种oop,即klassOop,对应的klass是klassKlass

    Klass体系:

    结构:

    • class Klass;

    // klassOop的一部分,用来描述语言层的类型,其他所有类的父类

    • class instanceKlass;

    // 在虚拟机层面描述一个Java类,每一个已加载的Java类都会创建一个此对象,

    // 在JVM层表示Java类

    • class instanceMirrorKlass;

    // 专有instantKlass,表示java.lang.Class的Klass

    • class instanceRefKlass;

    // 专有instantKlass,表示java.lang.ref.Reference的子类的Klass

    • class methodKlass; // 表示methodOop的Klass
    • class constMethodKlass; // 表示constMethodOop的Klass
    • class methodDataKlass; // 表示methodDataOop的Klass
    • class klassKlass; // 最为klass链的端点,klassKlass的Klass就是它自身
    • class instanceKlassKlass; // 表示instanceKlass的Klass
    • class arrayKlassKlass;

    // 表示arrayKlass的Klass

    • class objArrayKlassKlass; // 表示objArrayKlass的Klass
    • class typeArrayKlassKlass; // 表示typeArrayKlass的Klass
    • class arrayKlass; // 表示array类型的抽象基类
    • class objArrayKlass; // 表示objArrayOop的Klass
    • class typeArrayKlass; // 表示typeArrayOop的Klass
    • class constantPoolKlass; // 表示constantPoolOop的Klass
    • class constantPoolCacheKlass;

    // 表示constantPoolCacheOop的Klass

    功能:

        • 实现语言层面的Java类(在Klass基类中已经实现)
        • 实现Java对象的分发功能(由Klass子类提供虚函数实现)

    目的:为了实现虚函数多态,提供了虚函数表。

    • instanceKlass的内部结构:
    • objArrayOop _methods;

    // 类拥有的方法

    • typeArrayOop _method_ordering;

    //描述方法顺序

    • objArrayOop _local_interfaces;

    //实现的接口

    • objArrayOop _transitive_interfaces;

    //继承的接口

    • typeArrayOop _fields;

    //域

    • constantPoolOop _constants;

    //常量

    • oop _class_loader;

    //类加载器

    • oop _protection_domain;

    //protected域

    ....

    HotSpotJVM的设计这把对象一拆为二,分为Klass和oop,其中oop的只能主要在于表示对象的实例数据,所以其中不含有任何虚函数,而klass为了实现虚函数多态,所以提供了虚函数表。所以,关于java的多态,其实也有虚函数的影子在。

    instanceKlass

    JVM在运行时,需要一种用来标识Java内部类型的机制。在HotSpot中的解决方案是:为每一个已加载的Java类创建一个instanceKlass对象,用来在JVM层表示Java类。

    结构:

    //类拥有的方法列表

      objArrayOop     _methods;

      //描述方法顺序

      typeArrayOop    _method_ordering;

      //实现的接口

      objArrayOop     _local_interfaces;

      //继承的接口

      objArrayOop     _transitive_interfaces;

      //域

      typeArrayOop    _fields;

      //常量

      constantPoolOop _constants;

      //类加载器

      oop             _class_loader;

      //protected域

      oop             _protection_domain;

          ....

    在JVM中,对象在内存中的基本存在形式就是oop。那么,对象所属的类,在JVM中也是一种对象,因此它们实际上也会被组织成一种oop,即klassOop。同样的,对于klassOop,也有对应的一个klass来描述,它就是klassKlass,也是klass的一个子类。

    klassKlass作为oop的klass链的端点。关于对象和数组的klass链大致如下图:

    oop-klass-klassKlass关系图:

    符号引用

    符号引用就是用一组符号来描述所引用的目标,我们都知道在Java中,通常情况下我们写的一个Java类被编译以后都是一个class文件,在编译的时候,Java类并不知道所引用的类的实际地址,因此只能使用符号引用来代替。

    一般一个对象的创建就是从new开始的,而操作这些创建指令的就是jvm了,首先当你开始new的时候,jvm会先去查找一个符号引用,如果找不到这个符号引用就说明这个类还没有被加载,因此jvm就会进行类加载,然后符号引用被解析完成,紧接着jvm会为对象在堆内存中分配内存,也就是说我们这个user对象就在堆内存中有一块内存空间了。

    HotSpot虚拟机实现的Java对象包括三个部分:对象头,实例字段和对齐填充

    为对象分配完堆内存之后,jvm会将该内存进行零值初始化。

    内存存储:

    关于一个Java对象,他的存储是怎样的,一般很多人会回答:对象存储在堆上。稍微好一点的人会回答:对象存储在堆上,对象的引用存储在栈上。今天,再给你一个更加显得牛逼的回答:

    对象的实例(instantOopDesc)保存在堆上,对象的元数据(instantKlass)保存在方法区,对象的引用保存在栈上。

    其实如果细追究的话,上面这句话有点故意卖弄的意思。因为我们都知道。方法区用于存储虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 所谓加载的类信息,其实不就是给每一个被加载的类都创建了一个 instantKlass对象么。

    示例

    class Model{
    public static int a = 1;
    private final int NUMBER = 2;
    public int b;
    public int c = 3;
    
    public Model(int b){
    this.b = b;
    }
    
    public static void main(String[] args){
    int d = 10;
    Model modelA = new Model(2);
    Model modelB = new Model(3);
    }
    }
    

    存储结构:

    总结:

    在Java中,JVM中的对象模型包含两部分:Oop和Klass,在类被加载的时候,JVM会给类创建一个instanceKlass,其中包含了类信息、常量、静态变量、即时编译器编译后的代码等,存储在方法区,用来在JVM层表示该Java类。而使用new一个对象后,JVM就会创建一个instanceOopDesc对象,该对象包含对象头和实例数据,对象头中保存的是锁的状态标志等信息,元数据则实际上是一个指针,指向instanceKlass

    Java对象模型---对象头(Mark Word)

    对象自身的运行时数据

    这部分存储包括哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。这部分数据被官方称为Mark Word,在32位和64位的虚拟机中的大小分别为32bit和64bit。

    由于对象头信息是与对象自身定义的数据无关的额外存储成本,考虑到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构以提高存储空间的利用率。即这部分数据会根据对象的状态来分配存储空间。

    对象的类型指针

    即指向对象的类元数据的指针。虚拟机可以通过该指针判定对象实例属于哪个类。

    在Java对象中比较特殊的是Java数组,一个数组实例的对象头中必须记录数组的长度。JVM可以通过对象头中的数组长度数据来判定数组的大小,这是访问数组类型的元数据无法得到的。

    对象的实例数据

    前面提到对象头是对象的额外开销,只有实例数据才是一个对象实例存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。这部分内容同时记录了子类从父类继承所得的各类型数据。

    填充

    对齐填充在对象数据中并不是必然的,只是起着占位符的作用,没有特别含义。HotSpot要求对象起始地址必须是8字节的整数倍。对象头的大小刚好符合要求,因此当实例数据没有对齐时,就需要通过填充来对齐数据。

    获取类的元数据

    虚拟机在加载类的时候会将类的信息、常量、静态变量和即时编译器编译后的代码等数据存储在方法区(Method Area)。类的元数据,即类的数据描述,也被存在方法区。我们知道对象头中会存有对象的类型指针,通过类型指针可以获取类的元数据。因此,对象的类型指针其实指向的是方法区的某个存有类信息的地址。

    但是,并不是每个对象实例都存有对象的类型指针。根据对象访问定位方法的不同,对象的类型指针被存放在不同的区域。

    • 通过句柄访问对象
      • 对象的类型指针被存放在句柄池中;
    • 通过Reference指针直接访问对象
      • 对象的类型指针被存放在对象本身的数据中。

    比较来说:

    • 使用句柄访问的最大好处就是reference中存储的是稳定的句柄地址,当对象被移动(垃圾收集时会经常移动对象)时智慧改变句柄中实例数据执政,而reference本身不需要修改。
    • 使用直接指针访问方式的最大好处就是速度快,节省了一次指针定位的时间开销(对象的访问在java中也非常频繁)

    因此,Java的对象数据存储可以理解为:

    • 引用类型(指向对象的Reference)
      • 存储在栈中
    • 对象的类的元数据 (Class MetaData)
      • 存储在方法区中
    • 对象的实例数据
      • 存储在堆中

    对象内存布局

    • 存储的是与对象本身定义的数据无关的额外存储成本,其数据结构不固定。
    • 32位JVM中,对象不同装填的mark word各个比特位区间图示如下:

    对象五种状态:无锁态、轻量级锁、重量级锁、GC标记和偏向锁。

    HotSpot中对象头主要包含两部分

    第一:

    用于存储对象自身的运行时数据,如上表中的对象哈希码,对象分代年龄,偏向线程id,偏向时间戳等。

    第二:

    类型指针了,我们看表中也有指针字样,那么这部分主要就是杜希昂指向它的类元数据的指针了,虚拟机就是通过这个指针来确定这个对象时那个实例。

    偏向锁和重量级锁

    • 偏向锁:主要解决无竞争下的锁性能问题
      • 按照HotSpot设计,每次加锁/解锁都会涉及到一些CAS操作,CAS操作会延迟本地调用
      • 偏向锁会偏向第一个访问锁的程序,如果接下来的运行过程中,该锁没有被其他线程访问,则持有偏向锁的线程将永远不需要触发同步。
      • 但是如果在运行过程中,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM会尝试消除它身上的偏向锁,将锁恢复到标准的轻量级锁
      • 只能在单线程中起作用
    • 轻量级锁:为了在无多线程竞争的环境中使用CAS来替代synchronized。减少传统的重量级锁使用操作系统互斥量产生的性能消耗,是为了减少多线程进入互斥的几率。并非替代互斥。

    参考资料:

    《深入理解Java虚拟机》

    http://www.cnblogs.com/chenyangyao/p/5245669.html

    深入理解多线程(二)—— Java的对象模型-HollisChuang's Blog

    深入理解多线程(三)—— Java的对象头-HollisChuang's Blog

     

    展开全文
  • 对象模型(Object Model )

    千次阅读 2020-09-24 17:20:18
    标准的C ++对象模型为对象范例提供了非常有效的运行时支持。但是它的静态性质在某些问题领域是不灵活的。图形用户界面编程是一个既需要运行时效率又需要高度灵活性的领域。 Qt通过结合C ++的速度和Qt对象模型的灵活...

    标准的C ++对象模型为对象范例提供了非常有效的运行时支持。但是它的静态性质在某些问题领域是不灵活的。图形用户界面编程是一个既需要运行时效率又需要高度灵活性的领域。 Qt通过结合C ++的速度和Qt对象模型的灵活性来提供此功能。
    Qt将这些功能添加到C ++中:

    • 一种非常强大的无缝对象通信机制,称为信号和槽
    • 可查询和可设计的对象属性
    • 强大的事件和事件过滤器
    • 上下文字符串翻译以实现国际化
    • 先进的间隔驱动计时器,使许多任务可以优雅地集成到事件驱动的GUI中
    • 分层且可查询的对象树,以自然方式组织对象所有权
    • 保护的指针(QPointer),在销毁引用的对象时会自动将其设置为0,这与普通的C ++指针不同,在对象销毁时,C ++指针会变成悬挂的指针
    • 跨库边界的动态转化。
    • 支持自定义类型创建。

    这些Qt功能中的许多功能都基于从QObject继承的标准C ++技术实现。其他对象,例如对象通信机制和动态属性系统,则需要Qt自己的元对象编译器(moc)提供的元对象系统。
    元对象系统是C ++扩展,使该语言更适合于真正的组件GUI编程。
    重要类
    这些类构成了Qt对象模型的基础。

    QMetaClassInfo有关类的其他信息
    QMetaEnum有关枚举器的元数据

    QMetaMethod

    有关成员函数的元数据
    QMetaProperty有关属性的元数据
    QMetaType在元对象系统中管理命名类型

    QObject

    所有Qt对象的基类
    QSignalBlockerQObject :: blockSignals()周围的异常安全包装器
    QObjectCleanupHandler观察多个QObject的生命周期
    QMetaObject包含有关Qt对象的元信息
    QPointer提供指向QObject的受保护指针的模板类
    QVariant充当最常见Qt数据类型的并集


    Qt对象:特性(identity)与值
    上面列出的Qt对象模型的某些附加功能要求我们将Qt对象视为身份(identity),而不是值。值被复制或分配;身份被克隆。克隆意味着创建一个新的身份,而不是旧身份的精确副本。例如,双胞胎具有不同的身份。他们可能看起来完全一样,但是名称不同,位置不同,并且社交网络也可能完全不同。
    那么克隆身份比复制或分配值要复杂得多。我们可以在Qt对象模型中看到这意味着什么。
    Qt对象...

    • 可能具有唯一的QObject :: objectName()。如果我们复制一个Qt对象,我们应该给它起什么名字?
    • 在对象层次结构中具有位置。如果我们复制一个Qt对象,该副本应位于何处?
    • 可以连接到其他Qt对象以向它们发出信号或接收它们发出的信号。如果我们复制Qt对象,应该如何将这些连接转移到副本中?
    • 可以在运行时向其中添加未在C ++类中声明的新属性。如果我们复制一个Qt对象,该副本是否应该包括添加到原始对象的属性?

    由于这些原因,应将Qt对象视为身份,而不是值。身份是克隆的,而不是复制或分配的,克隆身份比复制或分配值要复杂得多。因此,QObject和QObject的所有子类(直接或间接)都禁用了其复制构造函数和赋值运算符。

    展开全文
  • 目录 一、瀑布模型 1.1什么是瀑布模型 1.2特点 1.3优缺点 1.4客户需求 ...二、快速原型模型 ...2.1什么是快速原型模型 ...2.3快速原型模型的思想...3.4作用 四、螺旋模型 4.1什么是螺旋模型 4.2特点 4.3优缺点 4.4...

    目录

    一、瀑布模型

    1.1什么是瀑布模型

    1.2特点

    1.3优缺点

    1.4客户需求

    二、快速原型模型

    2.1什么是快速原型模型

    2.2优缺点

    2.3快速原型模型的思想产生、原理及运用方式

    2.4类型

    2.5开发步骤

    三、增量模型

    3.1什么是增量模型

    3.2特点

    3.3优缺点

    3.4作用

    四、螺旋模型

    4.1什么是螺旋模型

    4.2特点

    4.3优缺点

    4.4限制条件


    一、瀑布模型

    1.1什么是瀑布模型

    1970年温斯顿.罗伊斯提出了著名的“瀑布模型”,直到80年代早期,它一直是唯一被广泛采用的软件开发模型

    瀑布模型将软件生命周期划分为制定计划、需求分析、软件设计、程序编写、软件测试运行维护等六个基本活动,并且规定了它们自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落

    瀑布模型是最早出现的软件开发模型,在软件工程中占有重要的地位,它提供了软件开发的基本框架。其过程是从上一项活动接收该项活动的工作对象作为输入,利用这一输入实施该项活动应完成的内容给出该项活动的工作成果,并作为输出传给下一项活动

    从本质来讲,它是一个软件开发架构,开发过程是通过一系列阶段顺序展开的,从系统需求分析开始直到产品发布和维护,每个阶段都会产生循环反馈,因此,如果有信息未被覆盖或者发现了问题,那么最好 “返回”上一个阶段并进行适当的修改,开发进程从一个阶段“流动”到下一个阶段,这也是瀑布开发名称的由来

    对于经常变化的项目而言,瀑布模型毫无价值

    1.2特点

    1、阶段间具有顺序性和依赖性

    该阶段具有两重含义

    1. 必须等前一阶段的工作完成后,才能开始后一阶段的工作
    2. 前一阶段的输出文档就是后一阶段的输入文档,因此只有前一阶段的输出文档正确,后一阶段的工作才能获得正确的结果

    2、推迟实现的观点

    对于规模较大的软件项目来说,往往编码开始的越早,最终完成开发所需时间越长。因为前面阶段的工作没做或做的不扎实,过早地考虑进行程序实现,往往导致大量返工,有时甚至发生无法弥补的问题

    瀑布模型在编码之前设置了系统分析与系统设计的各个阶段,分析与设计阶段的基本任务规定,在这两个阶段主要考虑目标系统的逻辑模型,不涉及软件的物理实现

    清楚的区分逻辑设计与物理设计,尽可能推迟程序的物理实现,是按照瀑布模型开发软件的一条重要的指导思想

    3、质量保证的观点

    为了保证所开发的软件的质量,在瀑布模型的每一个阶段都应坚持两个重要做法

    1. 每个阶段都必须完成规定的文档,没有交出合格的文档就是没有完成该阶段的任务
    2. 每个阶段结束前都要对所完成的文档进行评审,以便尽早发现问题,改正错误

    传统的瀑布模型过于理想化,实际的瀑布模型是带"反馈环"的。如图所示(图中实线箭头表示开发过程,虚线箭头表示维护过程),当在后面阶段发现前面阶段的错误时,需要沿图中左侧的反馈线返回前面的阶段,修正前面阶段的产品后再回来继续完成后面阶段的任务

    瀑布模型是文档驱动的模型,遵守这个约束可使软件维护变得比较容易一些,从而显著降低软件预算

    1.3优缺点

    优点:

    • 项目提供了按阶段划分的检查点
    • 当前一阶段完成后,您只需要去关注后续阶段
    • 可在迭代模型中应用瀑布模型

    缺点:

    • 不适合需求模糊或需求经常变动的系统
    • 由于开销的逐步升级问题,它不希望存在早期阶段的反馈
    • 在一个系统完成以前,它无法预测一个新系统引入一个机构的影响
    • 用户可能需要较长等待时间来获得一个可供使用的系统,也许会给用户的信任程度带来影响和打击
    • 最终产品往往反映用户的初始需求而不是最终需求

    1.4客户需求

    对项目而言,是否使用这一模型主要取决于是否能理解客户的需求以及在项目的进程中这些需求的变化程度;对于经常变化的项目而言,瀑布模型毫无价值,可以考虑其他的架构来进行项目管理,比如螺旋模型

    瀑布模型强调文档的作用,并要求每个阶段都要仔细验证。但是,这种模型的线性过程太理想化,已不再适合现代的软件开发模式,几乎被业界抛弃,其主要问题在于:

    1. 各个阶段的划分完全固定,阶段之间产生大量的文档,极大地增加了工作量
    2. 由于开发模型是线性的,用户只有等到整个过程的末期才能见到开发成果,从而增加了开发的风险
    3. 早期的错误可能要等到开发后期的测试阶段才能发现,进而带来严重的后果

    按照瀑布模型的阶段划分,软件测试可以分为单元测试集成测试系统测试

     

    二、快速原型模型

    2.1什么是快速原型模型

    快速原型是快速建立起来的可以在计算机上运行的程序,它所能完成的功能往往是最终产品能完成的功能的一个子集

    快速原型模型是增量模型的另一种形式,在开发真实系统之前,迅速建造一个可以运行的软件原型 ,以便理解和澄清问题,在该原型的基础上,逐渐完成整个系统的开发工作

    它允许在需求分析阶段对软件的需求进行初步而非完全的分析和定义,快速设计开发出软件系统的原型,该原型向用户展示待开发软件的全部或部分功能和性能;用户对该原型进行测试评定,给出具体改进意见以丰富细化软件需求;开发人员据此对软件进行修改完善,直至用户满意认可之后,进行软件的完整实现及测试、维护

    2.2优缺点

    优点

    • 克服瀑布模型的缺点,减少由于软件需求不明确带来的开发风险
    • 适合预先不能确切定义需求的软件系统的开发

    缺点

    • 所选用的开发技术和工具不一定符合主流的发展;快速建立起来的系统结构加上连续的修改可能会导致产品质量低下
    • 使用前提是要有一个展示性的产品原型,一定程度上可能会限制开发人员的创新

    2.3快速原型模型的思想产生、原理及运用方式

    1、思想产生

    在需求分析阶段得到完全、一致、准确、合理的需求说明十分困难

    获得一组基本需求说明后,就快速地使其“实现”,通过原型反馈,加深对系统的理解满足用户基本要求,使用户在试用后对需求说明进行补充和精确化,从而获得合理完整、现实可行的需求说明

    再把快速原型思想用到软件开发的其他阶段,向软件开发的全过程扩展

    先用相对少的成本,较短的周期开发一个简单的、但可以运行的系统原型向用户演示或让用户试用,以便及早澄清并检验一些主要设计策略,在此基础上再开发实际的软件系统

    2、原理

    利用原型辅助软件开发

    经过简单快速分析快速实现一个原型,用户与开发者在试用原型过程中加强通信与反馈,通过反复评价和改进原型,减少误解,弥补漏洞,最终提高软件质量

    3、运用方式

    由于运用原型的目的和方式不同,在使用原型时也采取不同的策略

    • 抛弃策略:将原型用于开发过程的某个阶段,促使该阶段的开发结果更加完整、准确、一致、可靠,该阶段结束后,原型随之作废。探索型和实验型就是采用此策略的
    • 附加策略:将原型用于开发的全过程,原型由最基本的核心开始,逐步增加新的功能和新的需求,反复修改反复扩充,最后发展为用户满意的最终系统,演化型快速原型就是采用此策略

    采用何种形式、何种策略运用快速原型主要取决于软件项目的特点、可供支持的原型开发工具和技术等,根据实际情况的特点决定

    2.4类型

    在软件开发中,原型是软件的一个早期可运行的版本,它反映最终系统的部分重要特性

    探索型

    这种原型目的是要弄清对目标系统的要求,确定所希望的特性,并探讨多种方案的可行性

    实验型

    这种原型用于大规模开发和实现之前,考核方案是否合适,规格说明是否可靠

    进化型

    这种原型的目的不在于改进规格说明,而是将系统建造得易于变化,在改进原型的过程中,逐步将原型进化成最终系统

    2.5开发步骤

    1、快速分析

    在分析人员与用户密切配合下,迅速确定系统的基本需求,根据原型需要体现的特征描述基本需求以满足开发原型的需要

    2、构造原型

    在快速分析的基础上,根据基本需求说明尽快实现一个可行的系统

    要求具有强有力的软件工具的支持,并忽略最终系统在某些细节上的要求,主要考虑原型系统能够充分反映所要评价的特性

    3、运行原型

    发现问题,消除误解,开发者与用户充分协调

    4、评价原型

    在运行的基础上,考核评价原型的特性,分析运行效果是否满足用户的愿望,纠正过去交互中的误解与分析中的错误,增添新的要求,并满足因环境变化或用户的新想法引起的系统要求变动,提出全面的修改意见

    5、修改

    根据评价原型的活动结果进行修改

    若原型未满足需求说明的要求,说明对需求说明存在不一致的理解或实现方案不够合理,根据明确的要求迅速修改原型

    快速原型模型不带反馈环,软件产品的开发基本上是线性顺序进行的

    快速原型的本质是"快速"。开发人员应尽可能地建造出原型系统,以加速软件开发过程,节约软件开发成本

    原型的用途是获知用户的真正需求,一旦需求确定了,原型将被抛弃

     

    三、增量模型

    3.1什么是增量模型

    增量模型也称渐增模型。使用增量模型开发软件时,把软件产品作为一系列的增量构件来设计、编码、集成和测试。每个构件由多个相互作用的模块构成,并且能够完成特定的功能

    使用增量模型时,第一个增量构件往往实现软件的基本需求,提供最核心的功能

    把软件产品分解成增量构件时,唯一必须遵守的约束条件是,当把新构件集成到现有构件中时,所形成的产品必须是可测试的

    瀑布模型或快速原型模型目标是一次就把一个满足所有需求的产品提交给用户

    增量模型把整个软件产品分解成许多个增量构件,分批地逐步向用户提交产品

    3.2特点

    把瀑布模型的顺序特征与快速原型法的迭代特征相结合

    将软件看作一系列相互联系的增量,在开发过程的各次迭代中,每次完成其中的一个增量

    风险更大的增量模型

    确定用户需求后就着手拟定第一个构件的规格说明文档,完成后规格说明组转向第二个构件的规格说明文档,同时设计组开始涉及第一个构件

    使用该方法将不同的构件并行构建,可能加快工程进度,但将冒构建无法集成到一起的风险

    3.3优缺点

    优点

    1. 能在较短的时间内向用户提交可完成部分工作的产品
    2. 将待开发的软件系统模块化,可以分批次地提交软件产品,使用户可以及时了解软件项目的进展
    3. 以组件为单位进行开发降低了软件开发的风险。一个开发周期内的错误不会影响到整个软件系统
    4. 开发顺序灵活。开发人员可以对组件的实现顺序进行优先级排序,先完成需求稳定的核心组件。当组件的优先级发生变化时,还能及时地对实现顺序进行调整

    缺点

    1. 由于各个构件是逐渐并入已有的软件体系结构中的,所以加入构件必须不破坏已构造好的系统部分,这需要软件具备开放式的体系结构
    2. 在开发过程中,需求的变化是不可避免的。增量模型的灵活性可以使其适应这种变化的能力大大优于瀑布模型和快速原型模型,但也很容易退化为边做边改模型,从而是软件过程的控制失去整体性
    3. 如果增量包之间存在相交的情况且未很好处理,则必须做全盘系统分析,这种模型将功能细化后分别开发的方法较适应于需求经常改变的软件开发过程

    3.4作用

    1、开发初期的需求定义只是用来确定软件的基本结构,使得开发初期用户只需要对软件需求进行大概的描述;而对于需求的细节性描述,则可以延迟到增量构件开发时进行,以增量构件为单位逐个地进行需求补充。这种方式能够有效适应用户需求的变更

    2、软件系统可以按照增量构件的功能安排开发的优先顺序,并逐个实现和交付使用。不仅有利于用户尽早用上系统,能够更好地适应新的软件环境,而且在以增量方式使用系统的过程中,还能获得对软件系统后续构件的需求经验

    3、软件系统是逐渐扩展的,因此开发者可以通过对诸多构件的开发,逐步积累开发经验。实际上,增量式开发还有利于技术复用,前面构件中设计的算法、采用的技术策略、编写的源码等,都可以应用到后面将要创建的增量构件中去

    4、增量式开发有利于从总体上降低软件项目的技术风险。个别的构件或许不能使用,但一般不会影响到整个系统的正常工作

    5、实际上,在采用增量模型时,具有最高优先权的核心增量构件将会被最先交付,而随着后续构件不断被集成进系统,这个核心构件将会受到最多次数的测试。这意味着软件系统最重要的心脏部分将具有最高的可靠性,这将使得整个软件系统更具健壮性

     

    四、螺旋模型

    4.1什么是螺旋模型

    螺旋模型是一种演化软件开发过程模型,它兼顾了快速原型的迭代特征以及瀑布模型的系统化与严格监控。螺旋模型最大的特点在于引入了其他模型不具备的风险分析,使软件在无法排除重大风险时有机会停止,以减小损失。同时,在每个迭代阶段构建原型是螺旋模型用以减小风险的途径

    螺旋模型是快速原型模型以进化的开发方式为中心,在每个项目阶段使用瀑布模型法。该模型的每一个周期都包括需求定义、风险分析、工程实现和评审4个阶段,由这4个阶段进行迭代。软件开发过程每迭代一次,软件开发又前进一个层次。用螺旋模型的软件过程如下

    简化的螺旋模型

    完整的数据模型

     

    图中带箭头的点划线的长度代表当前累计的开发费用,螺旋线的角度值代表开发进度,螺旋线的每个周期对应于一个开发阶段

    图中的四个象限代表了以下活动

    1. 制定计划:确定软件目标,选定实施方案,弄清项目开发的限制条件
    2. 风险分析:分析评估所选方案,考虑如何识别和消除风险
    3. 实施工程:实施软件开发和验证
    4. 客户评估:评价开发工作,提出修正建议,制定下一步计划

    4.2特点

    螺旋模型在“瀑布模型”的每一个开发阶段前引入一个非常严格的风险识别、风险分析和风险控制,它把软件项目分解成一个个小项目。每个小项目都标识一个或多个主要风险,直到所有的主要风险因素都被确定

    螺旋模型强调风险分析,使得开发人员和用户对每个演化层出现的风险有所了解,继而做出应有的反应,因此特别适用于庞大、复杂并具有高风险的系统

    4.3优缺点

    优点

    1. 对可选方案和约束条件的强调有利于已有软件的重用,也有助于把软件质量作为软件开发的一个重要目标
    2. 减少了过多测试(浪费资金)或测试不足(产品故障多)所带来的风险
    3. 在螺旋模型中维护只是模型的另一个周期,在维护和开发之间并没有本质区别

    缺点

    1. 采用螺旋模型需要具有相当丰富的风险评估经验和专门知识,在风险较大的项目开发中,如果未能够及时标识风险,势必造成重大损失
    2. 过多的迭代次数会增加开发成本,延迟提交时间

    4.4限制条件

    1. 螺旋模型强调风险分析,但要求许多客户接受和相信这种分析,并做出相关反应是不容易的,因此,这种模型往往适应于内部的大规模软件开发
    2. 如果执行风险分析将大大影响项目的利润,那么进行风险分析毫无意义,因此,螺旋模型只适合于大规模软件项目
    3. 软件开发人员应该擅长寻找可能的风险,准确地分析风险,否则将会带来更大的风险

    一个阶段首先是确定该阶段的目标,完成这些目标的选择方案及其约束条件,然后从风险角度分析方案的开发策略,努力排除各种潜在的风险,有时需要通过建造原型来完成。如果某些风险不能排除,该方案立即终止,否则启动下一个开发步骤。最后,评价该阶段的结果,并设计下一个阶段

    展开全文
  • 对象模型,动态模型,功能模型

    千次阅读 2017-06-10 11:44:45
    第七周作业——用面向对象方法分析研究书中习题2第3题中描述的机票预订系统,试建立它的对象模型、动态模型和功能模型。   来源:博客园  2016-04-18 对象模型如下: 动态模型如下: 功能模型...
    第七周作业——用面向对象方法分析研究书中习题2第3题中描述的机票预订系统,试建立它的对象模型、动态模型和功能模型。  
    
          来源:博客园    2016-04-18

    对象模型如下:

    动态模型如下:

    功能模型如下:

    展开全文
  • c++对象模型知识久负盛名,在c++界具有很高的美誉度,这方面知识的学习,更是被诸多颇具开发实力的行业前辈倾力推荐! 本门课程内容将涉及到很多不被常人所知的 c++对象内部工作原理、底层的一些具体实现机制方面的...
  • 业务模型;UML类图
  • 面向对象分析与设计——对象模型

    千次阅读 2014-10-22 09:18:58
    对象模型  对象模型包括:抽象、封装、模块化、层次结构、类型、并发和持久   2.1 对象模型的演进   OO建立在以前技术的最佳思想之上。两大趋势:小规模→大规模;高级程序设计语言;   2.1.1 程序...
  • 第一章 面向对象及软件建模概述

    千次阅读 2017-12-01 09:03:41
    面向对象的软件建模 n6.统一建模语言UML 1 软件与软件工程  软件: 程序+文档+数据  特点:  (1)软件规模大。  (2)软件开发规范并趋于标准化。  (3)软件开发方法多,有大量的软件工具...
  • java内存模型

    千次阅读 多人点赞 2018-11-09 13:09:55
    java内存模型 下图就是java内存模型,但是一般讨论的时候不会画这个图,一般画的是java内存模型抽象结构图(在下文)。Thread Stack就是java内存模型抽象结构图中的本地内存,Heap就是java内存模型抽象结构图中的主...
  • jvm oop-klass对象模型

    千次阅读 2018-06-10 22:51:49
    jvm对象模型可以从hotspot7的源代码中学习.本文内容都是以jdk7对应的hotspot虚拟机为基础进行分析的. 一.oop-klass的层级关系 首先,从oopsHierarchy.hpp的源代码.看看jvm对象模型的层次结构. 引用Hotspot实战里面...
  • ADO对象模型总结

    千次阅读 热门讨论 2016-05-08 19:26:44
    ADO 简介 ActiveX data Object (取代 dao 和rdo) 通过 OLE DB 实现不同类型数据源的访问  有三种类型  数据提供者:将特殊数据转化成...ADO对象模型 七个 三个独立对象 四个依赖独立对象才能使用 Connection 连接对象
  • 浅谈 Excel 对象模型

    千次阅读 2016-02-23 17:14:14
    不论您采用何种方式来开发Excel应用程序,了解Excel对象模型尤其重要,这些对象是您与Excel进行交互的基石。据不完全统计,Excel的对象模型中有270多个对象及超过5000多个属性和方法。通过这些对象及方法,您可以...
  • AutoCAD对象模型

    千次阅读 2015-04-21 16:37:33
     对象是 AutoCAD ActiveX 接口的主要构造块,每一个显示的对象均精确代表一个 AutoCAD 组件。AutoCAD ActiveX 接口的主要对象有:  • 直线、圆弧、文字和标注等图形对象。  • 线型与标注样式等样式设置对象 ...
  • Qt 5——对象模型(对象树)

    千次阅读 2021-02-18 21:23:17
    文章目录对象模型(对象树)对象树与内存问题 对象模型(对象树) 在Qt中创建对象的时候会提供一个Parent对象指针,下面来解释这个parent到底是干什么的。 QObject是以对象树的形式组织起来的。 当你创建一个...
  • Java基础知识面试题(2020最新版)

    万次阅读 多人点赞 2020-02-19 12:11:27
    Java 中,如何跳出当前的多重嵌套循环 面向对象 面向对象概述 面向对象和面向过程的区别 面向对象三大特性 面向对象的特征有哪些方面 什么是多态机制?Java语言是如何实现多态的? 面向对象五大基本原则是什么(可选...
  • 试述数据模型的概念,数据模型作用和数据模型的三个要素: 答案: 模型是对现实世界的抽象。在数据库技术中,表示实体类型及实体类型间联系的模型称为“数据模型”。 数据模型是数据库管理的教学形式框架,是...
  • 因为想在笔记中夹杂这篇文章中部分内容,所以进行了还是比较多的引用,核心的地方还是自己写的 可以一直接调转到深入理解Java的OOP ...名称:Object-Oriented Analysis:面向对象分析方法 OOA是指...
  • VBSCRIPT文档对象模型

    2007-08-24 09:48:41
    文档对象模型(DOM)属于VBScript客户端扩展部分,在文档对象模型中提供了大量的对象,这些对象应用于浏览器上,这些对象在我们编写脚本时发挥着重要的作用
  • C++对象模型之简述C++对象的内存布局

    万次阅读 多人点赞 2015-05-22 02:28:26
    那么,它们如何影响C++的对象在内存中的分布呢? 当存在继承的情况下,其内存分布又是如何呢? 下面就一个非常简单的类,通过逐渐向其中加入各种成员,来逐一分析上述两种成员变量及三种成员函数对类的对象的内存...
  • 面向对象建模得到的模型包含系统的3个要素:静态结构(对象模型)、交互次序(动态模型)和数据变换(功能模型)。  这三个模型解决的问题不同,其重要程度也不同:几乎解决任何一个问题,都需要从客观世界实体及...
  • RBF神经网络参考模型自适应MATLAB实现(分析)

    万次阅读 多人点赞 2018-12-06 17:22:48
    一般的神经网络的作用是去做一些分类,回归等工作,能够根据系统输入,在训练好的神经网络系统下分类或者预测出系统的输出,我主要的工作不是做分类器,这个方法主要运用在机器视觉上,我的研究生主要工作是逼近一个...
  • 图说C++对象模型:对象内存布局详解

    千次阅读 多人点赞 2018-02-20 22:09:07
    何为C++对象模型?2.文章内容简介3.理解虚函数表3.1.多态与虚表3.2.使用指针访问虚表4.对象模型概述4.1.简单对象模型4.2.表格驱动模型4.3.非继承下的C++对象模型5.继承下的C++对象模型5.1.单继承5.2.多继承6.虚继承...
  • 浏览器对象模型

    千次阅读 2013-04-09 19:36:32
    BOM-浏览器对象模型:提供了独立于内容而与浏览器窗口进行交互的对象,window对象是整个BOM的核心,所有对象和集合都以某种方式回接到window对象 window对象 window对象表示整个浏览器窗口,但...
  • 《深入理解c++对象内存模型

    千次阅读 2018-03-05 17:06:46
    《c++对象内存模型》读书笔记这本书大二第一次接触,刚开始由于功力不够不能很好的消化这本书的内功,多读几遍就会对自己的语言思想有很大的提升。这本书出版很久了,但一直没被淘汰。记录自己的学习笔记,温故知新...
  • 1.引言  经过几十年的发展,今天的GIS系统已经具备了较强的数据存贮、管理和输入输出功能,但目前大多数的...为此,作者为现有GIS软件总结了两种典型的数据模型[1]:拓扑关系数据模型和面向实体的数据模型,并分析了
  • 单一继承且无虚函数的对象模型 class A { public: int foo( ) { return val ; } static int staFun( ) { return staVal ; } static int staVal ; private: int val ; char bit1 ;
  • 1. 什么是JS对象?在JS中,对象是一组无序属性的集合。其中,属性可以是基本数据类型、引用类型、函数。如下面这个对象的例子:var chai={ name : "柴毛毛", // 属性为基本数据类型 perosn : { // 属性为引用类型 ...
  • C++对象模型之RTTI的实现原理

    万次阅读 多人点赞 2015-06-14 03:11:19
    C++引入这个机制是为了让程序在运行时能根据基类的指针或引用来获得该指针或引用所指的对象的实际类型。但是现在RTTI的类型识别已经不限于此了,它还能通过typeid操作符识别出所有的基本类型(int,指针等)的变量...
  • 数据模型是数据库中用来对现实世界进行抽象的工具,是数据库中用于提供信息表示和操作手段的形式架构。一般地讲,数据模型是严格定义... 是研究的对象类型的集合,是对系统静态特性的描述。 (2)数据操作 ...
  • 建立动态模型 开发交互式系统,动态模型非常重要 步骤: 编写典型交互行为脚本(依据用例描述) 从脚本中提取事件及相关对象,用顺序图表达 确定对象状态及状态间转换关系,用状态图描绘 结合ATM系统的实例,介绍...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 454,774
精华内容 181,909
关键字:

对象模型的作用