2008年10月10日

什么是设计模式

设计模式的定义方式各不相同,如果只是大致描述一下的话,我们可以说,设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

但是我相信,肯定有很多首次踏入这个领域,或是初次听到该名词的朋友会有和我当初同样的困惑,那就是 — 到底什么是设计模式?虽然介绍设计模式的书籍和网页是层出不穷,然而却很少有让人一看就能理解的。于是我就有了些想法,希望能在这里贡献自己微薄的力量,将我所理解到的设计模式通过简单的类比方法告诉大家。

其实,我们只需要剖析“设计模式”这四个字,就能明白它指的是什么了。根据所学的语文知识我们知道,它是一个名词短语,偏重于“模式”二字,因此经过添油加醋后可以理解成是“良好设计所应遵循的模式”。也就是说,如果希望自己的软件能够设计得更好,那么我们就应当使用某些模式。

可是这里的“模式”又是什么意思呢?我们可以借助仿生学来理解模式二字。简言之,仿生学就是模仿生物的科学,也就是对某些生物的一些非常优秀的特性进行相应的模仿,并应用到人类技术的一门科学。比如说:潜水员的脚蹼就是模仿青蛙的脚蹼而来的。因为脚蹼增大了划水时与水的接触面积,因此能够使得潜水员的游泳速度加快。

如果不考虑经验来源和动机的差别,模式的道理与其类似。由于人们在生活中以及长期编码过程中,见识过很多的事物、遇到过各种复杂的情况,并累积了许许多多有用的经验。于是基于生活中某些事物的特点以及软件开发中所得到的宝贵经验,人们总结出了一些能够提高代码质量和软件产品品质的方法,这样的方法就叫做模式。典型的设计模式的例子有:抽象工厂、仓库模式、备忘录模式等等。这些模式也都是根据相应事物的特性和优点来命名的。

好了,其他有关于设计模式的官方说法和完备的定义我就省去就不说了,希望以上文字对大家有所帮助。

2008年10月7日

[译文]An Introduction to RDF and the Jena RDF API(3-陈述)

RDF模型中的每一个箭头表示为一个陈述(statement). 每一个陈述声明了关于某个资源的某个事实. 一个陈述有三部分组成.

  • 主体, 也就是箭头的出发的资源.
  • 谓词, 也就是标识箭头的属性.
  • 客体, 也就是箭头所指向的那个资源或文本.

一个陈述有时也叫做一个三元组的原因就是它由三部分组成.

一个RDF模型(译者注: 指Jena中的接口Model)是由一组陈述所组成的. 在Tutorial2中, 每调用一次addProperty函数就会在模型中增加另一个陈述. (因为一个模型是由一组陈述组成的, 所以增加一个重复的陈述并不会产生任何意义.) Jena模型接口定义了一个listStatements()方法, 此方法会返回一个StmtIterator类型的变量. StmtItor是Java中Iterator的一个子类型, 这个StmtIterator变量重复迭代了该接口模型中的所有陈述. StmtIterator类型中有一个方法nextStatement(), 该方法会从iterator返回下一个陈述. (就和next()返回的一样, 但是已将其映射为Statement类型). 接口Statement提供了访问陈述中主体, 谓词和客体的方法.

现在我们会用使用那个接口来扩展Tutorial2, 使起列出所有的创建的陈述并将它们打印出来. 此例完整的代码可以在Tutorial3中找到.

// list the statements in the Model
StmtIterator iter = model.listStatements();

// print out the predicate, subject and object of each statement
while (iter.hasNext()) {
    Statement stmt = iter.nextStatement(); // get next statement
    Resource subject = stmt.getSubject(); // get the subject
    Property predicate = stmt.getPredicate(); // get the predicate
    RDFNode object = stmt.getObject(); // get the object

    System.out.print(subject.toString());
    System.out.print(" " + predicate.toString() + " ");
    if (object instanceof Resource) {
        System.out.print(object.toString());
    } else {
        // object is a literal
        System.out.print(" \"" + object.toString() + "\"");
    }

    System.out.println(" .");
}

