存档

文章标签 ‘Architecture’

Daniel-Journey Weekly Dose –2012/2/5

2012年2月5日 admin 没有评论

Windows

Windows 7中Telnet功能安装与测试

Programming

我们什么时候应该使用异常?

错误码

1. 错误信息不丰富
2. 加入错误状态码可能需要改变函数签名
3. 错误状态码可能会被忽略

 

Cloud

谁来拯救云计算

Scalability

Write Through Cache

Cache is a component that will magically store data so that future requests of that same data will not be to the Remote Server, and hence it will improve the performance of our application significantly faster.

Operations

Java应用运维

Architecture

关于排队系统

对事件驱动的消息订阅的再思考

浅谈架构

如果要更正式点定义,架构就是model和pattern,从而把code串成system。而其中最重要的就是design principles (设计原则),即为什么这个问题要用这个而非那个。更文艺点,再结合点美学,也可以叫作design philosophy (设计哲学或理念)。

然后我们来看什么是model和pattern,这两个具体的定义我还没想出来。先说一下比较,model偏宏观,而pattern偏微观;model重抽象描述,而pattern重具体实现。比如,你的系统有一个服务端和一个客户端,那么client/server就是model,而client与server之间的交互方式则是pattern,比如RPC/message、同步/异步,比如用滑动窗口来组织请求与应答等等。当然,这和系统的尺度有关。如果你zoom in到服务端,此时的model可能就是模块的组织关系,而pattern则是调用方式,比如用function call还是event等。

架构是什么:其实"架构", 就是一个人用于解决常见(注意常见)设计问题的特定方法…

经常有人把"架构"说的很玄乎,很虚. 其实"架构", 就是一个人用于解决常见(注意常见)设计问题的特定方法(注意特定的, 但不一定是一个). 遇到问题稍许有些变化, 他能适当的调整自己的常用(注意常用)设计而去适合这个变化的能力. 这就叫:"架构"设计… 也就是说, 架构是:方法论, 是经验, 更是变通能力.

Reactor模式和NIO

Reactor模式,或者叫反应器模式

Java

 

使用Jakarta Commons Pool处理对象池化

对于没有状态的对象(例如String),在重复使用之前,无需进行任何处理;对于有状态的对象(例如StringBuffer),在重复使用之前,就需要把它们恢复到等同于刚刚生成时的状态。由于条件的限制,恢复某个对象的状态的操作不可能实现了的话,就得把这个对象抛弃,改用新创建的实例了。

Java克隆

Java Support for Large Memory Pages

Java HotSpot VM (Virtual Machine) Performance Tuning: Command-line options

Solving OutOfMemoryError (part 5) – JDK Tools

jps -lvm

-m Output the arguments passed to the main method. The output may be null for embedded JVMs.
-l Output the full package name for the application’s main class or the full path name to the application’s JAR file.
-v Output the arguments passed to the JVM.

Daniel-Journey Weekly Dose –2011/1/16

2012年1月16日 admin 没有评论

SOA

服务治理过程演进

LINUX

如何在Linux下来查看OS系统块的大小

getconf PAGESIZE

Java

logback与Log4J的区别

The Trove library provides high speed regular and primitive collections for Java

Put your fat Collections on a diet!

Java Collection Performance

Java Sequential IO Performance
HotSpot虚拟机对象探秘

Low GC in Java: Use primitives instead of wrappers

There are two good reason to use primitives instead of wrappers where possible.

  • Clarity. By using a primitive, you are making it clear that a null value is not appropriate.
  • Performance. Using primitives is often much faster.

Servlet 3.0 新特性详解

  1. 异步处理支持:有了该特性,Servlet 线程不再需要一直阻塞,直到业务处理完毕才能再输出响应,最后才结束该 Servlet 线程。在接收到请求之后,Servlet 线程可以将耗时的操作委派给另一个线程来完成,自己在不生成响应的情况下返回至容器。针对业务处理较耗时的情况,这将大大减少服务器资源的占用,并且提高并发处理速度。
  2. 新增的注解支持:该版本新增了若干注解,用于简化 Servlet、过滤器(Filter)和监听器(Listener)的声明,这使得 web.xml 部署描述文件从该版本开始不再是必选的了。
  3. 可插性支持:熟悉 Struts2 的开发者一定会对其通过插件的方式与包括 Spring 在内的各种常用框架的整合特性记忆犹新。将相应的插件封装成 JAR 包并放在类路径下,Struts2 运行时便能自动加载这些插件。现在 Servlet 3.0 提供了类似的特性,开发者可以通过插件的方式很方便的扩充已有 Web 应用的功能,而不需要修改原有的应用。

