62
Concerning Objects 中中中中中中中中中中中中 中中 2010 中 05 中

Concerning Objects

Embed Size (px)

DESCRIPTION

Concerning Objects. 中国科学技术大学软件学院 孟宁. 2010年05月. previously on this course. Design is 设计是 The creative process to transform the problem into a solution将问题转化成解决方案的创造性的活动 The description of a solution对解决方案的的描述 Two stages of design设计的两个阶段 Conceptual Design概念设计 Technical Design技术设计 - PowerPoint PPT Presentation

Citation preview

Concerning Objects

中国科学技术大学软件学院孟宁

2010年 05月

previously on this course

♦ Design is 设计是– The creative process to transform the problem into a s

olution将问题转化成解决方案的创造性的活动– The description of a solution对解决方案的的描述

♦ Two stages of design设计的两个阶段– Conceptual Design概念设计– Technical Design技术设计

♦ Five ways to create designs♦ Architectural styles and strategies♦ Coupling耦合性与 Cohesion内聚♦ 提高模块独立性♦ Documenting the Design

需求与设计

Agenda

♦ Previously on this course♦ What is OO?♦ The OO Development Process♦ Use Cases♦ Representing OO:An Example Using UML♦ OO System Design♦ OO Program Design♦ OO Measurement

What is OO?

♦ 面向对象 Object Orientation是一种把问题和它的解决方案作为对象的集合组织在一起的软件开发方法;数据结构和操作都包含在对象的描述中。

♦ 面向对象描述 OO Representation的七的特征: identity,abstraction,classification,encapsulation,inheritance,polymorphism,and persistence.

OO Representation的七的特征♦ Identity标识

– 涉及将数据组成离散的、可辨别的称为对象的实体,单个对象有与它相关的状态和行为;在面向对象的系统中每一个对象通常都有一个名字,也叫做一个参考或句柄;名字用来区别不同的对象。

♦ Abstraction抽象– 抽象形成了一个表示不同的系统全貌是怎样关联起来的分级结构。

♦ Classification分类– 用来给某些有着共同属性和行为的对象分组

♦ Encapsulation封装– 类封装了某个对象的行为和属性,隐藏了具体的实现

♦ Inheritance继承– 一种类的层次结构,根据类之间的相同或差异来构造的

♦ Polymorphism多态– 同样的行为在不同的类或子类中的不同表现

♦ Persistence持久性– 某个对象的名称、状态和行为超越时间或空间的能力,换句话说,对象的名字,状态和行为在对象被改变时保存。

Examples of objects grouped into classes

框表示某个对象的名称、属性和行为

Objects and classes

♦ Every object has a name (also called a reference or handle)每一个对象都有一个名称(也叫引用或句柄)

♦ Objects can have attributes (such as color, size, location)对象具有属性(如颜色、大小、位置)

♦ Objects can have operations or behaviors (such as takeoff, land, repair)对象具有作用或行为(如起飞,着陆、修理)

♦ Each object is an instance of a class每一个对象都是某个类的实例

♦ A specific implementation of an operation for a certain class is called a method某个类的操作的特定实现称为方法

Object的特点♦ 以数据为中心;♦ 对象是主动的;♦ 属性和操作封装,信息是隐蔽的。♦ 对象独立处理自身的数据,并通过消息传递进行通信,具有并行的性质

♦ 高模块独立性,对象是 OO软件的基本模块,低耦合,高内聚。

♦ 对象具有唯一识别的功能,行为比较丰富♦ 对象必须参与一个或多个类

Class类♦ 定义

– 具有相同结构、操作,并遵守相同约束规则的对象聚合成一组,这组对象集合称为对象类,简称类。

♦ 类层次( Hierarchy)– 子类、派生类– 父类、基类、超类

♦ 类实例( Instance)– 由某个特定类所描述的一个具体对象。– 如类抽象“中国人”的一个实例“王志东”

Forming a hierarchy

柴油

汽油汽油柴油

消息、方法与属性♦ 消息就是某个操作的规格说明,其组成:

– 接收消息的对象– 消息名(消息选择符)– 零个、一个或多个变元例如:对于类 Circle的一个实例MyCircle,如果使其以绿色在屏

幕上显示,MyCircle . Show ( GREEN );♦ 方法(操作、服务)