因为一个陈述的客体可以是一个资源也可以是一个文本. getObject()方法会返回一个类型为RDFNode的客体, RDFNode是Resource和Literal类共同的超类. 为了确定本例中的客体确切的类型, 代码中使用 instanceof来确定其类型和相应的处理.

运行后, 此程序回产生与此相似的输出:

http://somewhere/JohnSmith http://www.w3.org/2001/vcard-rdf/3.0#N anon:14df86:ecc3dee17b:-7fff.
anon:14df86:ecc3dee17b:-7fff http://www.w3.org/2001/vcard-rdf/3.0#Family "Smith".
anon:14df86:ecc3dee17b:-7fff http://www.w3.org/2001/vcard-rdf/3.0#Given "John" .
http://somewhere/JohnSmith http://www.w3.org/2001/vcard-rdf/3.0#FN "John Smith".

现在你明白了为什么模型构建会更加清晰. 如果你仔细观察, 就会发现上面每一行都由三个域组成, 这三个域分别代表了每一个陈述的主体, 谓词和客体. 在此模型中有四个箭头, 所以会有四个陈述. "anon:14df86:ecc3dee17b:-7fff"是有Jena产生的一个内部标识符, 它不是一个URI, 也不应该与URI混淆. 它只是Jena处理时使用的一个内部标号.

W3C的RDF核心工作小组定义了一个类似的表示符号称为N-三元组(N-Triples). 这个名字表示会使用"三元组符号". 在下一节中我们会看到Jena有一个内置的N-三元组写机制(writer).

2008年10月5日

[译文]An Introduction to RDF and the Jena RDF API(2-导言)

资源描述框架是(RDF)是描述资源的一项标准(在技术上是W3C的推荐标准). 什么是资源? 这实在是一个很难回答的问题, 其精确的定义目前尚在争论中. 出于我们的目的, 我们可以把资源想象成任何我们可以确定识别的东西. 在本教程中,读者你本身就是一个资源, 而你的主页也是一个资源, 数字1和故事中巨大的白鲸都是资源.

在本教程中, 我们的例子会围绕人们展开. 假设人们会使用VCARDS(电子名片), 而VCARD将由RDF表示机制来描述. 我们最好把RDF考虑成由结点和箭头的形式构成的图. 一个简单的vcard在RDF中可能看起来是这样的:


资源John Smith在图中用椭圆表示, 并被一个统一资源定位符(URI) 所标识, 在本例中是"http://.../JohnSmith"). 如果你想要通过你的浏览器来访问这个资源的话,你很有可能会失败. 四月的愚人节笑话并不经得起考验, 相反如果你的浏览器把John Smith传递到你的桌面的话, 你才该感到惊讶. 如果你并不熟悉URI's的话, 你可以把它们想象成简单的陌生名字.

资源拥有属性(property). 在这些例子中, 我们对John Smith名片上出现的那些属性很感兴趣.图1只显示了一个属性, John Smith的全名. 属性是由标有属性名的箭头表示的. 属性的名字也是一个URI, 但是由于URI十分冗长笨重, 所以图中将它显示为XML qname的形式. 在':'之前的部分称为命名空间前缀并表示了一个命名空间. 在':'之后的部分称为局部名, 并表示在命名空间中的一个名字. 在写成RDF XML形式时, 属性常常以qname的形式表示, 这是一个在图形和文本中的简单的缩写方法. 然而, 严格地讲, 属性应该用URI来标识. 命名空间前缀:局部名的形式是一种命名空间连接局部名的URI缩写. 当浏览器访问时, 用并没有强制属性的URI必须指向一些具体的事物.

每个属性都有一个值. 在此例中, 值为一个文本(literal), 我们现在可以把它看成一个字符串.文本在图中显示为长方形.

Jena是一个Java API, 我们可以用它来创建和操纵诸如上述例图的RDF图. Jena设有表示图(graph), 资源(resource), 属性和文本(literal)的对象类. 表示资源, 属性和文本的接口分别称为Resource, Property, 和Literal. 在Jena中, 一个图(graph)被称为一个模型并被Model接口所表示.

创建上述例图或称为上述模型的代码很简单:

// some definitions
static String personURI = "http://somewhere/JohnSmith";
static String fullName = "John Smith";

// create an empty Model

Model model = ModelFactory.createDefaultModel();

// create the resource