Architecture

历届「Jolt Awards」获奖书籍

企业应用架构模式

响应性不同于请求处理,它是系统响应请求的速度有多快。这个指标在许多系统里非常重要,因为对于一些系统而言,如果其响应太慢,用户将难以忍受——尽管其响应时间可能不慢。如果能够在处理真正完成之前就给用户一些信息表明系统已经接到请求,则响应性就会好一些。例如,进展条。

一条关于依赖性的普遍原则:领域层和数据源层绝对不要依赖于表现层。

领域逻辑的组织可以分为三种主要的模式:事务脚本、领域模型以及表模块。

事务脚本是这样一个过程:从表示层获得输入、进行校验和计算处理、将数据存储到数据库中以及调用其他系统的操作等。基本的组织方式是让每个过程对应用户可能做的一个动作。所以,我们可以将这一模型想像成一个动作或业务事务的脚本。每一个动作是由一个过程来驱动。

在领域模型中,不再是由一个过程来控制用户某一动作的逻辑,而是由每一个对象都承担一部分相关逻辑。

在许多方面,表模块是事务脚本和领域模型的一个中间地带。它围绕表而非直接围绕过程来组织领域逻辑,提供了更多的结构,而且更容易发现和移除冗余代码。但是,你无法应用许多在领域模型中可以使用的组织细粒度逻辑结构的技术,例如继承、策略和其他面向对象的设计模式。

通常,序列化LOB(大对象Large OBject)对于用来组成应用程序部分的相对独立对象群而言是最好的。但如果过多使用它,最终会把数据库弄得和事务文件系统差不多。

对于任何继承结构,一般都有三种选择。可以为一个层次中的所有类建立一个表,即单表继承;也可以为每个具体类建立一个表,即具体表继承;或者为这个层次中每一个类建立一个表:类表继承。

这三种方法有利有弊。单表继承浪费空间,但避免了连接操作;具体表继承在超类改变时不得不改变所有表,但它也避免了连接操作,允许从一个表取得一个对象;类表继承需要多个连接操作来载入一个对象,这样通常损失了性能,但它是类和表之间最简单的关系。

如果机器处在屏幕流的控制下,那么你就需要应用控制器;如果这台机器是在用户的控制下,你就不要应用控制器。

在视图方面,可以考虑三种模式:转换视图、模板视图和两步视图。

对任何并发程序的本质来说,仅仅考虑正确性是不够的,还必须考虑灵活性(即有多少并发活动可以同时进行)。人们常常需要牺牲一些正确性以获取更多的灵活性,这取决于失败的严重性和可能性以及人们对并发处理数据的需求。

并发问题有两个非常重要的解决方案:一个是隔离(isolation),一个是不变性(immutability)。

在乐观锁和悲观锁之间进行选择的标准是:冲突的频率与严重性。如果冲突很少,或者冲突的后果不会很严重,那么通常情况下应该选择乐观锁,因为它能得到更好的并发性,而且更容易实现。但是,如果冲突的结果对于用户来说是痛苦的,那么就需要使用悲观锁策略。

超时控制和检测机制处理已经出现的死锁,而其他的方法则尽力防止死锁的发生。

跨越多个请求的事务称为长事务。

在请求开始时启动事务,在请求结束时提交事务,这是请求事务。

另一种方法是尽可能晚打开事务。使用延迟事务时,应在事务外完成读取数据的操作,只在修改数据的时候启动事务。然而,这可能会导致不一致读问题。

当可以并发执行并且结果与以某种顺序依次执行的结果相同时,事务就是可串行化的(serializable)。

如果系统中有很多用户,应该考虑使用集群来提高吞吐率。会话迁移(session migration) 允许一次会话从一台服务器转移到另一台服务器,从而可以由一台服务器处理一个请求,其他服务器处理其他的请求。与其相反的方式是服务器亲和(server affinity),它要求某次特定会话的所有请求只能由同一台服务器处理。

分布对象设计第一定律:不要分布使用对象。