– 对象所能执行的操作,即类中所定义的服务。它是对操作算法和响应消息办法的描述。

– 在类 Circle中给出成员函数 Show (int color)的定义。♦ 属性是类中所定义的数据,是实体性质的抽象

– 类实例都有其特有的属性值,如类 Circle定义的圆心、半径和颜色。

Inheritance继承♦ 继承性的含义

– 对象共享所在类的结构、操作和约束等语义特性– 多层类层次的继承传递性– 类的继承(多重继承)

♦ 继承性的作用– 继承性使所建立的软件系统具有开放性– 继承是信息组织和分类的有效方法– 提高代码可重用率和可靠性,降低开发工作量

多态与重载♦ 多态性含义

– 把相同的操作施加于不同类型的对象,获得不同的结果

♦ 重载 Overloading– 运算符重载:同一运算符作用于多种数据类型上。– 函数名重载:相同的方法作用于不同的对象类型产生不同的行为效果。

– 虚函数( Virtual)

The OO Development Process

♦ 面向对象开发的一个优点是语言的一致性。我们可以用同样的方式来描述问题和解决方法:类,对象,方法,属性和行为。在整个开发过程中,我们应该具有术语和全局的一致性。

♦ 用面向对象表示法来描述类有三个概貌:静态,动态,限制。静态的视图包括对象的描述,属性,行为和相互之间的关系。动态的视图描述了通信,控制 /定时,和状态及状态的变化。限制描述了结构上的限制和动态行为。

♦ OO Requirements♦ OO Design♦ OO Coding and Testing

OO Requirements

♦ 面向对象的需求分析通常使用用户的语言来描述并且讨论了在应用领域中的概念和情况。

♦ 无论开发者打算怎样实现系统,需求的定义都可以作为一个对象来独立表示。

OO Design

♦ Usually uses an OO requirements representation通常使用一种OO需求表达

♦ System design identifies and represents objects and classes, plus details of each objects attributes and behaviors系统设计确定和表示对象与类,加上每个对象的属性和行为的详细资料

♦ System design also identifies interactions and relationships系统设计也要确定(对象和类的)交互和关系

♦ Program design inserts computational features in the models 程序设计插入计算特征到模块中

♦ Program design inserts class library details 程序设计插入类库的细节

♦ Program design considers nonfunctional requirements to enhance design 程序设计考虑非功能性需求以增强设计

OO Coding and Testing

♦ 编码通过把模型翻译成一种面向对象变成语言来进行。

测试小组测试

编码人员测试

Use Cases

♦ 确定系统边界♦ 确定参与者(用户及其分组、外部系统

等)♦ 尽可能多地发掘用例

– 各参与者如何分别使用系统提供的功能♦ 将用例进行合并、分类、分层

进一步检查用例图,找出现有的和潜在的问题

♦ 用例是否使用了正确的术语?♦ 活动是否和观点匹配?♦ 对活动和执行者的描述是否清楚完整?♦ 是否遗漏了对候补参与者的描述?♦ 是否描述了某个外部系统或一组用户,但实际上没有参与系统的某个活动或交互?

♦ 每个活动的开始和结束是否明确?

Representing OO: UML

♦ UML 融合了 Booch、 OMT和 OOSE方法中的基本概念,而且这些基本概念与其他面向对象技术中的基本概念大多相同 ;

♦ UML不仅仅是上述方法的简单汇合,而是扩展了现有方法的应用范围 ;

♦ UML是标准的建模语言 , 而不是标准的开发过程。尽管 UML的应用必然以系统的开发过程为背景 , 但由于不同的组织和不同的应用领域 ,需要采取不同的开发过程。

UML软件开发过程♦ Rational 公司 1998年发布了名为 Rational Unified

Process的面向对象软件开发过程框架。♦ 该框架将软件开发过程分为四各阶段:

– 初始阶段– 细化阶段– 构造阶段– 移交阶段

♦ 该过程框架强调的原则:– 用例驱动 (Use Case Driven)– 以架构为中心 (Architecture-Centric)– 迭代增量 (Iterative and Incremental)

模型内容的组织和 UML表述

♦ UML的用于描述模型的基本词汇 (“构造块” ):– 事物 (Things)

– 关系 (Relationships)

– 图 (Diagrames)

事物 (Things)

