目前的情况是,拿到了近战单位,要做远程单位。。
大概是用 creat object这个action。。。
调了一上午bug…sigh
1 2 3 4 5 6 7 8 9 |
conda update anaconda 后提示 ValueError: unsupported format character ')' (0x29) at index 49 |
查到了这个:anaconda update issue
I have narrowed this down to the following packages:
package build psutil-1.2.1 py27_0 hard-link pycparser-2.10 py27_0 hard-link pykit-0.1.0 np18py27_2 hard-link pyparsing-2.0.1 py27_0 hard-link by calling “conda install anaconda” and then successfully installing everything else one at a time.
These four packages consistently exhibit the described behaviour.
(note: pykit depends on pycparser so may itself be ok – can’t tell)
我先把psutil卸载掉,重新update了一下,成功。
1 2 3 4 5 6 7 |
conda remove psutil |
…先随便记录一下好了。。。
安装python pandas pandas
发现之前装caffe的时候…装了这个东西。。。
但是就是检测不到?于是卸载重装。。。。
需要注意的是,如果是python2,要用pip2 install pandas,如果是python3,要用pip3 install pandas.
安装tensorflow…直接sudo pacman -Syu python-tensorflow 即可。。。
然后装好之后检测不到orz…感觉还是pip的安装方式比较靠谱。。。
pip2 install tensorflow
我的环境是python2.7
1 2 3 4 5 6 7 8 9 10 |
# Ubuntu/Linux 64-bit, CPU only, Python 2.7 $ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0-cp27-none-linux_x86_64.whl sudo pip install --upgrade $TF_BINARY_URL |
安装成功。。然后发现。。numpy挂了(?????
SO上给出的建议
感觉之后还会各种遇到不同python版本导致的问题。。。。那就上anaconda好了。。。
试了anaconda…想法挺好。。但是貌似还不成熟.。。比如用anaconda安装numpy会报错orz..
最后解决办法是。。。卸载了python-numpy以及所有依赖python-numpy的a包;卸载了python2-numpy以及所有a依赖python2-numpy的包
然后重新安装了python2-numpy
以及发现。。。还有些坑是shellaa相关的.。。y所以暂时不要用fish了。。。
然后提示Missing required dependencies [‘dateutil’]
解决办法是安装python2-datautil
以及各种pip安装。。都记得要pip2而不是pip
中间缺少一堆库。。。大部分直接安装就好了。。。记得要安装python2对应的版本。。。
然后对于ImportError: No module named tensorboard.plugins
解决办法 是将tensorflow升级到1.0以上(安装之后的版本默认为0.1)
sudo proxychains4 pip2 install tensorflow –upgrade
Freeman链码(弗雷曼链码)是指用曲线起始点的坐标和边界点方向代码来描述曲线或边界的方法,常被用来在图像处理、计算机图形学、模式识别等领域中表示曲线和区域边界。它是一种边界的编码表示法,用边界方向作为编码依据,为简化边界的描述,一般描述的是边界点集。
常用的链码按照中心像素点邻接方向个数的不同,分为4连通链码和8连通链码。4连通链码的邻接点有4个,分别在中心点的上、下、左和右。8连通链码比4连通链码增加了4个斜方向,因为任意一个像素周围均有8个邻接点,而8连通链码正好与像素点的实际情况相符,能够准确地描述中心像素点与其邻接点的信息。因此,8连通链码的使用相对较多。
(a)四方向链码的方向符; (b)八方向链码的方向符。
八链码如下:
1. 链码的定义
按照水平、垂直和两条对角线方向,可以为相邻的两个像素点定义4个方向符:0、1、2、3,分别表示0°、90°、180°和270°四个方向。同样,也可以定义8个方向符:0、1、2、3、4、5、6、7。链码就是用线段的起点加上由这几个方向符所构成的一组数列,通常称之为Freeman链码。用Freeman链码表示曲线时需要曲线的起点,对8链码而言,奇数码和偶数码的对应线段长度不等,规定偶数码单位长度为1,奇数码的单位长度为1.414。
2. 曲线的链码表示
(1)原链码 从边界(曲线)起点S开始,按顺时针方向观察每一线段走向,并用相应的指向符表示,结果就形成表示该边界(曲线)的数码序列,称为原链码,表示为
其中,S表示边界(曲线)的起点坐标,N=4或8时分别表示四链码和八链码。当边界(曲线)闭合时,会回到起点,S可省略。
(2)归一化链码
原链码具有平移不变性(平移时不改变指向符),但当改变起点S时,会得到不同的链码表示,即不具备唯一性。为此可引入归一化链码,其方法是:
对于闭合边界,任选一起点S得到原链码,将链码看作由各方向数构成的n位自然数,将该码按一个方向循环,使其构成的n位自然数最小,此时就形成起点唯一的链码,称为归一化链码,也称为规格化链码。我们将这样转换后所对应的链码起点作为这个边界的归—化链码的起点。
(3)链码的旋转归一化
用链码表示给定目标的边界时,如果目标平移,链码不会发生变化。
但是,如果目标旋转则链码会发生变化。为了得到具有旋转不变性的链码,我们可定义所谓的差分码。链码对应的差分码定义为:
对差分码进行(起点)归一化,就可得到归一化(唯一)的差分码,它具有平移和旋转不变性,也具有唯一性。
3. 边界的形状数表示
由于归一化的差分码既具有唯一性,也具有目标物平移和旋转不变性,因此可用来表示边界,称为形状数。形状数序列的长度(位数)称为形状数的阶,它可作为闭合边界的周长。
如上图所示的目标边界,其
原链码为:42120606454 ,
差分码为 : 6716626617 ,
形状数: 1662661767 ,
形状数的阶为10 。
参考资料:
还是比直接写代码方便点。。。所以不妨学习一个!
以及。。。qt在2017年6月1号发布了5.9。。。所以之前是5.8。。。现在变成5.9了。。。
遇到了修改了ui文件却没有生效的问题。。。
解决办法:
1234567 到项目目录下去执行:uic mainwindow.ui > ui_mainwindow.h
时间测试的qt方法。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
头文件#include <QTime> QTime time; time.start(); // do something qDebug()<<time.elapsed()<<"ms"; (注意单位。。。 |
des的基本搞定了。。。打包。。。
在linux下打包成exe。。。。实在是。。没什么好办法的样子。。。
嘛。转念一想。老师说是打包成可执行文件。。。没说一定是exe啊。。。
然后也许我就零分了呢2333
好了。。我又跑到windows下装了个qt…安装包2.3G,记得要安装编译器…
装好以后。。。开始打包。。。
注意区分:
Qt Widgets Application 和 Qt Quick Application
我的是后者。。。打包方式略有不同。。。
下面引用了详细步骤。。我来说下简略步骤好了。。。
顺便吐槽这工具有点智障。。。文件夹选项不显示后缀名就找不到helloqml 也是有毒。。。
Qt 官方开发环境使用的动态链接库方式,在发布生成的exe程序时,需要复制一大堆 dll,
如果自己去复制dll,很可能丢三落四,导致exe在别的电脑里无法正常运行。
因此 Qt 官方开发环境里自带了一个工具:windeployqt.exe。
以官方 Qt 5.4.0+MinGW 开发环境为例,
从开始菜单–》Qt 5.4.0–》5.4–》MinGW 4.9 (32-bit)–》Qt 5.4 for Desktop (MinGW 4.9 32 bit),可以打开 Qt 命令行,从这里就可以执行 windeployqt 工具。集成开发环境 QtCreator 目前生成图形界面程序 exe 大致可以分为两类:
Qt Widgets Application 和 Qt Quick Application。
下面分别介绍这两类exe 的发布方式。1、Qt Widgets Application可执行程序发布方式
首先用 QtCreator 新建一个 Qt Widgets Application 项目,直接用默认的 QMainWindow 程序就可以了,项目名字假定是 hellomw。
然后以 Release 方式编译生成 exe 程序:
生成的程序运行正常之后,找到项目的生成目录,比如 项目源码路径:
C:\QtPros\hellomw\
它的项目生成目录是
C:\QtPros\build-hellomw-Desktop_Qt_5_4_0_MinGW_32bit-Release\
进入这个文件夹,在进入它的子文件夹 release 里面,找到 hellomw.exe ,
将这个exe 复制到一个新的单独的文件夹里用于发布,比如存到
D:\hellomw\ 文件夹里面。然后从开始菜单打开 Qt 命令行,输入命令 :
cd /d D:\hellomw
然后使用 windeployqt 工具命令:
windeployqt hellomw.exe
然后可以在 D:\hellomw 文件夹里看到 windeployqt 工具自动复制的插件文件夹
和 dll文件、qm文件。这时候得到的就完整的 exe 程序发布集合,依赖关系都解决好了。
把 D:\hellomw 文件夹 打包就可以发布了,不用自己一个个找 dll 文件了。
D:\hellomw 文件夹里的qm文件是多国语言翻译文件,不需要可以删了,
其他的都保留。2、Qt Quick Application发布方式
首先用 QtCreator 新建一个 Qt Quick Application 项目,直接用默认的项目模版,点击下一步生成项目,项目名字假定是 helloqml。
然后以 Release 方式编译生成 exe 程序:
然后找到项目的构建目录,比如项目源码目录 C:\QtPros\helloqml,
它的构建目录是:
C:\QtPros\build-helloqml-Desktop_Qt_5_4_0_MinGW_32bit-Release\
进入这个目录,再进入 release 子文件夹,找到 helloqml.exe ,
复制到一个新的单独的文件夹里面,比如 D:\helloqml\ 文件夹里面。然后从开始菜单打开 Qt 命令行,进入D:\helloqml\文件夹:
cd /d D:\helloqml
然后使用 windeployqt 工具命令:
windeployqt helloqml.exe –qmldir C:\Qt\Qt5.4.0\5.4\mingw491_32\qml
注意不要跟烧包一样照抄上条命令,–qmldir 是指出 Qt 库里面的 qml 文件夹位置,
上面命令里 C:\Qt\Qt5.4.0 是 Qt 官方开发环境安装的文件夹,
C:\Qt\Qt5.4.0\5.4\mingw491_32 是Qt类库的目录(QTDIR),
因此使用的 –qmldir 后面写的是 C:\Qt\Qt5.4.0\5.4\mingw491_32\qml
读者Qt环境安装路径不一样,要根据实际情况修改!然后可以看到 D:\helloqml 文件夹里有一大堆文件,就是 QtQuick程序需要的依赖文件。
将整个 D:\helloqml 文件夹 打包就可以发布出去,在别的电脑上使用。
这个 D:\helloqml 文件夹里的东西很多,看不懂就不要删,老老实实打包发布就行了。
上面是最简单的程序发布,实际复杂程序可能还带一些图片文件、数据库文件、配置文件之类的,可以按自己需要添加这些文件到发布文件夹里面。
update3:
终于知道了正确的学习姿势…
用百度把要用的东西大概描述出来,然后总能找到一个是你要的。。。
然后再去搜关键词。。。
嗯。。百度还是很有用的啊2333
所以现在要把之前写成dialog的几个改回Line edit
update2:
老师说要把输入框中的东西随时选中复制出来check…
QLabel默认好像不具有这种属性啊?
稍微查了下。。。
查到了一个叫setTextInteractionFlags的属性
以及连根拔出了。。
找到了解决办法。。。
1 2 3 4 5 6 7 8 9 10 |
openFileNameLabel = new QLabel; openFileNameLabel->setFrameStyle(frameStyle); openFileNameLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); //添加可选中可复制的交互属性。。。 |
记得要
1 2 3 4 5 6 7 |
#include <QGraphicsTextItem> |
update1:
扶起。。。QFile读中文路径文件毫无问题。。。
换成了cpp的 ifstream就一直报错。。。
由于我还改了其他部分。。。所以。。。
查了好久才发现是ifstream的锅。。。。
把des放了进去。。。
本来加密和解密想就用一个函数用参数调节的。。。
不过看了半天也没太懂。。。这种connnet怎么写。。。
不过对connect的理解更深了一些。。。
信号和槽果然是qt的精髓。。。看起来还算不那么无聊。。。
放一些关于信号和槽的资料好了。。。
然后目前的进度是。。。
des放了进去。。。加密基本没啥问题。。。
但是有个小问题。。。
对于加密过程。。。我是用了一个全局的QString QTextSt来传递信息。。。
对于打开文件。。。过程是file->QString
加密后得到密文文件。。过程是QString -> file
但是解密过程。。。。完全反过来了啊。。。?
在思考怎么写在一起能够不违和。。。。。
先来放一波过程中用到的资料和官方文档好了。
Standard Dialogs Example qt 5.8
更新的部分还是放在最前面好了。。。
convert from QString to char *的时候有个坑。。。
In order to convert a QString to a char*, then you first need to get a latin1 representation of the string by calling toLatin1() on it which will return a QByteArray. Then call data() on the QByteArray to get a pointer to the data stored in the byte array. See the documentation:
See the following example for a demonstration:
举个栗子。。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
int main(int argc, char **argv) { QApplication app(argc, argv); QString str1 = "Test"; QByteArray ba = str1.toLatin1(); const char *c_str2 = ba.data(); printf("str2: %s", c_str2); return app.exec(); } |
Note that it is necessary to store the bytearray before you call data() on it, a call like the following
const char *c_str2 = str2.toLatin1().data();
will make the application crash as the QByteArray has not been stored and hence no longer exists.
嘛。。为了系统安全课来学一波qt…
现在算是写出了一个可以打开文件,保存文件的记事本。。。
接下来要搞定的事情是。。。如何写一个自定义的事件。。。比如计算个开方之类的。。。
放一波代码好了。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
#include <QAction> #include <QMenuBar> #include <QMessageBox> #include <QStatusBar> #include <QToolBar> #include <QDebug> #include <QTextEdit> #include <QFileDialog> #include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { openAction = new QAction(QIcon(":/images/file-open"), tr("&Open..."), this); openAction->setShortcuts(QKeySequence::Open); openAction->setStatusTip(tr("Open an existing file")); saveAction = new QAction(QIcon(":/images/file-open"), tr("&Save..."), this); saveAction->setShortcuts(QKeySequence::Save); saveAction->setStatusTip(tr("Save a new file")); QMenu *file = menuBar()->addMenu(tr("&File")); file->addAction(openAction); file->addAction(saveAction); QToolBar *toolBar = addToolBar(tr("&File")); toolBar->addAction(openAction); toolBar->addAction(saveAction); textEdit = new QTextEdit(this); setCentralWidget(textEdit); connect(openAction, &QAction::triggered, this, &MainWindow::openFile); connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile); } MainWindow::~MainWindow() { } void MainWindow::openFile() { QString path = QFileDialog::getOpenFileName(this, tr("Open File"), ".", tr("Text Files(*.txt)")); if(!path.isEmpty()) { QFile file(path); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { QMessageBox::warning(this, tr("Read File"), tr("Cannot open file:\n%1").arg(path)); return; } QTextStream in(&file); textEdit->setText(in.readAll()); file.close(); } else { QMessageBox::warning(this, tr("Path"), tr("You did not select any file.")); } } void MainWindow::saveFile() { QString path = QFileDialog::getSaveFileName(this, tr("Open File"), ".", tr("Text Files(*.txt)")); if(!path.isEmpty()) { QFile file(path); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { QMessageBox::warning(this, tr("Write File"), tr("Cannot open file:\n%1").arg(path)); return; } QTextStream out(&file); out << textEdit->toPlainText(); file.close(); } else { QMessageBox::warning(this, tr("Path"), tr("You did not select any file.")); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include "mainwindow.h" #include <QApplication> #include <QSpinBox> #include <QSlider> #include <QHBoxLayout> // !!! Qt 5 int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow win; win.show(); return app.exec(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTextEdit> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; void openFile(); void saveFile(); QAction *openAction; QAction *saveAction; QTextEdit *textEdit; }; #endif // MAINWINDOW_H |
大概看了一下午。。。这东西看起来虽然说完全没难度。。。但是还是很麻烦啊。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
Cha1 软件架构概念: 是系统的一个或多个结构,它们由软件组件,组件的外部可见属性以及组件之间的关系组成。 组件的外部可见属性是指其他组件对该组件所做的假设。 软件架构的多个结构: 静态的角度: 模块结构 分析类结构 类结构 动态的角度: 进程结构 数据流 控制流 使用结构 调用结构 层次结构 部署的角度: 物理结构 架构不止是功能需求的结果 Ch2: 需求包含三要素:功能,质量,限制条件 质量属性:系统在其生命周期过程中所表现出来的各种特征 质量属性的关系: 一个质量属性的获取对其他质量属性可能产生正面或者负面的影响。 任何质量属性都不可能在不考虑其他属性情况下单独获取。 质量属性举例: 运行时可见属性:性能,可用性,安全性 维护时可见属性:可修改,可扩展,可移植 易用性: 可学习性 可记忆性 错误避免 错误处理 满意度 质量场景创建的参与人员: 最终用户 系统管理员 维护人员 客户 开发组织 构架本身的质量属性: 一致性 正确性和完整性 可构建性 生成质量属性场景的目的和意义: 帮助构架师生成有意义的质量属性需求 使质量属性需求的描述规范化 某一场景是一类场景的代表,系统将以完全相同的方式做出反应。 构架的商业属性(限制): 上市时间 成本和收益 预期系统生命周期长短 目标市场 推出计划 与老系统的集成 第三章: 软件架构样式的种类: 以数据为中心 数据流 虚拟机 调用-返回 独立组件 C/S 构架的异质性: 局部异质 层次异质 并行异质 ISO/OSI七层参考模型: 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 软件框架: 提取特定领域软件的共性部分形成的体系结构。 框架和架构的关系: 框架不是构架。 构架确定了系统整体结构、层次划分、不同部分之间的协作等设计老驴。 框架比构架更具体,更偏重于技术。 一个框架对应一个架构,一个架构可以有多个框架。 第四章: 架构战术:影响质量属性的设计决策。 架构策略:架构中所采用的战术的集合。 可用性的战术: 错误检测的战术: 回声 心跳 异常 错误恢复的战术: 表决 主动冗余 被动冗余 备件 状态再同步 检查点/回滚 错误预防的战术: 进程监视器 从服务中删除 事物 可修改性的战术: 局部化修改的战术: 维持语义一致性 预期期望的变更 泛化模块 限制可能的选择 防止连锁反应的战术: 信息隐藏 维持现有的接口 添加结构 添加适配器 提供一个占位程序 推迟绑定时间的战术: 运行时注册 配置文件 多态 组件更换 遵守已定义的协议 实施性能的战术: 影响响应时间的两个基本因素: 资源消耗 阻塞时间: 资源争用 资源的可用性 对其他计算的依赖性 控制对资源需求的战术: 减少处理一个事件所需要的资源: 提高计算效率 减少计算开销 减少需要同时处理: 管理事件率 控制采样频率 控制系统的使用: 限制执行时间 限制队列的大小 资源管理的战术: 引入并发 维持数据或计算的多个副本 增加可用资源 资源仲裁常见的调度策略: 先进/先出 固定优先级:语义重要性;时限时间单调;速率单调 动态优先级调度:轮转;时限时间最早优先 静态调度 实施安全性的战术: 用于抵抗攻击的战术: 对用户进行身份验证 对用户进行授权 维护数据的机密性 维护完整性 限制暴露的信息 限制访问 检测攻击的战术: 从攻击中恢复的战术: 回复状态 识别攻击者 易用性的战术: 运行时战术: 维持任务的一个模型 维护用户的一个模型 维护系统的一个模型 设计时战术: 软件架构样式与战术的关系: 软件架构样式是从战略层面解决质量问题,战术是从具体部署上给猪解决质量问题的局部策略。 第五章:设计构架 基于构架的开发步骤: 为软件系统创建一个商业案例 弄清系统需求 构建构架 正确表述此构架,并与有关各方进行交流 对此构架进行分析和评价 实现基于构架的系统并保证与构架相一致 系统维护时,构架文档应同步维护 构架驱动的因素: 功能 质量 部分限制条件(限制条件的某个子集) 良好架构的评判原则(判断题常考): 设计构架过程的建议: 架的设计应该由一门设计师来完成 设计师应该全面掌握对系统的技术需求,以及对各项定性指标的优先级清单。 构架的文档完备,并蚕蛹所有人员认可的文档形式。 构架设计文档应让各风险承担者积极评估。 通过对构架分析,得出明确的定性与定量指标。 构架设计应该有助于具体实现。 允许构架带来一定的资源争用,并给出可行的解决方案。 关于构架的结构的建议: 构架由定义良好的模块组成,各个模块的功能划分应该基于信息隐藏。 模块的划分应体现出相互独立的原则。 把计算机基础结构的特性封装在一定的模块 构架尽量不依赖某个特定版本的商品产品或工具。 产生数据的功能和使用数据的功能应分属于不同的模块。 对并发系统,构架应充分考虑进程与模块结构的不对应。 进程编写要考虑到与特定处理器的关系,并容易改变关系。 构架应尽量采用一些已知的设计模式。 ADD构架设计的步骤: 样本输入 选择要分解的模块 根据下列5个步骤对模块进行求精(重点): 从具体的质量场景和功能需求集合中选择构架驱动因素。 选择满足构架驱动因素的构架模式。 实例化模块并根据用例分配功能,使用多个视图进行表示 定义子模块的接口 验证用例和质量场景并对其进行求精,使它们称为子模块的限制。 对需求进一步分解的每个模块重复上述步骤。 创建骨架系统: 思想:提供一种基本能力,以一种对项目有利的顺序实现系统的功能。 好处: 提高开发效率,鼓舞士气。 能更早发现复杂的依赖关系。 使开发人员更多关注最难实现的部分。 能够缩短系统集成时间,降低其成本,并使集成成本更明确。 便于评审和测试。 步骤: 实现处理构架组件交互的软件部分 选择组件逐步添加到系统中。 逐步进行测试。 架构师的职责: 了解所在组织的业务目标,使架构更好地支持业务目标。 规划产品的开发与严禁 规划和建设架构级的重用etc 分析软件构架的原因(重要): 它是风险承担者之间的交流平台,是早期设计决策的体现,是可传递的模型。 软件质量不可能在软件开发的最后阶段追加上去,必须在设计之初就考虑到。 第七章: 构架评审: 成本: 人员时间成本 构架评审部门的组织开销 构架评审部分要求高级设计人员参与的代价(不就是人员时间成本吗。。。 收益: 及早发现构架中存在的问题 构架的改进 财务收益 强制位评审做准备 捕获构架设计的基本思想 验证需求的有效性 评审实施: 按问题的重要性进行分类 强调那些与偶家相符或相悖的重要问题 必须记载评审中所提的每个问题 构架评审的主要指导原则: 把由独立部门实施的正规的构架评审作为项目开发周期规划的一部分。 选择评审的最佳时间,尽早预审一次。 选择恰当的评审技巧 签署评审合同 限制所要品神的质量属性的个数 要保证评审小组中有构架方面的专家,领域专家,资料员,后勤员。 一定要有系统设计师。 收集各种场景数据,并在此基础上形成评审清单。 第八章: 架构权衡分析法(ATAM): 特点:不仅可以揭示出构架满足特定质量目标的情况,而且可以让我们更清楚地认识质量目标之间的联系。 输入:用场景集合捕获的质量要求。 输出: 简介的框架表述 表述清楚的业务目标 构架决策到质量需求的映射 所确定的敏感点和权衡点集合 有风险决策和无风险决策 风险主题的集合 阶段: 评估小组和项目决策者共同决定评估细节 评估小组收集信息和分析 风险承担着参与评估 评估小组自我检查和改进,提交书面报告 步骤(重点): ATAM方法的表述 商业动机的表述 构架的表述 对构架方法进行分类 生成质量属性效用树 分析构架方法 集体讨论并确定场景优先级 再次分析构架方法 结果的表述 第九章: 文档: 目的与作用:让不同的风险承担者都能快速找到和理解他们需要的信息。 基本原则:从读者的角度出发。 |