这种情况下,怎样有效利用多处理器资源呢?大多数情况下是使用集群系统。在每一个处理器上都部署所有的对象并在其他几个节点上复制它们。这样一来,每个处理器上的对象只需用到本地调用,从而运行更快。还可以使用细粒度接口来设计对象,从而得到更简单的编程模型和更好的可维护性

分类: 阅读 标签: , , ,

Daniel-Journey Weekly Dose –2011/1/8

2012年1月12日 admin 没有评论

Architecture

Event stream processing

Java

使maven2在下载依赖包的同时下载其源代码包

1. 使用maven命令:mvn dependency:sources 下载依赖包的源代码。
2. 使用参数: -DdownloadSources=true 下载源代码jar。 -DdownloadJavadocs=true 下载javadoc包。

Protocol Buffers, Avro, Thrift & MessagePacks

Thread-Local Allocation Buffers 

HotSpot JVM中的垃圾收集

快速分配
从下文对垃圾收集器的描述中可以看出,在许多情况下,内存中都有大块的连续空闲空间用以满足对象的分配请求。这种情形下的分配操作使用简单的“bump-the-pointer”技术,效率很高。按照这种技术,JVM内部维护一个指针(allocatedTail),它始终指向先前已分配对象的尾部,当新的对象分配请求到来时,只需检查代中剩余空间(从allocatedTail到代尾geneTail)是否足以容纳该对象,并在“是”的情况下更新allocatedTail指针并初始化对象。下面的伪代码具体展示了从连续内存块中分配对象时分配操作的简洁性和高效性:
void * malloc(int n){
if( geneTail – allocatedTail < n )

doGarbageCollection();
void * wasAllocatedTail = allocatedTail;
allocatedTail += n;
return wasAllocatedTail;
}
对于多线程应用,分配操作必须是线程安全的。如果使用全局锁为此提供保证,则分配操作必定成为一个性能瓶颈。基于此,HotSport JVM采用了一种被称为“线程局部分配缓冲区”(Thread-Local Allocation Buffers,TLAB)的技术。该项技术为每个线程提供一个独立的分配缓冲区(伊甸区的一小部分),借此来提高分配操作的吞吐量。因为针对每个TLAB,只有一个线程从中分配对象,故而分配操作可以使用“bump-the-pointer”技术快速完成,而不必使用任何锁机制;只有当线程将其已有TLAB填满并且需要获取一个新的TLAB时,同步才是必须的。同时,为了减少TLAB所带来的空间消耗,还使用了一些其他技术,例如,分配器能够把TLAB的平均大小限制在伊甸区的1%以下。
“bump-the-pointer”和TLAB技术的组合保证了分配操作的高效性,类似new Object()这样的操作在大部分时间内只需要大约10条机器指令即可完成

Java线程的6种状态

NEW

至今尚未启动的线程处于这种状态。

RUNNABLE

正在 Java 虚拟机中执行的线程处于这种状态。处于可运行状态的某一线程正在 Java 虚拟机中运行,但它可能正在等待操作系统中的其他资源,比如处理器。

BLOCKED

受阻塞并且正在等待监视器锁的某一线程的线程状态。处于受阻塞状态的某一线程正在等待监视器锁,以便进入一个同步的块/方法,或者在调用 Object.wait 之后再次进入同步的块/方法。

WAITING

无限期地等待另一个线程来执行某一特定操作的线程处于这种状态。某一线程因为调用下列方法之一而处于等待状态:

1、不带超时值的 Object.wait

2、不带超时值的 Thread.join

3、LockSupport.park

处于等待状态的线程正等待另一个线程,以执行特定操作。 例如,已经在某一对象上调用了 Object.wait() 的线程正等待另一个线程,以便在该对象上调用 Object.notify() 或 Object.notifyAll()。已经调用了 Thread.join() 的线程正在等待指定线程终止。

TIMED_WAITING

具有指定等待时间的某一等待线程的线程状态。某一线程因为调用以下带有指定正等待时间的方法之一而处于定时等待状态:

1、Thread.sleep

2、带有超时值的 Object.wait

3、带有超时值的 Thread.join

4、LockSupport.parkNanos

5、LockSupport.parkUntil

TERMINATED

已终止线程的线程状态。线程已经结束执行。

G1 Garbage Collector

Java关于JIT的原理和相关知识

关于Lazy-UnLocking(Reservation Lock)对Java锁的性能优化

关于JVM的Thin Lock, Fat Lock, SPIN Lock与Tasuki Lock