♦ 结构事物 (Structure Thing)– UML中的静态元素:类、接口、协作等

♦ 行为事物 (Behavioral Thing)– UML中的静态元素:交互 (Interaction)、状态机

(State Machine)

♦ 组织事物 (Grouping Thing)– UML的分组元素:包 (Package)

♦ 注释事物 (Annotation Thing)– UML的分组元素:注释 (Note)

关系 (Relationships)

♦ 关系 (Relationships)– 关联关系 (Association)

• 元素间的结构化关系,是一种弱关系,被关联的元素间通常可以被独立的考虑。 – 依赖关系 (Dependency)

• 元素 A的变化会影响元素 B,但反之不成立,那么 B和 A的关系是依赖关系, B 依赖A。

– 泛化关系 (Generalization)• 归纳、类属关系,即通常所说的继承关系。

– 聚合关系 (Aggregation)• 关联关系的一种特例,表示部分和整体(整体 has a 部分)的关系。

– 组合关系 (Composition)• 组合是聚合关系的变种,表示元素间更强的聚合关系。对于组合关系,如果整体被破坏则个体一定会被破坏,而聚合的个体则可能是被多个整体所共享的,不一定会随着某个整体的破坏而被破坏。

– 实现关系 (Realization)• 元素 A定义一个约定,元素 B实现这个约定,则 B和 A的关系是实现关系, B 实现

A。这个关系最常用于接口。

图 (Diagrames)图名称 图定义 图性质

1 类图 一组类、接口、协作及它们的关系 静态图2 对象图 一组对象及它们的关系 静态图3 用例图 一组用例、参与者及它们的关系 静态图4 顺序图 一个交互,强调消息的时间顺序 动态图5 协作图 一个交互,强调消息发送和接受的对象的结

构组织动态图

6 状态图 一个状态机,强调对象按事件排序的行为 动态图

7 活动图 一个状态机,强调从活动到活动的流动 动态图

8 构件图 一组构件及关系 静态图

9 部署图 一组接点及它们的关系 静态图包图 : 包中的类以及包与包之间的关系 (静态图 )

UML

关系

实现关系

泛化关系

依赖关系

关联关系

活动图

组件

用例图类图对象图

静态图

构件图

动态图

顺序图

实施图

状态图

协作图

事物

结构事物

行为事物

组织事物

辅助事物

交互状态机

包 注释

节点

活动类

协作

接口类用

聚合关系

组合关系

UML的 9个模型

序号 模型名称 模型定义和解释1 业务模型 建立业务流程的抽象2 领域模型 建立系统的语境 (业务操作规

则 )

3 用例模型 建立系统的功能需求4 分析模型 建立概念设计(逻辑设计)5 设计模型 建立问题的解决方案6 过程模型 建立系统的并发和同步机制7 部署模型 建立系统的硬件拓扑网络结构8 实现模型 建立的软硬件配置设计9 测试模型 建立系统的测试计划设计

UML的 5种视图♦ 在 UML 中,系统的表示使用 5种不同的“视图” ( UML定义的五类图,共 9 种图形),它们可以从软件开发的不同阶段、不同视角 和不同层次对所开发的系统进行描述。每个视图由一组图定义。– 用户模型视图 - 用例图,从外部描述系统的功能– 结构模型视图 - 类图和对象图,描述类、对象以及它们之间的关系等静态结构,用来支持系统的功能需求,即描述系统内部的功能是如何设计的。

– 行为模型视图 - 序列图、协作图、状态图和活动图,描述形成系统并发与同步机制的线程和进程,关注的重点是系统的性能、易伸缩性和系统吞吐量等非功能性需求。

– 实现模型视图 - 构件图,用来描述系统的实现模块、它们之间的依赖关系以及资源分配情况,主要用于系统的配置管理。

– 环境模型视图 - 部署图,用来描述物理系统的硬件拓扑结构,描述软件构件到物理节点的映射。

UML用于软件系统开发的不同阶段

♦ 用户需求:– 可使用用例图来捕获用户的需求,用例图从用户的角度来描述系统的功能,表示了操作者与系统的一个交互过程。

♦ 系统分析:– 可使用类图来描述系统的 静态模型,为了实现用例、类之间需要协作,可用动态模型的状态图、顺序图、协作图来描述。 分析阶段只考虑问题域的对象建模。需要通过静态模型和动态模型来描述系统结构和系统行为。