Resource johnSmith = model.createResource(personURI);

// add the property

johnSmith.addProperty(VCARD.FN, fullName);

这些代码先定义了一些常量, 然后使用了ModelFactory类中的createDefaultMode()方法创建了一个空的基于内存存储的模型(Model 或 model). Jena还包含了Model接口的其他实现方式. 例如, 使用关系数据库的, 这些类型 Model接口也可以从ModelFactory中创建.

于是John Smith这个资源就被创建了, 并向其添加了一个属性. 此属性由一个"常" ("constant")类VCARD提供, 这个类保存了在VCARD模式(schema)中所有定义的表示对象. Jena也为其他一些著名的模式提供了常类的表示方法, 例如是RDF和RDF模式, Dublin 核心标准和DAML.

创建资源和添加属性的代码可以写成更紧凑的层叠形式:

Resource johnSmith =
        model.createResource(personURI)
            .addProperty(VCARD.FN, fullName);

这个例子的工作代码可以在Jena发布的材料的教程包中的Tutorial1中找到. 作为练习, 你自己可以获得此代码并修改其以创建一个简单VCARD.

现在让我们为vcard再增加一些更详细的内容, 以便探索更多的RDF和Jena的特性.

在第一个例子里, 属性值为一个文本. 然而RDF属性也可以采用其他的资源作为其属性值. 下面这个例子使用常用的RDF技术展示了如何表示John Smith名字的不同部分:


在这里我们增加了一个新的属性, vcard:N, 来表示John Smith名字的结构. 这个模型有几点有趣之处. 注意属性vcard:N使用一个资源作为起属性值. 同时注意代表复合名字的椭圆并没有URI标识. 它被认为是一个空白结点(blank Node).

创建此例的Jena代码也十分简单. 首先是一些声明和对空模型的创建.

// some definitions
String personURI = "http://somewhere/JohnSmith";
String givenName = "John";
String familyName = "Smith";
String fullName = givenName + " " + familyName;

// create an empty Model
Model model = ModelFactory.createDefaultModel();

// create the resource
// and add the properties cascading style
Resource johnSmith
  = model.createResource(personURI)
               .addProperty(VCARD.FN, fullName)
               .addProperty(VCARD.N,
                model.createResource()
                          .addProperty(VCARD.Given, givenName)
                          .addProperty(VCARD.Family, familyName));

此例的工作代码可以在Jena发布材料的教程包的Tutorial2中得到.

[译文]An Introduction to RDF and the Jena RDF API(1-前言)

本文是一篇对W3C的资源描述框架(RDF)和 Jena(一个Java的RDF API)的教程性介绍. 本文是为那些不熟悉RDF的, 以及那些通过建立原形可以达到最好学习效果的, 或是因为其他原因希望能快速操作Jena的程序员而写的. 我们假设读者在阅读本文前已具有一定的XML和Java知识.

如果读者在没有理解RDF数据模型的基础上就迅速进入操作阶段,往往会导致失败和失望. 然而,如果光学习数据模型又是十分枯燥乏味的, 并常常会导致曲折的形而上学的难题. 更好的学习办法是在理解数据模型的同时练习操作它. 可以先学习一点数据模型再动手试一试.然后在学习一点再试一试. 这样一来就能达到理论实践相结合的效果.数据模型本身十分简单,所以学习过程不会太长.

RDF具有XML的语法, 所以许多熟悉XML的人就会认为以XML语法的形式来思考RDF. 然而, 这是不对的. RDF应该以它数据模型的形式来被理解. RDF数据可是用XML来表示, 但是理解数据模型的重要性更在理解此语法重要性之上.

Jena API的一个运行例子, 包括本教程中所有例子的工作源代码都可以在http://jena.sourceforge.net/downloads.html下载.

2008年10月4日

Jena伴我同行

