2014年5月12日星期一

组合模式小试(模拟构建xml文件) - Chandler Qian

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
组合模式小试(模拟构建xml文件) - Chandler Qian  阅读原文»

组合模式是一种功能比较单一的设计模式,一般与其他设计模式搭配使用。本篇简单模拟了一下自动构建xml文件的小程序。

一、介绍

  还是先来看一下《研磨设计模式》的介绍——将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

  组合模式的本质——统一叶子对象和组合对象。

  什么是组合模式呢?说白了,就是用一个抽象类把对象的整体和部分的操作统一起来。在外部看来,整个对象无论是整体还是部分,操作都是一样的。最常见使用组合模式的譬如我们的数据结构——树。树有3种模块,分别是根、枝、叶。这3个都分别有各自的特征。我们就可以用组合模式构建一个抽象类,将3者一样的操作在抽象类中实现,不一样的操作构建成抽象方法留给子类实现。这样在外界看来,整棵树自成一体,无须区分哪个是根、哪个是枝、叶。

二、我的实现

  在这里,我们利用组合模式来做一个自动构建xml文件的小程序,也算是简单模拟了一下dom4j的功能。

  xml文件分别有哪些部分组成?完整的xml文件,最顶端是xml声明,下面是xml的处理指令,然后下面是文档类型声明,然后下面是一个根元素,根元素包括了一个或多个子元素。而作为元素而言,又包括了元素内容、属性键值对等等。同时,xml注释可以在任意地方添加。

  通常简单的xml文件只包括了xml声明、根元素(包含各种内容)以及xml注释。

  由于xml声明只出现一次,可以在总的构建类中再处理。这里我们主要处理元素和xml注释。因为注释可以在任何地方添加,也可以抽象为元素的一种。

1、组合模式最麻烦的,就是这个抽象类,下面是我的抽象类,包含了元素和xml注释所有可能的方法:

1 package composite.qsk;
2
3 import java.util.List;
4
5 public abstract class AbstractElement {
6
7 // 内容(包含在"<X>"和"</X>"之间的部分,没有用“<”和“>”括起来)
8 protected String content = null;
9
10 // 元素层,根层数为0,其子元素层数为1,依次
11 private int level = 0;
12
13 // 抽象方法、得到本元素所有内容(类似“<a c=d>efgh </a>”)
14 public abstract String getAllContent();
15
16 public List<XMLElement> getChildElements()
17 {
18 throw new UnsupportedOperationException("对象不支持此功能");
19 }
20
21 public int getLevel()
22 {
23 return level;
24 }
25
26 public void setLevel(int level)
27 {
28 this.level = level;
29 }
30
31 // 设置本元素内容
32 public boolean setContent(String content)
33 {
34 boolean flag = false;
35 if (content != null)
36 {
37 this.content = content;
38 flag = true;
39 }
40 return flag;
41 }
42
43 // 得到本元素的内容
44 public String getContent()
45 {
46 return content;
47 }
48
49 // 增加属性
50 public boolean addAttribute(XMLAttribute xmlAttribute)
51 {
52 throw new UnsupportedOperationException("对象不支持此功能");
53 }
54
55 public boolean addAttribute(String aName, String aValue)
56 {
57 throw new UnsupportedOperationException("对象不支持此功能");
58 }
59
60 // 根据属性名移除属性
61 public boolean removeAtrribute(String name)
62 {
63 throw new UnsupportedOperationException("对象不支持此功能");
64 }
65
66 // 增加子元素
67 带你走近AngularJS - 基本功能介绍 - 葡萄城控件技术团队博客  阅读原文»

AngularJS是Google推出的一款Web应用开发框架。它提供了一系列兼容性良好并且可扩展的服务,包括数据绑定、DOM操作、MVC设计模式和模块加载等。本文专注于AngularJS 指令的使用,在我们进入主题之前,我们将快速浏览AngularJS的基本用法。

AngularJS 不仅仅是一个类库,而是提供了一个完整的框架。它避免了您和多个类库交互,需要熟悉多套接口的繁琐工作。它由Google Chrome的开发人员设计,引领着下一代Web应用开发。也许我们5年或10年后不会使用AngularJS,但是它的设计精髓将会一直被沿用。

了解AngularJS的开发人员,你肯定会为AngularJS自定义指令(它的功能相当于.NET 平台下的自定义控件)功能感到兴奋。自定义指令允许你扩展HTML标签和特性。指令可以复用并且可以跨项目使用。

自定义指令已经得到了广泛的应用,其中值得一提的是-Wijmo控件集。它包含了近50款基于AngularJS 控件。Wijmo是用于创建桌面和移动Web应用程序的HTML5前端控件集。从交互式图表到强大的表格控件,Wijmo几乎包含了我们所需要的一切。可以从官网了解Wijmo的更多信息。所以,Wijmo是学习AngularJS很好的参考示例:

image

创建自定义指令是非常容易的。指令可以测试、维护并且在多个项目中复用。

使用AngularJS, 需要在HTML页面引用脚本文件,给HTML或Body标签添加ng-app 特性。下面是一个使用AngularJS的简单实例:

<html>
<head>
<script src="http://code.angularjs.org/angular-1.0.1.js"></script>
</head>
<body ng-app ng-init="msg = '葡萄城控件团队博客'">
<input ng-model="msg" />
<p>{{msg}}</p>
</body>
</html>

当AngularJS 加载后,它会在文档中搜索ng-app 特性。这个标签通常被设置给项目的主要模块。一旦发现,Angular 就会对文档进行操作。

在这个例子中,ng-init 特性初始化了一个msg 变量“葡萄城控件团队博客”, ng-model 特性把它和input 控件进行了双向绑定(注意:大括号是绑定的标记)。AngularJS 会解析这个标记,随着input值改变实时更新msg 文本值。可以从链接查看效果:点击进入

image

AngularJS 模块

模块可以说是AngularJS 的根本。它包含配置、控制、过滤、工厂模式、指令及其它模块。

如果你熟悉.NET平台,但初步学习Angular。下面的表格是一个简要的对比,帮助你理解Angular中的角色扮演情况:

AngularJS

.NET

摘要

module

Assembly

应用开发模块

controller

ViewModel

控制器,启到不同层面间的组织作用

scope

DataContext

为视图提供绑定数据

filter

ValueConverter

数据传输到视图之前修改数据

directive

Component

可复用的UI元素,也可以理解为前端插件

factory, service

Utility classes

为其他模块元素提供服务

例如,下面的代码使用控制器、过滤器和指令创建了一个模块:

// the main (app) module
var myApp = angular.module("myApp", []);

// add a controller
myApp.controller("myCtrl", function($scope) {
$scope.msg
= "grapecity team blog";
});

// add a filter
myApp.filter("myUpperFilter", function() {
return function(input) {
return input.toUpperCase();
}
});

// add a directive
myApp.directive("myDctv", function() {
return function(scope, element, attrs) {
element.bind(
"mouseenter", function() {
element.css(
"background", "yellow");
});
element.bind(
"mouseleave", function() {
element.css(
"background", "none");
});
}
});

上面示例中module 方法的第一个参数为模块的名称,第二个参数为它的依赖模块列表。我们创建了一个独立的模块,不依赖于其它模块。所以第二个参数为空数组(注意:即使它为空,我们也必须填写这个参数。否则,该方法回去检索之前的同名模块)。这部分我们将在后续的文章中详细阐述。

controller 构造函数获取$scope 对象,用于存储所有controller 暴露的接口和方法。scope 由Angular 传递到视图和指令层。在这个例子中, controller 添加了msg 属性给scope对象。一个应用模块可以包含多个controller,每个controller各司其职,控制一个或多个视图。

filter 构造函数返回一个方法用于更改input文本的显示方式。Angular 提供很多内置的filter,同时,你也可以添加自定义filter,操作方式Angular内置filter相同。在这个例子中,实现了小写到大写的转换。Filter不仅可以格式化文本值,还可以更改数组。AngularJS 内置的格式化Filter有number、date、currency、uppercase和lowercase。数组 filter有filter、orderBy和 limitTo。Filter需要设置参数,语法格式也是固定的: someValue |filterName:filterParameter1:filterParameter2....

directive 构造函数返回了一个方法,该方法用于传递一个元素,并依据scope中的参数对其进行修改。示例中我们绑定了mouseenter 和mouseleave 事件用于切换文本高亮显示。这是一个功能简单的指令,在后续的章节将展示如何创建一些复杂指令。

下面是使用模块构建的页面:

<body ng-app="myApp" ng-controller="myCtrl">
<input ng-model="msg" />
<p my-dctv >
{{msg | myUpperFilter }}
</p>
</body>

可以从链接查看效果:点击进入

image

注意应用中module、controller和filter 作为特性值应用。它们代表JavaScript 对象,因此名称是区分大小写的。指令的名称同样也是属性值,它作为HTML标签被解析,所以也是区分大小写的。但AngularJS 会自动转换这些特性为小写,例如“myDctv" 指令变成"my-dctv" (就像内置的指令ngApp, ngController, 和ngModel会转换成 "ng-app", "ng-controller", 和"ng-model"。

项目组织结构

使用AngularJS 可以创建大型Web项目。你可以把项目拆分为多个模块,把一个模块拆分为多个模块文件。同时,可以按照你的使用习惯组织这些文件。

列举一个典型的项目结构:

Root
default.html
styles
app.css
par

阅读更多内容

没有评论:

发表评论