♦ 系统设计:– 对类进行细化,如引入人机交互的接口类、处理数据类、处理通信类。

♦ 系统实现:– 用构件图描述代码构件的物理结构以及构件之间的关系。用配置图来描述和定义系统中软硬件的物理通信结构。

♦ 测试:– 可使用类图进行单元测试;可使用构件图、协作图进行集成测试;可使用用例图进行确认测试。

UML and the OO process

♦ Workflow diagrams 工作流图♦ Object model 对象模型♦ Sequence diagrams 顺序图♦ Collaboration diagrams 协作图♦ Package diagrams 包图♦ Component diagrams 组件图♦ Deployment diagrams 配置图

How UML supports the development process

UML class diagrams

Class

Attribute

operation()

Bill (帐单)

Issue_date : Date (发布日期)

Payment_date : Date (支付日期)

Price( ) (价格)

Taxes( ) (税款)

Customers( ) (顾客)

Purchase( ) (购买)

Add_to_bill( customer, amount,date)

帐单的类框图 继承关系

类关联

Royal Service Station Requirements

♦ 1. 皇家服务站为顾客提供三种类型的服务:加油,车辆管理和停车。也就是说,一个顾客可以向他自己车辆的槽中加油,可以进行车辆维护,或者能够在停车场中停放车辆。一个顾客可以选择在购买时自动付账或是按月账单付账。无论是那种情况,顾客都可以用现金,信用卡或个人支票支付。皇家服务站燃料出售时,根据每加仑价格,而这个价格又依赖于燃料是否是柴油的,标准的或是高级的。服务的价格是根据部件和劳动力的费用。停车的价格根据天,周和月的比率。燃料,服务维护,部件和停车的价格都可能变动;只有站长Manny 可以改动价格。根据他的决定权,可以指定给某一个顾客以打折的待遇;这个折扣也可能根据不同的顾客有所变动。而且所有的购买活动要缴纳5%的税。

Royal Service Station Requirements

♦ 2. 系统必须跟踪每月的账单情况和加油站提供的产品和服务情况。跟踪的结果要报告给站管理员。

♦ 3. 站管理员使用系统控制清单。系统会在库存少的时候提出警告,并自动定购新的部件和燃料。

♦ 4. 系统将跟踪信用记录,并且对其过期的用户发出警告信。账单在顾客购买后的每个月的第一天发给顾客。任何的账单只要在期限后 90 天没有付,就会取消顾客的会员资格。

♦ 5. 系统仅用于常规的重复顾客。常规的重复顾客意味着一个顾客可以通过姓名,地址和生日识别,并且他至少每个月在服务站消费一次。

Royal Service Station Requirements

♦ 6. 系统必须处理和其他系统的接口的日期要求。一个信用卡系统用于处理产品和服务的信用卡交易。信用卡系统要使用如下信息:卡号,姓名,到期日期和购买量。在接受这些信息后,信用卡系统证实交易使被允许还是拒绝。部件订购系统接受部件码和数量。他返回部件发送的日期。燃料订购系统要求一个燃料定购的描述,包括燃料类型,加仑量,站名和站的识别码。它返回燃料将被发送的日期。

♦ 7. 系统必须纪录税和相关信息,包括每一个顾客付的税,和每项的税。

♦ 8. 站长必须能够按照要求复查税纪录。♦ 9. 系统会为用户提供定期信息,提醒他们车辆到时候该

维修了。通常,维护需要每六个月一次。

Royal Service Station Requirements

♦ 10.顾客可以在站停车场中租车位。每位用户必须从系统中要求一个可获得的车位。站长能够查看有关车位的占用情况的月纪录。

♦ 11.系统维护一个统计信息库,可访问统计数和顾客姓名。

♦ 12.站长必须能够按照要求复查统计信息。♦ 13.系统能够按要求报告价格的打折分析情况给站长。♦ 14.系统可以自动通知休眠账目的所有者。也就是,如

果顾客超过两个月没有在站内进行消费的话,会被通知。♦ 15.系统不可用时间不能超过 24 小时。♦ 16.系统必须对顾客的信息进行保密。

Package diagrams♦ View the system as

a small collection of the packages将系统看作是包的集合

Sequence diagram for the refuel use case

Customer Service StationCredit Card