最近在与孙老师聊天的时候,他和我谈起前几天和中国三星的技术主管的一次交流的事。之所以有这样的机会主要是因为三星准备在我们模式识别与智能系统这个专业招一批博士生,并以他们为中心创建一个新的部门,部门的具体名称我记不得了,我只知道他们的职责就是把握未来几年或者是十几年中IT业的发展方向以及技术走向,并将他们所掌握到的理论知识转变为实际应用来创造生产力。在他们交谈的时候,那些人问孙老师现在在研究些什么,孙老师说最近比较关注的东西都是与服装有关的,一是移动设备上的3D应用(移动设备上的三维试衣技术),二是基于语义网所构建的服装方面的本体信息来实现相关的技术应用。在听完孙老师的简要介绍之后,那些三星的人顿时对这两个领域产生了浓厚的兴趣,并且表示这些领域的确值得关注,同时他们也有想法在这两方面做点文章,因此迫切的希 望孙老师能够拿出一些demo来给他们演示一下。从这个角度来看,孙老师目前所把握的方向是比较准确的,同时这也是对他这一年来所做工作的肯定,当然这也是对作为他学生的我们的鼓励和刺激。

另外孙老师也特别关心我们现在和郑州那边的项目进展,希望我们能够赶紧摆脱手中大量耗时的编码工作,来摸索他所看中的这两个领域。也正是因为这个原因,我最近才开始继续研究语义网的。其实,从开始看语义网的书和资料到现在已经有2个月整了,我深深的感觉到,自学一门技术还真是不容易,特别是学习一项枯燥且抽象的技术。不过,经过暑假时的一部分积累以及最近的一些研究再加上Jena这个框架的到来,感觉自己总算是摸到一点门道,找到一些成就感了。

Jena ( 发音: 耶那 ) 是由HP的一个项目组开发的基于Java语言的开源框架,它提供RDF, RDFS和OWL的可编程环境,外加SPARQL以及基于规则的推理引擎。使用Jena,我们能够很容易的构建语义网的应用。Jena包括了

  • (1) RDF API.
  • (2) 读写RDF/XML, N3以及N-Triples.
  • (3) OWL API.
  • (4) 主存内的存储以及持久化.
  • (5) SPARQL查询引擎等。

Jena的源码再加上Jena的教程,对于学习这门技术来说的我来说,是一个恰到好处的朋友。目前我仅仅只是掌握到一些皮毛, 相信将来还有很长的路要与这位朋友相伴呢。

2008年9月28日

启动语义网的研究

从开学起到现在,一直都在忙着上课和做项目,所以没有多少时间去研究自己想研究的东西。直到最近,首先是我们的项目告一段落,其次是长假给了我很多的空闲时间。因此我打算利用这些空闲时间研究一下上学期末孙老师就安排我看的语义网。

语义网(Semantic Web),我曾经稍微看了一下,初步判定它是一个比较难的东西,主要是没有什么感性认识的途径,只能是看一些书和论文,有点儿枯燥的说。不过呢,这却是一个非常猛的东西,是个在将来会大展宏图的技术,而且我对这项技术还是有些兴趣的。不管怎么说,先看看再说吧嘿嘿。

如果有朋友也研究相关领域的话,希望大家能够相互交流。

2008年9月26日

开博啦~小试一篇

话说博客这个东东呢,貌似是5年前就在中国火起来的东西,然而5年后的今天本人却才刚刚开博,好像有点落伍的意味了呵呵。其实我以前也尝试过申请博客,可是没写两篇就封笔了,想想还真是惭愧呢。不过如果好好分析一下自己的这些行为和举动的话,会发现,实际上这才是一个真实的我。

突然在今天下定决心要真正的、好好的写博客,原因其实有三个。首先,目前已经是以一个研究生的身份开始学习和生活了,所以我希望能够在新的人生阶段里体验新的生活和感受并且与关注我的人进行分享;其次,现在的自己也比过去要成熟多了,不再像以前那样容易受到外界干扰和诱惑,再就是做事情更加有耐心了;第三,则是因为逛了逛阿里巴巴卢克进先生的google博客,感觉还挺不错的,再加上我对google是情有独钟,所以就毫不犹豫的申请了个google的博客。


今天这篇文章仅仅只是小试牛刀而已,好戏还在后头呢。为了增加我博客的文章量,我就先将我之前写在校内的文章转个两篇过来好了,它们分别是《永恒的秋》《穿红衣的女孩,橘黄色的火焰—辛德勒的名单》。有兴趣的朋友可以点击链接回顾一下。好了,本篇就到此为止了。