JVM相关知识

TLAB全称叫 Thread Local Allocation Buffer),Sun JDK为了提高对象生成的效率,在Eden哪里为每一个新创建的线程创造一个这么样的空间。TLAB的大小一般都是由JVM 运行计算得出的,但是可以通过-XX:TLABWasteTargetPercent来设置TLAB可占用的Eden Space
的百分比,默认值为1%。
在TLAB分配内存时不需要加锁,因为在堆上分配内存时候要加锁,所以在TLAB分配时效率快很多。当然 这只是适合小对象分配。其分配细节取决于具体的GC。

Windows

Windows 性能监控

perfmon.msc 性能监视器

Windows uses the term “Privileged Time” to represent kernel or system CPU Utilization.

typeperf

利用TypePerf.exe

LINUX

mpstat使用详解

user 在internal时间段里,用户态的CPU时间(%) ,不包含 nice值为负 进程 usr/total*100

nice 在internal时间段里,nice值为负进程的CPU时间(%) nice/total*100

system 在internal时间段里,核心时间(%) system/total*100

iowait 在internal时间段里,硬盘IO等待时间(%) iowait/total*100

irq 在internal时间段里,软中断时间(%) irq/total*100

soft 在internal时间段里,软中断时间(%) softirq/total*100

idle 在internal时间段里,CPU除去等待磁盘IO操作外的因为任何原因而空闲的时间闲置时间 (%) idle/total*100

intr/s 在internal时间段里,每秒CPU接收的中断的次数 intr/total*100

CPU总的工作时间=total_cur=user+system+nice+idle+iowait+irq+softirq

total_pre=pre_user+ pre_system+ pre_nice+ pre_idle+ pre_iowait+ pre_irq+ pre_softirq

user=user_cur – user_pre

total=total_cur-total_pre

其中_cur 表示当前值,_pre表示interval时间前的值。上表中的所有值可取到两位小数点。

使用pidstat命令监视进程

分类: 阅读 标签: , , ,

Daniel-Journey Weekly Dose –2011/12/4

2011年12月4日 admin 没有评论

Scalability

深入浅出Flashcache(一)

投资

趋势是什么?总听到人说“顺势而为”,其实很多人并没搞清楚。股市的趋势是要分时间周期的,对以周为单位的人来说,最近3周的趋势无疑是下跌的;对于以日为单位的人来说,上周4的日内趋势就是上涨。因此请先确定你的操作频率,以周为单位应该做空,以日为单位在上周4就应该做多,都是可以盈利的!

欧债危机到底是怎么回事

Java

java nio 之MappedByteBuffer

理解Heap Profling名词-Shallow和Retained Sizes

Shallow Size
对象自身占用的内存大小,不包括它引用的对象。
针对非数组类型的对象,它的大小就是对象与它所有的成员变量大小的总和。当然这里面还会包括一些java语言特性的数据存储单元。
针对数组类型的对象,它的大小是数组元素对象的大小总和。

Retained Size
Retained Size=当前对象大小+当前对象可直接或间接引用到的对象的大小总和。(间接引用的含义:A->B->C, C就是间接引用)
换句话说,Retained Size就是当前对象被GC后,从Heap上总共能释放掉的内存。
不过,释放的时候还要排除被GC Roots直接或间接引用的对象。他们暂时不会被被当做Garbage。

LINUX

理解Inode

Architecture

关于复杂事件处理和事件驱动架构的争论

EDA: Event-Driven Architecture事件驱动架构

高性能队列Fqueue的设计和使用实践

Java读写

BufferedOutputStream虽然最快,但是易丢失数据,权衡之下,我们选择了MappedByteBuffer作为我们的文件操作实现

Daniel-Journey Weekly Dose –2011/10/01

2011年10月2日 admin 没有评论

Daniel-Journey Weekly Dose- 2011/7/31

2011年7月31日 admin 没有评论

数据库

MySQL新技术探索与实践

架构和设计

@淘宝聂风:团队大了,很多的工程师一起工作,就会导致代码混乱,难以维护的情况,这样的感觉说是说不出来的,需要规范和协议,制定好规则,该分离就分离,该重构就重构!

@JavaCoding:业务代码混乱是很正常的, 但是, 基础代码一定要精益求精!

操作系统

关于IO的同步,异步,阻塞,非阻塞

Java