SystemPurchase Refuel

refuel( )

Verify customer(credit_card_sum, amount )

new_purchase (customer, refuel,

date, gallons)new_refuel (customer, date, gallons)

cancelcredit cardtransaction transaction

okay

pay_by_cash( )

object’s lifeline

start or end of a message

message

message name

condition

object

Collaboration diagram for the parking use case

Customer

Parking Space

Purchase

Parking

Service Station

1: parking( )

2: next_available( )

3: parking_at(location)

4: new_purchase(customer, parking, date, location)

5: new_parking(customer, location)

State diagrams for inventory class

Activity diagrams for inventory class

Program design considerations

♦ 如何将概念设计变成技术设计?♦ User interface requirements用户界面需求

–将概念设计直观化♦ Data structure and management details数据结构和管理细节–将概念设计可编程

♦ Nonfunctional requirements 非功能性需求♦ Reused components复用组件♦ Reusable components可复用的组件

OO Measurement

♦ 局域性(局部化)♦ 封装性♦ 信息隐藏♦ 继承性♦ 抽象

Localization

♦ 局域性 (Localization)是指信息被集中在一个程序内的方式。 – ( 1)传统方法:数据与过程分离,功能分解和功能信息局域化。其典型的实现形式为过程模块,工作时用数据驱动功能。

– 此时的量度放在功能内部结构和复杂性上(如模块规模、聚合度、环路复杂性等)或放在该功能与其他功能(模块)的耦合方式上。

– ( 2) OO方法:局域性基于对象,因为类是 OO系统的基本单元,对象封装数据和过程,因此应把类(对象)作为一个完整实体来量度。

– 另外,操作(功能)和类之间的关联是一对一的。因此,在考虑类合作中的量度时,必须能适应一对多和多对一的关联。

封装性♦ 封装 (Encapsulation)是指一个项集合的包装。

– ( 1)传统方法:记录、数组,只有数据没有过程,为低层次的封装;过程、函数、子例程和段,则只有过程没有数据,为中层次的封装。其量度的重点分别在代码行的数据和环路的复杂性。

– ( 2) OO方法: OO系统封装拥有类的职责(操作),包括类的属性、操作和特定的类属性值定义的类(对象)的状态。其量度和重点不是单一的模块,而是包含数据(属性)和过程(操作)的包。

信息隐藏♦ 信息隐藏 (Information hiding)是指隐藏(删除)了程序构件操作的细节,只将访问该构件所必要的信息提供给访问该构件的其他构件。 – 在这一点上, OO方法和传统方法基本一致。因此, OO系统应支持信息隐藏,除提供隐藏等级说明的量度外,还应提供 OO设计质量指标。

继承性♦ 继承性 (Inheritance)是指一个对象的属性和操作能够传递给其他对象的机制。继承性的发生贯穿于一个类的所有层次。 – 一般来说,传统软件不支持这种特性。而对

OO系统来说,继承性是一个关键性的特性。因此,很多 OO系统的量度都以此为重点,如子的数量(类的直接实例数量),父的数量(直接上一代数量),以及类的嵌套层次(在一个继承层次中,类的深度)。

抽象♦ 抽象 (Abstraction) 使设计者只关心一个程序构件的主要细节(数据和过程两者),而不考虑底层的细节。 – 抽象是一种相对概念,在 OO和传统开发方法中都被

采用。如处于抽象的较高层次时,我们可忽略更多的细节,当处于抽象的较低层次时,可以引入更多的细节,即提供一个关于概念或项的更详细的看法。

– OO 量度可用一个类度量的项来表示抽象,如每个应用类的实例化的数量、每个应用类被参数化的数量,以及类被参数化与未被参数化的比例等。

面向类的度量♦ 类是 OO系统的基本单元。类、类的层次和类的合作的度量,对软件工程设计质量的评价是十分重要的。

OO 测试的量度1. 封装性

– (1) 方法(操作与服务)中聚合的不足 LCOM LCOM的值越高,表示更多的状态必须进行测试,才能保证方法不产生副作用。

– (2) 公共与私有的百分比 PAP (Percent Public and Protected) 公共属性从其他类继承,所以这些类是可见的。私有属性是专属的,为一特定子类所拥有。这种量度说明类的公共属性的百分比, PAP的值高就可能增加类间的副作用。