Java NIO 选择器(Selector) 知识预备 (linux poll)

项目管理

『Agile Project Management』软件项目成功的十大关键因素:用户参与;高级管理者的支持;清晰的业务目标;优化的范围;敏捷过程;项目管理专家;财务管理;拥有熟练技能的人力资源;正规的方法学;优秀的工具和基础设施。

网络营销

企业电子邮件营销五要素

64945e3djw1djdpgjy5yzj

投资

买进靠耐心,卖出靠决心——巴菲特

美国有位基金经理久仰巴菲特大名,专门去拜访巴菲特。可是在他和巴菲特详细交谈后失望地说,巴菲特只不过是一个“业务投资者”。他的意思是说,巴菲特的主要精力并没有集中在股市上,而是在股市外。

盈利能力最强的公司,往往是那些5年来甚至10年来经营方式一直没有改变的企业。由于经营方式一直不变,企业管理层才有机会不断改善服务,改进产品线,不断提高生产技术。相反,如果公司经验总是发生重大变化,就很有可能会随之经常出现重大失误。

投资和投机是两个经济概念,很不容易分辨,却又迥然不同。这主要看亮点:一是投资行为看重长期的稳定回报,而投机行为着眼于短期内技术性套利;二是投资行为追求双赢的发展途径,而投机行为只能增加未来经济的不确定性。

Facade模式&远程Facade模式

2011年5月2日 admin 没有评论

Facade 模式

Facade(外观)模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用。他是为子系统中的一组接口所提供的一个一致的界面。这在某种意义上与Adapter及Proxy有类似之处,但是,Proxy(代理)注重在为Client-Subject提供一个访问的中间层,如CORBA可为应用程序提供透明访问支持,使应用程序无需去考虑平台及网络造成的差异及其它诸多技术细节;Adapter(适配器)注重对接口的转换与调整;而Facade所面对的往往是多个类或其它程序单元,通过重新组合各类及程序单元,对外提供统一的接口/界面。

在遇到以下情况使用Facade模式

  1. 当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。Facade可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过Facade层。
  2. 客户程序与抽象类的实现部分之间存在着很大的依赖性。引入Facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
  3. 当你需要构建一个层次结构的子系统时,使用Facade模式定义子系统中每层的入口点,如果子系统之间是相互依赖的,你可以让它们仅通过Facade进行通讯,从而简化了它们之间的依赖关系。

Facade模式的优点

  1. 它对客户屏蔽子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。
  2. 它实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的。松耦合关系使得子系统的组件变化不会影响到它的客户。Facade模式有助于建立层次结构系统,也有助于对对象之间的依赖关系分层。Facade模式可以消除复杂的循环依赖关系。这一点在客户程序与子系统是分别实现的时候尤为重要.在大型软件系统中降低编译依赖性至关重要。在子系统类改变时,希望尽量减少重编译工作以节省时间。用Facade可以降低编译依赖性,限制重要系统中较小的变化所需的重编译工作。Facade模式同样也有利于简化系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。

远程外观模式

远程外观模式为细粒度对象提供粗粒度的外观来改进网络上的效率。任何对象可能作为远程对象使用时,经常需要一个粗粒度的接口来减少完成某些任务所需要的调用次数。一个粗粒度的远程外观建立在大量的细粒度之上。所有细粒度对象都没有远程接口,并且远程外观不包括领域逻辑。远程外观所要完成的就是把粗粒度的方法转换到低层的细粒度对象上。

远程外观有有状态和无状态之分。无状态的远程外观可以组成池,这样就可以提高资源的使用率和和效率。

除了提供一个粗粒度的接口以外,远程外观还增加了其他几个功能。例如,它的方法中可以提供安全检查。远程外观同样也提供事务控制。远程外观中的方法可以开始一个事务,当做完需要工作后提交事务。每次调用都是一次完整的事务,应为当结果返回客户的时候,你不会希望这次事务还在运行中,因为这种长时间的运行将会使事务变得效率很低。

分类: 软件设计 标签: ,

如何编写优秀的设计文档

2010年11月14日 admin 4 条评论

不知不觉自己自己做软件开发已经快6年了,虽然工作中离不开编写或者阅读设计文档,而且公司都提供了详尽的设计文档模板,可在具体的工作中对设计文档的编写依然会觉得存在很多的障碍,例如:

  • 不清楚设计文档应该包含哪些内容,该如何组织。
  • 该用什么样的方式来体现自己的设计思路不明确
  • 对设计文档所需要描述的程度没有把握,太概括了起不到效果,而过于详细的描述,又怕浪费太多的时间和精力