– (3) 数据成员的公共访问 PAD (Public Access to Data Member) 这种量度说明可访问其他类属性的类的数量,即一种封装的破坏。 PAD的值高可能导致类间的副作用。所以,测试的设计必须保证每一种这样的副作用能够被发现。

2. 继承性 – (1) 根类的数量 NOR (Number of Root Classes) 这种量

度是在设计模型中,描述性质各不相同的类层次数量的计算方法。对每一个根类及其子类的层次必须开发相应的测试序列。随着 NOR的增大,测试工作量也相应增加。

– (2) 扇入 FIN (Fan In) 当扇入用于 OO 情况时,扇入是一种多重继承的指标。 FIN大于 1 ,说明一个类不只从属一个根类,而是继承更多的根类的属性和操作。

– (3) 子的数量 NOC (Number of Children)和继承树的深度 DIT (Depth of the Inheritance Tree) 正如在 OO 测试中讨论的,超类的方法(操作、服务)将不得不为每个子类进行重新测试。

OO项目的量度♦ 项目管理人员的任务就是计划、协调、跟踪和控

制一个软件项目的进行。其中主要问题就是对软件的实现规模进行估算。因为规模与工作量和开发时间成正比。

♦ (1) 脚本的数量 NSS (Number of Scenario Scripts) 脚本的数量或使用用例与满足需求所要求的类的数量、每个类的状态的数量,以及方法(操作)、属性和合作的数量成正比。所以, NSS是程序规模的重要指标。

♦ (2) 关键类的数量 NKC (Number of Key Classes) 关键类一般都集中在问题的事务域上,而且它通过重用来实现的可能性很小。因此, NKC的值高表明实际的开发工作还处于初期阶段。 Lorenz和 Kidd 认为,在一般的 OO系统中,关键类应在 20%~ 40%,而其他类支持底层结构( GUI、通信、数据库等)。

♦ (3) 子系统的数量 NSUB (Number of Subsystems) 子系统的数量能对资源分配、进度安排(特别强调采用并行开发)及整个集成的工作量提供更好的了解。

♦ 脚本的数量 NSS、关键类的数量 NKC和子系统的数量 NSUB的量度还可以用来收集与过去 OO项目及其整个项目和单个过程活动(如 OOA、 OOD、 OOP和OOT)相关的工作的花费。这些数据也可以与前面讨论过的设计量度一起用来计算生产率量度,如每个开发人员开发类的平均值等。总之,这些量度可以用于估算当前项目的工作量、开发时间、使用人员和其他信息。

Homework-4

♦ System Design– 有 5种设计思路:Modular decomposition模块分解 \Data-ori

ented decomposition面向数据的分解 \Event-oriented decomposition面向事件的分解 \Outside-in design由外而内的设计 \Object-oriented design OO设计,选择其中 3种来尝试构造您的项目的系统设计,其中必须包括 OO设计。

– 每种设计思路至少分两级抽象视图来描述,必须使用图形化的描述方法,也就是说不少于 6个图形分别从 3个视角来描述系统。

– 比较选用的 3种分解设计思路,分别解释各自的优缺点,总结项目系统设计的优点和不足。

– 请于 2010年 5月 20 日提交

Five ways to create designs

♦ Modular decomposition模块分解– 高层的功能描述 ->将功能分配给组件 ->每一个低层组件是如何组织起来的及组件之间的关系

♦ Data-oriented decomposition面向数据的分解– 基于外部数据结构– 一般的数据结构 ->包含的数据元素及其之间的关系

♦ Event-oriented decomposition面向事件的分解– 基于系统必须处理的事件和事件改变系统的状态信息

♦ Outside-in design由外而内的设计– 基于系统的用户输入(属黑盒方法),即系统如何处理每一个输入及产生什么样的输出

♦ Object-oriented design OO设计– 确定对象的类和它们之间的相互关系– 然后描述对象的属性和方法,解释对象之间的关系

谢谢大家!

ReferencesPfleeger, Shari. L., Software Engineering: Theory and Pratice(Second Edition), Higher Education Press, 2001软件工程—实践者的研究方法( Software Engineering-A Practitioner’s Approach) ; (美 ) Roger S. Pressman 著; 机械工业出版社 ISBN: 7-111-07282-0http://code.google.com/p/advancedsoftwareengineering/