在2010年11月12日的一次周会上我们几个童鞋针对一份具体且典型的设计文档进行了一次“从文档的本身来审视一下这篇文档”的讨论,在这次讨论以后,对设计文档的编写有了更进一步的掌握,也就形成了这篇文章。

先说明一下我对“如何编写优秀的设计文档”这个问题的一个总结“从多种视角、分层次并采用合适的形式来编写设计文档”。下面我们逐一展开.

多视角

通常设计文档的编写多数采用的就一个视角——“设计者的视角”来编写文档,在内容上主要是说明设计的最终结果和设计的意图。这就是我们目前“典型性”的设计文档,这样的文档主要是仅仅达到了设计文档编写人员“自圆其说”的效果,离一批优秀的设计文档相差的还很远。一篇优秀的设计文档应该包括以下几个视角:普通文档阅读人员的视角、设计文档评审人员的视角,使用者或二次开发人员的视角,需求方或者产品经理的视角、测试人员的视角。

普通文档阅读人员的视角:普通文档阅读人员至少要求文档结构清晰,目的明确,文章的层次分明等等。

设计文档评审人员的视角:设计文档评审人员在阅读设计文档的时候需要能从设计文档中清晰、直接地了解本次设计所要解决的问题,如果是解决具体问题而进行的设计,就可以对这些问题做一些陈述。这样评审人员和包括以后的文档阅读人员对设计所要解决实际问题就会有一个很好的了解。接下来就是要注意设计或者解决方案在表达时候的效率和效益,这一点我们留到对设计文档的形式描述环节来说明。

使用者和二次开发人员的视角:很多设计为的是解决一组相同的问题,当有其他新的问题解决需需要利用这个设计的时候,使用者或者二次开发人员理所当然的想要从设计文档中得到直接地指导。例如接口的设计文档,要有完整的接口定义、错误码定义,如果有更直接地接口调用样例代码就更好了,如果设计需要进行一些配置,就需要对配置的过程有说明。

需求方或者产品经理:需求方或者产品经理更多的会关注设计文档对那些问题具体问题是如何解决的,而在设计的可扩展性、耦合度的降低等方面不是特别的关注。所以设计文档处理要描述模块、框架、组件的设计以外,还要对实际问题的解决来一个明确的说明,从而让需求方或者产品经理对问题的解决充满信心。

测试人员的视角:从测试人员的视角出发文档中应该要说明设计本身对测试的影响,例如对设计内容对测试内容和范围的影响,设计对分模块和分层设计有哪些帮助和影响。

一篇设计文档只有从“多视角”进行阐述和说明,才能最大程度的满足文档阅读者的需求,给他们想要的答案。

分层次

一篇设计的文档应当要全面阐述设计所要解决的问题、设计所依赖历史背景、设计所需面对的限制和约束以及设计的理由以及遵循的原则。

设计所需解决的问题:通常可以对具体的业务需求和目的进行阐述;如果是对目前存在的设计进行重构和改进,我们也需要对历史设计方案的做介绍和说明,如果新设计方案着重要克服历史设计方案的诟病,那就要对历史方案存在的问题加以阐述和说明。

设计所需面对的限制和约束:很少有系统设计的时候是没有约束和限制的,例如并发的要求、数据量的要求、操作系统的限制、服务器的配置等等。很多时候这些约束和限制影响甚至决定最后的设计方案

还是另外,由于绝大多数设计通常不是build in one Day,通常都有一个设计变迁的过程,如果能够记录设计变迁的过程或者设计决策的理由。这样设计文档在很多场合都会派上用场(以下几点参考至《软件架构师应该知道的97件事》#记录决策理由):

  • 可以作为和开发人员进行沟通的工具,说明应遵循的重要架构原则
  • 当开发人员对架构背后的逻辑提出疑问时,使团队成员能够“就事论事”,甚至能够避免一场“兵变”
  • 向经理和利益相关者说明这样构建软件的确切原因(比如,采用某种较为昂贵的硬件或软件的必要性等)。
  • 把项目移交给下任架构师(你有多少次在接手软件时很疑惑原来的设计者究竟为什么要采用那种做法?)。
  • 逼着你明确说明出理由,有助于确保基础(fundation)是扎实稳固的
  • 如果相关条件发生变化,需要对决策进行重新评估,它可以作为一个起点。

采用合适的形式

    设计文档的内容包含的形式是很多的,例如UML图,表格等等。以UML图为例,设计文档中使用的最多的是时序图和类图。

时序图(Sequence Diagram),亦称为序列图或循序图,是一种UML行为图。它通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作。它可以表示用例的行为顺序,当执行一个用例行为时,时序图中的每条消息对应了一个类操作或状态机中引起转换的触发事件。

类图(Class diagram)是显示了模型的静态结构,特别是模型中存在的类、类的内部结构以及它们与其他类的关系等。类图不显示暂时性信息。

这些专业绘图工具,具有一定的学习成本,以UML图工具为例,用StarUML和Vision制作的UML相差很大,所以最好选择在你的team中普遍掌握的工具加以使用。

除了这些专业的图形以外,用PPT或Word制作的普通图形,在描述系统模块、系统和系统之前的关系时也很有用。

以上是对”如何编写优秀的设计文档”这个话题的一些总结,这点内容倒腾了一个下午才陆续完成的,感觉“分层次”和“采用合适的形式”这两点总结的比较简单,先写下来,以后再补充完善。

分类: 软件设计 标签:

《软件架构师应该知道的97件》阅读笔记

2010年11月14日 admin 没有评论

书籍介绍

优秀的软件架构师应该既掌握业务知识又具备技术能力,做到这一点绝非易事,本书想要探讨的就是这个主题。这是一本真正的开源图书,我们邀请到50多位杰出的软件架构师参与写作。大家无偿地分享了各自的工作经验和心得,内容从规避风险的方法到组建团队的技巧,涵盖了架构设计的方方面面。衷心希望这97篇文章能激发您的思考,解决您工作中的困惑。豆瓣地址 http://book.douban.com/subject/4745287/

 

 

 

 

 

 

 

 

 

 

 

读书笔记

分类: 阅读 标签:

Daneil-Journey Weekly Dose-2010/10/3

2010年10月10日 admin 没有评论

Scalability

多IDC的数据分布设计(一)

多IDC的数据分布设计(二)

CAP原理与最终一致性

OO & Design Pattern

视角的力量–再说OO设计原则

Martin Fowler在他的著作 《UML Distilled》中提到了三层视角(perspective):概念视角,规约视角,实现视角。

使用三种视角看软件开发,我们可以得到这样的描述:

概念视角:呈现所研究领域中的各种概念,得出概念模型的时候应该尽量少德或者不考虑它的实现,这个视角要回答的问题是:软件要负责什么?是策略性的结论

规约视角:我们现在考虑的是软件,但是我们关注的是软件的接口而不是实现。规约视角要回答的问题是:怎么使用软件?这个层次关注的是软件各部分的交流。

实现:这时我们考虑的是代码本身但是许多方面我们使用规约视角可能会更好,软件在规约层交流在实现层执行。

视角帮助我们将问题划分层次,隔离

从上面的描述我们很明显得看到“软件开发”所设计牵扯的问题已经被划分到三个不同的层次,在每一个层次我们都要有特定的思考成果。在高层没有思考成熟的时候我们不往下一个层次进行,按照这样一个原则,细节被隔离在思维的围墙之外。

Active Object 并发模式在 Java 中的应用

Architecture

如何做好软件系统的架构设计?

Tomcat 系统架构与设计模式,第 1 部分: 工作原理

Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析

Java

Installing Multiple Eclipse Plugins with Ease

NOSQL

MapReduce: 一个巨大的倒退

Algorithm

拜占庭将军问题

拜占庭假设是对现实世界的模型化,由于硬件错误、网络拥塞或断开以及遭到恶意攻击,计算机和网络可能出现不可预料的行为。拜占庭容错协议必须处理这些失效,并且这S些协议还要满足所要解决的问题要求的规范。这些算法通常以其弹性t作为特征,t表示算法可以应付的错误进程数。 很多经典算法问题只有在t<n/3是才有解,如拜占庭将军问题,其中n是系统中进程的总数

如果要想容忍m个判国者,必须保证总的将军的个数大于3m。

产品

新浪内部对腾讯公司的深度解析.pdf

学习腾讯的产品管理之道

其他

如何让PPT的备注演示者看到而观众看不到