[CSS]2009年海外Web设计风潮(上)

mikel阅读(947)

这是 Smashing Magazine 花费几个月的时间研究编写的 2009 年 Web 设计风格与潮流,Smashing Magazine 的编辑们对当前流行的大量 Web 设计风格进行分析,总结出那些可能在 2009年风行的潮流,包括新的设计元素,新的图形方式,并给出大量的漂亮的示例。这是第一部分10个潮流,第二部分15个潮流将于下周推出。

1. 凸版印刷风格
这种风格有些出人意料,可能因为之前很少有人使用。该风格在在各种主题的网站中都有,但主要用于产品设计或在线服务类网站





2. 富UI
现代 Web 中的 UI 变得越来越漂亮,越来越好用。过去的一年,Web 中的 UI 有了显著提高,有了一种接近桌面的感觉。Ajax 和 Flash 被广泛使用。
特别是我们比去年看到了更多留白区域,还看到很多现代的 UI 技术会显示用户同系统之间交流的视觉状态,比如,按钮在正常和被按下时显示不同的样子,用户同系统交互时能及时得到反馈,另外,越来越多的服务可以被用户定制。

这些设计显示 Web 设计师将更多精力放到了用户体验上。




3. 透明 PNG
使 用 PNG 实现透明虽然不被 IE6支持,却在过去的一年大行其道。设计师们似乎正在尝试将背景图片和内容融合并实现一些印刷媒体的风格。比如,将 PNG半透明图片放到整体背景的某个区域上,用来加亮显示这个区域,如标题或声明。一些 PNG 同名技术还用来实现灯箱框效果。
Smashing Magazine 去年曾有篇使用透明效果实现创意设计的文章,很多设计师在他们的作品中开始尝试这些技巧。有趣的是,透明效果常被用于页首和页尾部分,不过也有些例外





4. 巨大字体
以前文章中我们曾介绍过巨型字体设计,2009年,巨型字体设计还会风行,尤其是那些设计社,以及展示型,产品介绍型,或在线服务型网站,他们会使用巨型字体显示重要信息。
巨型字体设计中使用的字号往往超过36px,设计师们对字体编排注入了更多关注,以实现更漂亮,更连贯,更值得信赖的站点。


5. 代用字体
设计师们还把更多注意力放到字体上,虽然经典的 Web 字体,Helvetica, Arial, Georgia 以及 Verdana 等仍占主流,一些代用字体正浮出水面(如 sIFR)。
有趣的是,这些字体会和设计无缝地衔接,设计师们似乎并非为字体而字体,而是要将字体同他们的设计结合在一起实现更漂亮的效果。




6. 灯箱效果
灯箱框是第二代弹窗,它们比第一代基于 JavaScript 的弹窗更友好,可以让用户将注意力集中到最重要的部分。这些窗口一般由用户的某个行为激发,并显示在其它内容的上层,他们有时候是半透明的,并包含一个关闭按钮。



7. 媒体块
随 着宽带接入的普及,用户现在可以承担更丰富的内容,设计师们也借机提出更有吸引力的内容。越来越多产品网站使用媒体块显示视频,让用户更容易理解这些内 容。用户只需靠在椅子上看视频,不需要一步一步往下点,这些食品通常比较短,直奔主题,虽然很正规,但也包含一些娱乐性。
不过请注意,视频应当是你内容展示方式的次要选项,并不是所有人都有宽带接入,也不是所有人都喜欢有视频播放(他们可能正在后台听网络收音机或播放音乐),另外,也不是所有人都启用了 Flash 和 JavaScript


8. 杂志外观
传统印刷媒体设计中使用的编排技术也出现在 Blog 设计中,文章的编排,文字排版,图片甚至对其方式。基于网格的设计也很流行,但主要用于展示与产品页以及大型博客,极少用于公司网站或网店。


9. 滚动幻灯导航
幻灯片水平和垂直滚动,可以向不同方向滚动,当前项加大加亮。这种导航技术可以让用户快速直观地浏览站点中的内容。一般常用语娱乐性网站,另外,设计者还可以使用该技术展示他们的作品。

10. 在重点位置做形象展示
网站的左上方一般是一个站点最重要的区域,因为那是用户注意力最集中的地方。因此,在那个部位放上网站中最重要的信息是明智之举。
事 实上很多设计师正是这样做的,不管是 Web程序,公司网站,在线服务还是作品展示,设计师们将口号或简介性内容放在那里,并使用醒目的排版给用户以良好的第一印象。这些内容长短不一,不管哪 种方式,但它们都占据可观的空间,一般横跨整个幅面,高度在250到400之间。不过这些形象展示性区域一般并不用于博客或在线商店。



未完待续
本文国际来源:Web Design Trends For 2009
中文翻译来源:COMSHARP CMS 官方网站(35公里译)

[C#]C#中三种截屏方式总结

mikel阅读(977)

昨天写自动化测试的CASE的时候,碰到一个疑难杂症,调用截图的函数去截取一个Popup窗口,但是总是把背景程序给截下来,Popup窗口就跟 看不到一样。本来以为是同步的问题,也就是以为先截图再点击弹出Popup窗口了。后来加了N个Thread.Sleep来测试,发现根本不是因为这个原 因,而是截图的函数截不下来这个窗口。

这个为啥呢,只好把截图的函数代码翻出来看,以前是用这种方式的:
BitBlt(dcImage, 0, 0, (int)(rect.Width), (int)(rect.Height), dcScreen, (int)(rect.Left), (int)(rect.Top), TernaryRasterOperations.SRCCOPY);

凭直觉感觉应该是因为这种通过DC的方式对WPF程序支持有问题,但是又觉得奇怪就是截取其它的WPF组件和窗口都没有问题,偏偏Popup窗口不行。

前些天听说另外一种截屏的方法,这种方法连被遮挡的窗口都可以截,于是就Google一大把,找打了PrintWindow函数,于是就有了第二种解决方案,代码如下:

IntPtr hdc = Native.GetWindowDC(this.Handle);
if (hdc != IntPtr.Zero)
{
    IntPtr hdcMem = Native.CreateCompatibleDC(hdc);
    if (hdcMem != IntPtr.Zero)
    {
        IntPtr hbitmap = Native.CreateCompatibleBitmap(hdc, (int)(Rect.Width), (int)(Rect.Height));
        if (hbitmap != IntPtr.Zero)
        {
            Native.SelectObject(hdcMem, hbitmap);
            Native.PrintWindow(this.Handle, hdcMem, 0);

            Native.DeleteObject(hbitmap);
            Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
            bmp.Save(sPath);
       }
        Native.DeleteObject(hdcMem);
    }
    Native.ReleaseDC(this.Handle, hdc);
}
就是拿到窗口的句柄,通过PrintWindow API来截取窗口。

但是更让人气愤的事情出现了,截出来的窗口中,只要是用到WPF组件的地方,全部是黑块儿,只有MFC的窗口框架和按钮可以正常被截取。

于是乎,就无奈的继续分析这个问题,我记得WPF是没有走GDI,而是通过Directx渲染的,那就是说DC的方式和PrintWindow的方式都不靠谱,但是截Directx的貌似还比较复杂。

突 然想起来,平常报bug的时候都是按PrintScreen,然后再处理一下的,那应该PrintScreen按键是管用的,看来只能曲线救国了。但是那 样就得走剪切板了,貌似会破坏剪切板的数据,不过如果我在截取前保存一下数据,在截取后再恢复一下剪切板数据,那就没有问题了。

于是就有了第三种解决方案(暂时还没有加恢复剪切板数据的代码):

const uint KEYEVENTF_EXTENDEDKEY = 0x1;
const uint KEYEVENTF_KEYUP = 0x2;
const byte VK_SNAPSHOT = 0x2C;
Native.keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, UIntPtr.Zero);
Native.keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, UIntPtr.Zero);

IDataObject iObj = Clipboard.GetDataObject();
if (iObj.GetDataPresent(DataFormats.Bitmap, true))
{
    Bitmap bmpScreen = iObj.GetData(DataFormats.Bitmap, true) as Bitmap;
    Bitmap bmpOutput = new Bitmap((int)this.Rect.Width, (int)this.Rect.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
    Graphics g = Graphics.FromImage(bmpOutput);
    Rectangle destRectangle = new Rectangle(0, 0, (int)this.Rect.Width, (int)this.Rect.Height);
    g.DrawImage(bmpScreen,destRectangle,  (int)this.Rect.X, (int)this.Rect.Y, (int)this.Rect.Width, (int)this.Rect.Height, GraphicsUnit.Pixel);
    bmpOutput.Save(sPath, System.Drawing.Imaging.ImageFormat.Bmp);
}

测试可用,只好先用着了

不过还有几个问题,先写下来,留待以后解决:

1. 针对第三种方案,既然可以按PrintScreen键截图,那对应的API是什么,总觉得发键盘消息没有直接调API稳定

2. 针对WPF截图有没有更好的解决方案

[Lucene]Lucene.Net 2.3.1开发介绍 —— 三、索引(七)

mikel阅读(719)

5、IndexWriter

索引这部分最后讲的是IndexWriter。如果说前面提到的都是数据的结构,那么IndexWriter就是业务的封装。无论述Document,Field还是看不见的Segment,Term都是对数据存储逻辑的抽象,IndexWriter包装了操作的过程。

当然,这里不会讨论IndexWriter的每个细节,这里主要介绍IndexWriter的常用法和实际使用中遇到的部署问题。

5.1 IndexWriter的常用方法

 IndexWriter的用法很简单,前文有例子。在《接触Lucene.Net 》一文中代码2.1.1就是最简单的用法。可以看到IndexWriter的构造函数很重要,AddDocument方法也很重要,有这两个方法,就可以 建立索引了。其它的方法都是对建立索引的过程或者结果进行了优化,或者是提供了一些索引中或者索引后的数据。比如,常用的Optimize方法,就是对索 引进行优化,使得搜索能够效率更高。还有一些常用的方法(按字母排序):

(1)、AddIndexes方法是合并不同部分索引的,这个方法很有用,比如,用5个线程在5个目录下建立索引,然后用这个方法把5个索引合并为一个,这样就能提高索引的效率;
(2)、Close方法是最后使用的方法,除了能够去除对文件的锁定外,还能起到Flush方法的作用。这个方法非常重要,在IndexWriter实例建立后,无论出现什么样的问题,哪怕程序崩溃,都一定要显式调用该方法。要不然索引会处于锁定状态,无法解除;
(3)、DeleteDocuments是用来删除索引的,这里只能指定Term删除,使用价值不是太高;

(4)、Flush方法是把缓冲数据写入的一个方法,在不想关闭索引但是要清空缓冲区的时候使用;

(5)、Optimize方法是优化索引的方法,如果索引数据很大,则调用这个方法会耗费很长时间。另外就是,如果索引文件这个时候被读取,并不能达到删除废弃文件的目的。

(6)、SetMaxBufferedDocs方法是规定缓冲区能够缓冲Document的个数,因为写硬盘要比写内存慢很多,这个值设置得越大,暂时存储到内存的Document就会越多;

(7)、SetMaxFieldLength方法设置Field的最大长度;

(8)、UpdateDocument用来更新索引,但是实际上并不是真正的更新,而是先删除,再添加,如果不进行优化,那么至少会增加两个文件,一个记录了增加的一个记录了删除的。

5.2 索引的部署

索引的部署根据索引的大小而趋向复杂,我认为至少是平方增长。复杂度增长的原因在于,索引大小的增长,将会引入更多需要考虑的因素。比如,索引的重建,索引优化时间,多索引部署等,而分布式部署基本上是目前最复杂的部署方案。

一般来说,应该一个索引存储,只应该由一个IndexWriter来控制。一个存储不应该超过2G,即使是2G,每次索引更新都需要10分钟左右来优化索引。至于如何分配索引,要根据实际情况来决定,而且要考虑诸如程序崩溃等情况。

在Java版的搜索引擎解决方案中有很多可以借鉴的地方,比如,对于数据索引,Compass的索引方式可以参考;对于抓取式的搜索引 擎,Nutch可以参考;分布式解决方案可以参考Hadoop。如何实现像Compass一样,添加、删除、更新都能及时反映到索引当中,站内搜索引擎一 般都会面临这样的问题。Lucene.Net已经为我们提供了实现的方法,至于实现的逻辑需要你去思考。

 

6、索引小节

本篇文章是索引部分的完结篇。从第一篇到这里第七篇,主要介绍了两个东西,一个是Lucene.Net的逻辑存储,另外一个就是如何操作逻辑存储。 在逻辑存储上讲得比较详细,特别是关于权重部分,而操作则只简单提一下。因为,逻辑存储有助于理解Lucene.Net索引的流程,而操作则只是相当于 CPU的指令,业务逻辑需要自己去实现。相信看了以上七篇文章,有助于对Lucene.Net索引的理解,当然,这里只讲了表面上的东西,更加深入地理解 Lucene需要从更加底层的Directory入手。索引部分就暂时写到这里了,后面将进入搜索问题的探讨。

[Flex]Flex与.NET互操作(五):使用FileReference+HttpHandler实

mikel阅读(582)

 在Flex的应用开发中,同ASP.NET,JSP,PHP等应用一样,都会有上传/下载文件的应用需求,Flex的SDK也为我们提供了专门的类FileRefUdderence实现文件上传/下载 。Flex只是作为一个客户端,要实现上传或下载必须得为其提供一个服务端来接受上传或下载的请求,本文以ASP.NET中的HttpHandler作为文件上传的服务端来完成上传功能。

     OK,我们从Flex客户端开始,看看客户端是通过什么方式想服务端发起请求。Flex客户端要完成文件上传下载都是通过FileRefUdderence来实现,首先得定义一个该类型对象实例:

1 [Bindable]
2 private var stateText:String = "请选择一个文件上传";
3 //通过调用file对象的方法来完成上传和下载功能
4 private var file:FileReference = new FileReference();

 

     上传文件通常涉及到的有选择文件、上传文件以及上传完成这些最基本的处理过程。OK,下面我们就以这三个过程为例来看看Flex是怎么来完成文件的上传功能。首先为这三个功能点分别添加监听事件处理函数,在程序加载时调用:

1 internal function initApp():void
2 {
3     file.addEventListener(Event.Select,onSelected);
4     file.addEventListener(Event.COMPLETE,onCompleted);
5     file.addEventListener(ProgressEvent.PROGRESS,onProgress);
6 }

 

     另外我们也可以不用上面这中定义一个函数在程序加载时调用进行初始化操作,应用程序(mxml)的初始化操作又 creationComplete方法完成,另外还有一个比它先执行的方法createChildren(),我们可以直接在mxml下重写该方法来实现 应用程序的初始化,如下:

1 /**
2  * createChildren 比 creationComplete 事件更早发生
3  * */
4 protected override function createChildren():void
5 {
6     file.addEventListener(Event.Select,onSelected);
7     file.addEventListener(Event.COMPLETE,onCompleted);
8     file.addEventListener(ProgressEvent.PROGRESS,onProgress);
9 }

 

     这三个事件处理函数的详细定义如下(其中的stateText为String的变量,用于显示文件上传状态提示):

 1 internal function onSelected(evt:Event):void
 2 {
 3     stateText = "选择了文件" + file.name;
 4 }
 5 
 6 internal function onCompleted(evt:Event):void
 7 {
 8     stateText = "上传完毕!";
 9 }
10 
11 internal function onProgress(evt:ProgressEvent):void
12 {
13     stateText = "已上传 " + Math.round(100 * evt.bytesLoaded / evt.bytesTotal) + "%";
14 }

 

     到这里客户端就只差一步了,那就是完成发起上传请求的方法,实际上就是通过URLRequest对象创建一个与服务端的连接,然后直接调用FielReference类的upload()方法就可完成该功能,详细如下代码定义:

 1 /**
 2  * 调用FileReference的实例方法upload()实现文件上传
 3  * */
 4 internal function onUpLoad():void
 5 {
 6     if(file.size > 0)
 7     {
 8         stateText = "正在上传文件:" + file.name;
 9     }
10     var request:URLRequest = new URLRequest();
11     request.url="http://localhost/Web/UpLoadHandler.ashx";
12     file.upload(request);
13 }

 

     写好了upload方法,现在就是调用他了,通过按扭的click事件直接调用就可以,另外调用file.browse()方法则实现选择文件的功能,如下mxml代码描述:

1 <mx:TextInput x="10" y="57" id="txtFile" text="{stateText}" width="229"/>
2 <mx:Button x="247" y="57" label="选择" fontWeight="normal" click="{file.browse()}"/>
3 <mx:Button x="29" y="111" label="上传文件" width="111" fontWeight="normal" click="onUpLoad()"/>

 

     如上便完成了上传文件的Flex客户端开发,通过file.upload()方法,将把选择的文件通过二进制的形式发送到指定的服务端, 并自动传递一个叫“fileName”的参数,服务端通过fileName便可以接收到客户端请求上传的文件。最后我们来看看服务端的 UpLoadHandler.ashx的详细定义:

 1 public class UpLoadHandler : IHttpHandler
 2 {
 3     //文件上传目录
 4     private string uploadFolder = "UpLoad";
 5 
 6     public void ProcessRequest(HttpContext context)
 7     {
 8         context.Response.ContentType = "text/plain";
 9 
10         HttpFileCollection files = context.Request.Files;
11         if (files.Count > 0)
12         {
13             string path = context.Server.MapPath(uploadFolder);
14             HttpPostedFile file = files[0];
15 
16             if (file != null && file.ContentLength > 0)
17             {
18                 string savePath = path + "/" + context.Request.Form["fileName"];
19                 file.SaveAs(savePath);
20             }
21         }
22         else
23         {
24             context.Response.Write("参数错误");
25             context.Response.End();
26         }
27     }
28 
29     public bool IsReusable
30     {
31         get
32         {
33             return false;
34         }
35     }
36 }

 

     如上一系列的步骤便可完成上传文件的功能,下面便是上传文件示例程序运行截图:     
     

 

     实现了文件上传下面来看看怎么实现文件下载, 以上面上传示例中上传的mp3为例,下面我们来看看怎么从服务器(http://localhost/Web/UpLoad/做你的爱人.mp3)上完成文件(做你的爱人.mp3)的下载。

     要实现文件下载对服务器端只要保证被下载文件存在就OK,同上传文件一样需要实例化一个FielReference对象的实例,并为其添加相应的事件处理函数:

1 private var fileDown:FileReference = new FileReference();

 

 1 /**
 2  * createChildren 比 creationComplete 事件更早发生
 3  * */
 4 protected override function createChildren():void
 5 {
 6     super.createChildren();
 7     file.addEventListener(Event.Select,onSelected);
 8     file.addEventListener(Event.COMPLETE,onCompleted);
 9     file.addEventListener(ProgressEvent.PROGRESS,onProgress);
10     //实现文件下载
11     fileDown.addEventListener(Event.COMPLETE,onDownCompleted);
12     fileDown.addEventListener(ProgressEvent.PROGRESS,onDownProgress);
13 }

 

     如上为实现下载文件的实例fileDown注册了成功下载文件后事件处理函数和下载过程处理函数,下面是两个方法的详细定义:

 1 internal function onDownCompleted(evt:Event):void
 2 {
 3     var fileRef:FileReference = evt.currentTarget as FileReference;
 4     resultLabel.text = "文件名:" + fileRef.name + "下载完毕!";
 5 }
 6 
 7 internal function onDownProgress(evt:ProgressEvent):void
 8 {
 9     downState.text = "已下载: " + Math.round(100 * evt.bytesLoaded / evt.bytesTotal) + "%";
10 }

 

     完成了对象事件的开发,最后便上惩罚下载请求了,直接调用FileReference类所提供的download()方法既可:

1 /**
2  * 调用FileReference类的实例方法download()实现文件下载
3  * */
4 internal function onDownLoad():void
5 {
6     var request:URLRequest = new URLRequest();
7     request.url="http://localhost:1146/UpLoad/做你的爱人.mp3";
8     fileDown.download(request);
9 }

 

     程序执行到download()方法的时候会自动弹出选择保存文件对话框,根据实际情况选择好保存路径就OK。下面是实现上传和下载的完整代码:

实现上传和下载的完整代码

 

     程序运行截图:

      

 

版权说明

  本文属原创文章,欢迎转载,其版权归作者和博客园共有。  

  作      者:Beniao

 文章出处:http://beniao.cnblogs.com/  或  http://www.cnblogs.com/

 

[MVC]在IIS上部署ASPNETMVC Beta网站

mikel阅读(805)

IIS上部署ASPNETMVC Beta网站

IIS上部署ASPNETMVC Beta网站,实际上和在IIS上部署其他类型的网站并没有太大的区别。个人觉得唯一比较有意思的是在配置IIS时,我们可以配置各种自定义的ISAPI扩展名(也在MVC应用配置的,通常在Global.asax中)

第一步:安装MVC

当然,首先要下载MVC Beta下载链接

安装的前提是.NET Framework 3.5,如果已经装有.NET Framework 3.5,直接下一步下一步安装就可以了。

第二步:安装IIS

安装IIS通常需要系统盘。

安装步骤如下:控制面板——>添加删除程序——>添加删除Windows程序——>如果是XP,直接勾选上IIS就可以了,如果是SERVER 2003,通常是在Application Server(中文大概是应用程序服务一类吧)选项中。——>点下一步安装就是了。

第三步:配置IIS

在整个部署的过程中,配置IIS最为麻烦。不同的网站往往会有不同的配置,下面是一个配置的例子:

1.       IIS上新建Web站点,打开IIS后,如下图选择新建站点。之后按向导可配置站点描述,站点目录,是否允许匿名访问,以及读写权限的配置。 

 

              

2.       配置站点端口和连接时限。其中端口号默认是80,如果有其它站点也是80,得改变其中一个端口号,避免冲突;或者可以把其他站点停掉(如果其他的暂时不用的话)。 

 

            

3.       配置目录和读写权限  

       点击Configuration,会弹出中间的那个对话框。可以把不用的扩展名选项删掉(更加安全)。点击靠上的那个Edit选项,把在Verify that file exists的勾选去掉,在Wildcard 下面添加ISAPI路径,通常是:C:"WINDOWS"Microsoft.NET"Framework"v2.0.50727"aspnet_isapi.dll

4.       禁止匿名访问

 

         

[C#]谈谈VS中的模板

mikel阅读(1266)

基本上,我们每次在VS中新建一个项目(Project)或项(Item)的时候,都用到了它的模板。这些模板给我们提供了一个好的开始。如果你曾 经历过从ASP.NET Web Application到AJAX Web Application的升级,就会对此有所体会;如果你是一个开源爱好者,需要在项目中应用大量的开源组件,那么每次的添加引用和配置也会让人厌烦。模 板给我们节省了很多时间,并能使同类型的项目/项保持一致。

在VS中我们可以很方便地导出项目/项模板,可以参考下面两篇文章:

在VS2005中创建项目模板来提高开发效率

制作Visual Studio项目模板

本文将介绍模板的更多内容。

什么是项目/项模板

项目模板包含了创建特定类型的项目所需的必要文件(包括引用)。VS本身就提供了很多内置的项目模板,如Console Application, Class Library和ASP.NET Web Application等等。大部分项目模板基于一种特定的语言,如C#、F#等,同时针对特定的领域,如Windows、Web和Test等等,它们正 是以此进行分类组织:

add-new-proj

这里,创建一个控制台应用程序,

create-a-console-application

基本的引用已经添加完毕,并且有了一个Program.cs文件,接下来就可以在Main函数编写代码了。

项模板用于创建逻辑上的单个文件(有时可能是创建了多个文件,比如Web Form模板,不过它们在逻辑上仍被看作单个文件)。这个过程就不再赘述了。

项目/项模板简析

现在该了解一下这些模板是如何实现的了。前面提到,VS内置了很多模板,那就看看它们是怎么做的。

先来看项目模板,内置的项目模板位于[VS2008 Path]\Common7\IDE\ProjectTemplates,这里可以看到几个以语言名称命名的文件夹,进入CSharp,则是 Windows、Web、Test等文件夹,这是前面提到的模板组织方式。继续下去,打开Windows\1033文件夹,可以看多几个zip文件包。从 文件名可以想到,VS当中看到的模板就是这里的一个zip包。

事实正是如此。解压缩ConsoleApplication.zip文件,这里有四个文件:

contents-of-console-template

.cs和.csproj文件就是创建项目后得到的文件,那vstemplate文件呢?它是模板的组织者,没有它,zip包就只是几个零散的文件而已。这个文件称为模板清单(Template Manifest),它实际上就是一个XML文件。

项模板的情况与此类似,它们位于[VS2008 Path]\Common7\IDE\ItemTemplates。

模板清单(Template Manifest)

清单文件是XML文件,它的Schema文件是[VS2008 Path]\XML\Schemas\1033\vstemplate.xsd,通过xsd文件我们可以了解清单文件的结构。

它的根节点是<VSTemplate>,该节点有两个Attribute:

  • Type:指定模板类型(项目模板还是项模板),取值可以是Project、ProjectGroup或Item;
  • Version:模板所用于的.NET Framework版本号。

该节点在Class文件的模板中是这样的:

<VSTemplate Version="3.0.0" Type="Item" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
</VSTemplate>

<VSTemplate>节点可以有四种子节点:

  • <TemplateData>:必选项,包含了模板的基本信息,如名称、图标、默认名称等。
  • <TemplateContent>:必选项,指定了模板所包含的文件。
  • <WizardData>:可选项,包含了传给自定义向导的XML数据。
  • <WizardExtension>:可选项,包含了一些自定义模板向导的信息。

由于这些节点包含的信息比较多,这里只好偷懒了,它们在MSDN的链接分别是:

另外还可以看看Visual Studio Templates主页项目模板和项模板之间的区别

有了上面这些知识,就可以对清单文件有全面的认识了,下面来看看如何创建模板。

创建模板

项目模板和项模板的创建有所不同,但是都有两种方式:自动方式和手工方式。使用自动方式,跟随VS的向导创建模板,而使用手工方式,则需要编写一些代码,尤其是前面提到的清单文件。一般情况下,自动方式更为简单、快捷,而手工方式则更为强大和灵活。

手工方式创建模板

其过程包含三个步骤:

  • 创建模板所包含的文件;
  • 创建清单文件,编写代码对模板进行配置;
  • 部署。

首先创建一个类库项目,它的结构如下所示:

myclasslib-arch

接下来在MyClassLibTemplate.vstemplate文件内对模板进行配置:

XML Code – 第一个模板清单文件
<VSTemplate Version="2.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
    
<TemplateData>
        
<Name>My ClassLib Template</Name>
        
<Description>A simple class library template</Description>
        
<ProjectType>CSharp</ProjectType>
        
<ProjectSubType></ProjectSubType>
        
<SortOrder>1000</SortOrder>
        
<CreateNewFolder>true</CreateNewFolder>
        
<DefaultName>MyClassLibProj</DefaultName>
        
<ProvideDefaultName>true</ProvideDefaultName>
        
<LocationField>Enabled</LocationField>
        
<EnableLocationBrowseButton>true</EnableLocationBrowseButton>
        
<Icon>ufo.ico</Icon>
    
</TemplateData>
    
<TemplateContent>
        
<Project TargetFileName="MyClassLib.csproj" File="MyClassLib.csproj"
                 ReplaceParameters
="true">
            
<ProjectItem TargetFileName="SampleClass.cs" ReplaceParameters="true" >
                SampleClass.cs
            
</ProjectItem>
            
<Folder Name="Properties" TargetFolderName="Properties">
                
<ProjectItem ReplaceParameters="true" TargetFileName="AssemblyInfo.cs">
                    AssemblyInfo.cs
                
</ProjectItem>
            
</Folder>
        
</Project>
    </TemplateContent>
</VSTemplate>

最后是部署。将所有这些文件放在一起(如果有文件夹,要保持它的层次结构),打包为zip文件。将文件拷贝到下面两个路径之一:

  • 如果是项目模板,拷到[My Documents Path]\Visual Studio 2008\Templates\ProjectTemplates;
  • 如果是项模板,拷到[My Documents Path]\Visual Studio 2008\Templates\ItemTemplates。

由于刚才创建的模板是项目模板,所以放在第一个路径下。然后打开VS 2008,新建一个项目,在My Templates下可以看到我们自定义的模板:

add-a-custom-project

关于以自动(向导)方式创建模板,可以参考本文开头提到的两篇文章。

自定义模板

前面的例子很简单,甚至是过于简单了。在真实的开发中,可能需要向模板传递一些参数。

首先,需要在文件中插入占位符,如$Author$,Author就是参数的名称。看下面的例子:

C# Code – 设置模板参数占位符
namespace ClassLibrary1
{
    
// Company: $Company$
    
// Created By: $Author$
    public class SampleClass
    {
    }
}

接下来需要在模板清单文件中定义这些参数和它们的值,向<TemplateContent>节点中添加<CustomParameters>节点:

XML Code – 设置参数值
<CustomParameters>
    
<CustomParameter Name="$Company$" Value="my company" />
    
<CustomParameter Name="$Author$" Value="Anders Cui" />
</CustomParameters>

好了,现在重新部署这个模板,添加一个新项目,得到的文件是:

C# Code – 使用参数之后
namespace ClassLibrary1
{
    
// Company: my company
    
// Created By: Anders Cui
    public class SampleClass
    {
    }
}

需要注意的是,相关ProjectItem的ReplaceParameters特性值要为“true”。现在,如果模板中有10个文件用到了$Author$,就能节省不少时间了,不过我还是不满足,能不能在运行时获取用户的输入呢?看看下一节关于向导的内容。

自定义模板向导

VS模板的一个增强特性就是自定义向导,这些向导可以在用户由模板创建项目/项的时候运行。向导的好处在于可以:

  • 收集用户的输入信息;
  • 向模板添加参数值;
  • 向项目添加其它文件;

使用模板向导,可以访问DTE对象(Development Tools Extensibility,是Visual Studio自动化对象模型中的主对象),从而可以方便地操作项目。创建模板向导的基本步骤为:

  • 创建一个程序集,它要实现IWizard接口;
  • 将该程序集注册到GAC(Global Assembly Cache);
  • 更新模板清单文件,使用该程序集。

这里将继续使用上面的例子,不过这次要从用户界面收集参数值,而不是把它们放在模板清单中。

先来实现IWizard接口,该接口有6个方法,这些方法会在项目模板生命周期的特定时刻执行,其中的部分方法仅适用于项模板,它们的详情请参考:IWizard成员

当Visual Studio开始创建项目时,它立即调用RunStarted方法,因此该方法是收集用户输入信息的良好位置。它有四个参数:

  • Object 参数,可强制转换为根 _DTE 对象,以使您能够自定义项目。
  • Dictionary 参数,它包含模板中所有预定义参数的集合。
  • WizardRunKind 参数,它包含有关所使用的模板种类的信息。
  • Object 数组,它包含通过 Visual Studio 传递给向导的一组参数。

在本例中,将来自用户的输入添加到Dictionary参数中。好了,现在可以开始编码了,新建一个类库项目,名称为CustomTemplateWizard,新建一个Windows Form,用来接受用户输入,界面大体如下:

其代码为:

C# Code – 接受用户输入的窗体

下面的类WizardImpl实现了IWizard接口:

C# Code – 实现IWizard接口的类WizardImpl

然后,编译项目,为项目添加强命名,接着注册到GAC(Global Assembly Cache)。

接下来要修改模板清单文件,来使用新出炉的程序集,这要在</TemplateContent>之后添加:

XML Code – 添加对程序集的引用

这些都完成后,跟前面一样,打包、部署,然后打开VS,新建一个项目,此时出现一个对话框,在这里输入信息:

info-collector2

点击确定,生成的文件中可以看到参数已被替换:

replacedfile

初学者工具包(Starter Kits)

初学者工具包是一种特殊的项目模板,用于与其他开发人员分享示例代码和代码资源,可以看作是加强版的项目模板。初学者工具包往往包含了项目模板的所有内容,还可能包含额外的文档内容。

小结

本文首先简单介绍了项目/项模板的概念,然后介绍了模板及其清单文件的结构,在此基础上演示了如何手工创建并部署模板。最后讨论了两种更为灵活和强大的方式:向模板传递参数以及自定义模板向导,后者借助于DTE对象可以完成很复杂的功能。

参考

《Professional Visual Studio® 2008 Extensibility》

MSDN

作者:Anders Cui
出处:http://anderslly.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

[Flex]Flex与.NET互操作(六):Flex和.NET协同开发利器FluorineFx

mikel阅读(774)

   在本系列前面几篇文章中分别介绍了通过WebService、HTTPService、URLLoader以及FielReference等 组件或类来完成Flex与.NET服务端的通信的相关知识点。通过这些方式来完成与服务端的通信是非常方便和简单的,但有他的缺点就是通信数据量较小,如 要传输大量的数据或是实现不同对象的序列化传输,它们则满足不了我们的需求,需要寻找另外一种通信协议,另一种高效的传输协议来代替SOAP协议传输的方 案,那便是AMF(ActionScript Message Format)协议。

     开源项目FluorineFx就是专门针对.NET平台与Flex通信提供的AMF协议通信网关,我们可以通过FluorineFx很方便的完成与.NET的通信。

     FluorineFx官方提供了安装包的下载和在线文档,可以帮助我们有效的利用FluorineFx来开发。 

     FluroineFx官方网站http://www.fluorinefx.com/    

     FluroineFx下载地址:http://www.fluorinefx.com/download.html

     FluroineFx在线文档:http://www.fluorinefx.com/docs/fluorine/index.html

     

     OK,下面我们来看看使用FluroineFx通信的.NET和Flex配置。开发环境选择如下:

     .NET:Microsoft Visual Studio 2008 + .NET Framework 3.5

     Flex:Adobe Flex Builder CS3 + Flex SDK 3.2

     FluroineFx:FluorineFx v1.0.0.15 (点击可下载)

 

 一、.NET服务端的开发

     通过Microsoft Visual Studio 2008 创建创建解决方案,并添加FluroineFx服务器库,如下图示:

     FluorineFx服务库添加成功后会发现,项目模板会自动为我们创建一个Sample类和一个Echo方法,如下:

 1 namespace FlexDotNet.ServiceLibrary
 2 {
 3     /// <summary>
 4     /// Fluorine sample service.
 5     /// </summary>
 6     [RemotingService("Fluorine sample service")]
 7     public class Sample
 8     {
 9         public Sample()
10         {
11         }
12 
13         public string Echo(string text)
14         {
15             return "Gateway echo: " + text;
16         }
17     }
18 }

 

     接着添加FluorineFx 网站到解决方案,添加成功后网站会自动引用FluorineFx服务库的dll。如下图:

     到这里我们可以简单的测试FluorineFx的.NET服务端是否成功创建。通过在浏览器中查看FluroineFx网站中的Console.aspx或是将网站设置为启动项目并设置Console.aspx为启始页运行网站都可以,程序便会运行到FluorineFx的控制台,展开左边项目的Services节点便会看到上面模板为我们创建的类和方法,点击方法节点在右边就可以进行简单的测试了,如下图示:

     

     OK,到这里.NET的服务器端就开发完成了,这里我们需要记住几点,在接下来的Flex开发中需要根据这些参数来进行配置。

     FluorineFx的.NET网站目录:F:\Demo\FlexDotNet\Web

     FluorineFx的.NET网站虚拟目录:/Web

     FluorineFx的.NET网站URL:http://localhost:2836/Web

     接受Flex客户端请求的URL:http://localhost:2836/Web/Gateway.aspx

     有了上面这些东西配置Flex就简单了,首先创建Flex项目,并将项目路径指向前建立的FluorineFx网站的根路径:

     如上图,将Application type设置为:Web application,Application Server type设置为:ASP.NET,然后“Next”。进入下一个创建项目向导界面,将Server设置为:"Use Internet Information Services (IIS)",Web Application root同样指向FluorineFx网站的根路径,Web Appliation URL则设置为上面我们获取到的路径便OK,详细见下图:

     按照上面步骤配置好后通过点击“Validate Configuration”进行配置验证,如过验证结果是: The web application root and the URL are valid.则代表配置正确,可以直接点下一步只到完成项目的创建。

     Flex项目创建完毕,下面在通过一些相应的配置就可以通过FluorineFx和.NET通信了。开发项目属性设置面板,设置其Flex Compiler为下图所示(-services的配置也可以设置为相对路径):

     设置Flex Server为如下配置,可以点“Validate Location”验证设置的正确性:

     最后设置输出路径就完成了Flex端的配置了:

 

     到这里Flex端的配置就全部完成,下面我们通过FluorineFx库模板为我们生成的Sample为例来测试下该环境是否可以通过,在Flex的mxml文件下通过<mx:RemoteObject>标签来访问远程对象,详细如下:

1 <mx:RemoteObject id="service" destination="fluorine"
2     source="FlexDotNet.ServiceLibrary.Sample">
3         <mx:method name="Echo" result="onResult(event)">
4         </mx:method>
5 </mx:RemoteObject>

 

     这里需要注意的是destination需要设置为与remoting-config.xml中的destination的id一 致,source则配置为远程对象的全路径(名称空间+类),通过<mx:method>标签配置远程对象下的方法并设置其成功调用后的结果 处理函数,下面便可通过id去调用远程方法了。

 1 <mx:Script>
 2     <![CDATA[
 3         import mx.rpc.events.ResultEvent;
 4         internal function onClick():void
 5         {
 6             service.Echo(txtInput.text);
 7         }
 8         
 9         internal function onResult(evt:ResultEvent):void
10         {
11             txtResult.text = evt.result.toString();
12         }
13     ]]>
14 </mx:Script>

 

下面是完整的Flex客户端mxml的代码定义:

完整的示例代码

 

本文示例截图:
     

 

版权说明

  本文属原创文章,欢迎转载,其版权归作者和博客园共有。  

  作      者:Beniao

 文章出处:http://beniao.cnblogs.com/  或  http://www.cnblogs.com/

 

[杂记]告诉你喝水的14个惊人真相收藏

mikel阅读(829)

如今,重视喝水的人,越来越多了;但真正会喝的人,却为数不多。
不挑时间地喝、不计较内容地喝、不动脑筋地喝……都只能证明你只是喝水,却不一定是喝对了水。
在这个爱惜身体成为一种流行的年代,曾经被认为最简单的喝水,也不得不成了一 门高深的学问。
1、清晨慎补水

许 多女人把起床后饮水视为每日的功课,图它润肠通便,降低血粘度,让整个人看上去水灵灵的。可是早晨怎样补水才更健康呢?其实,没有一定之规,早餐补水也要 因人而异。消瘦,肤白,体质寒凉的人,早晨不适合饮用低于体温的牛奶,果汁或冷水,可以换作温热的汤、粥。 鲜榨果汁不适合早晨空空的肠胃,即使是在夏季也要配合早餐一起饮用。 早晨补水忌盐,煲的浓浓的肉汤、咸咸的馄饨汤都不适合晨,只会加重早晨身体的饥渴。。
2、餐前补水最养胃
吃 饭前还要补水吗?那不是会冲淡胃液影响消化吗?西餐有餐前开胃的步骤,其道理在于利用汤菜来调动食欲,润滑食道,为进餐做好准备。那么,饭前补水也就有着 同样的意义,进固体食物前,先小饮半杯(约100毫升),可以是室温的果汁、酸奶,也可以是温热的冰糖菊花水或淡淡的茶水,或者是一小碗浓浓的开胃汤,都 是很好的养胃之法。
3、多喝看不见的水

有的人看上去一天到晚都不喝水,那是因为由食 物中摄取的水分已经足够应付所需。食物也含水,比如米饭,其中含水量达到60%,而粥呢,就更是含水丰富了。翻开食物成分表不难看出,蔬菜水果的含水量一 般超过70%,即便一天只吃500克果蔬,也能获得300~400毫升水分(有两怀呦)。加之日常饮食讲究的就是干稀搭配,所以从三餐食物中获得 1500~2000毫升的水分并不困难。不如充分利用三餐进食的机会来补水吧,多选果蔬和不咸的汤粥,补水效果都不错。
4、记住利水食物
所 谓利水食物是指能增加身体水分排泄的食物,如西瓜、咖啡、茶等含有利尿成分,能促进肾脏尿液的形成;还有粗粮、蔬菜水果等含有膳食纤维,能在肠道结合大量 水分,增加粪便的重量;辛辣刺激的成分能促进体表毛细血管的舒张,让人大汗淋漓、体表水分流失。补也好、利也好,都是达到身体水分平衡的手段。
5、畅饮与美容无关
身 体缺少水分,皮肤看上去会干燥没有光泽;饮水过少还容易发生便干,甚至便秘,皮肤很容易生小痘痘。虽说如此,单单补充水分对肤质和肤色的影响毕竟有限,不 过现在很多添加维生素的饮料打出了美容牌,比如一种含乳饮料里面含有维生素B6,其产品声称“能令皮肤润滑细嫩”,而现在含有这种“美容维生素”的饮料还 真不少。正统的营养学专著中并没有提到它的美容作用,好在摄入多些一没有危险,二还可以预防冠心病的发生,也算有益无害吧。
6、水里的“杀机”
经过煮沸的自来水可能含有具有致癌性的高氯化合物,如经较长时间放置(隔夜)水质会发生老化。 现在各种家用水处理机也纷纷登场,类似曾风靡一时的矿泉壶,这样的设备存在后续维护的问题,就如同饮水机,可能成为饮用水二次污染的源头。
7、喝运动饮料的学问
剧 烈运动前后不能补白水,也不能补高浓度的果汁,而应补运动饮料。运动饮料中应该含有少量糖分、钠盐、钾、镁、钙和多种水溶性维生素,以补充运动中身体所失 及所需。饮白水会造成血液稀释,排汗量剧增,进一步加重脱水。果汁中过高的糖浓度使果汁由胃排空的时间延长,造成运动中胃部不适。运动饮料中特殊设计的无 机盐和糖的浓度会避免这些不良反应。运动饮料的温度也讲究,过高不利于降低体温散热,过凉会造成胃肠道痉挛,一般应口感清凉,温度在10左右。
8、警惕酸味饮料
各 种果汁饮料多采用柠檬酸作味剂,柠檬酸食用过多,大量的有机酸骤然进入人体,当摄入量超过机体对酸的处理能力时,就会使体内的PH值不平衡,导致酸血症的 产生,使人疲乏,困倦。特别是在盛夏,由于天气炎热,出汗较多,人体会损失大量的电解质,如钾、钠、氯等碱性成分,大量的酸味饮料更容易令体液呈酸性。因 此,在夏季不宜过多饮用添加有机酸的酸味饮料。
9、甜饮料的陷阱
如果口渴的时候首先 想到的是饮料,可是相当危险的。可乐、雪碧、芬达的含糖量是11%,超过了西瓜、苹果、柑橘等很多种水果,一听350毫升的可乐所含的能量等同于一片面 包、一个玉米或250克水果。各种果汁的含糖量与此相当,甚至还要更高于它。脉动、她/他、激活等看上去像水的维生素饮料也含有3%的糖分,如果喝上一大 瓶(600毫升吧),对体重的影响相当可观。也的确听说过有人因为暴饮甜饮料而罹患糖尿病的不幸遭遇呢。
10、淡盐水的坏处

淡 盐水是指相当于生理浓度的盐水,每百毫升中含 1克左右的盐分,它在日常生活中有几种用途:一、大汗之后补充身体丢失的水分和钠;二、腹泻之后补充由肠道丢失的水分和盐,维持电解质的平衡;三、淡盐水 漱口能清除口腔内的细菌,减轻口咽部炎症造成的红肿。但是,淡盐水不适合心脏功能不好,有高血压的人饮用,特别是在早晨,当血液粘稠度最高时,饮用淡盐水 会加重口干,促进血压升高。
11、识破“花样”水
纯净水,经多重过滤去除了各种微生 物、杂质和有益的矿物质,突出的是饮用的安全性,它是一种软水,许多人认为它不够营养,长期饮用不利健康,可是这种观点未被证实。矿泉水,是种自然资源, 由地层深处开采出来,含有丰富的稀有矿物质,略呈碱性,应该更有利于健康,但是不排除有机物污染的可能。矿物质水,在纯净水中按照人体浓度比例添加矿物质 浓缩液配制而成的人工矿泉水,标志着饮用水科技的新高度。
12、爱运动更要会补水
运动补水要掌握以下原则:
1)不能渴时才补。因为感到口渴时,丢失的水分已达体重的2% 。
2).运动前、中、后都要补水。运动前2小时补250-500毫升;运动前即刻补150-250毫升;运动中每15~20分钟补120-240毫升;运动后按运动中体重的丢失量,体重每下降1千克需补1升。
13、勤补水不明智
身 体处于稳定状态的时候,每天正常补水1000~2000亳升,让小便保持清亮充沛就可以了。但是如果自觉或不自觉地大量饮水,这其中就有问题了。首先,说 明你的身体可能处于脱水状态,身处高温环境,大量排汗或大量进食盐分都可能千百万这种情况,那么补水是必要的;其次,如果存在高血糖、垂体或肾脏功能异常 的情况;或者处于感昌、发烧等感染性疾病中;又或者有泌尿系统炎症,甚至是一名高尿酸血症患者,那也可以主动大量饮水。而一个健康人在不感觉口渴的情况下 饮水超过2000毫升/天就实在没有必要了,那只不过是一再考验自身的肾脏功能罢了。
14、维生素C饮料多喝无益
新 上市的饮料中很多都含有维生素C,维生素C的益处自不必说,为了预防缺乏,每天人体需要补充60~100毫克。“酷儿”的维生素C含量为3~30毫克 /100毫升,“脉动”为25~50毫克/100毫升,“她”是15毫克/100毫升,也就是说,饮用此类饮料一瓶获得的维生素C就能满足每天的需要量。 那么,如果你饮用2瓶、3瓶,甚至更多呢?会不会发生维生素C中毒的情况呢?好在维生素C的安全范围广,但是千万不要以为它是多多益善的,过量摄入能引起 泌尿系统结石,渗透性腹泻以及大剂量维生素C依赖症。人们都希望自己青春永葆,容颜焕发,美容成为一种时尚。“饮水美容”价廉易行,深受人们欢迎。
人一刻离不开水,一旦缺水,不仅影响新陈代谢,还会使皮肤失去光泽而显得干燥衰老。
多喝开水,能发汗和增加皮脂分泌,使皮肤得以润滑。
清 早起床后不要急于舞剑弄棍,跳舞做操,应该先喝一杯开水。因为经过一夜睡眠、尿液和不显性失水会丢失水分,使血液粘稠度增高,循环阻力增大,心脑供血不 足,使人面容憔悴。清水一杯可以迅速被吸收,稀释粘稠的血液,改善脏器代谢,促进血液循环,使皮肤保持鲜亮光泽,具有自然美的魅力。这就是早已为生物学家 提倡的、“内洗涤法”。
饮用矿泉水,美容效果更好。矿泉水含有钙、镁、钠等多种矿物质及二氧化碳,能健脾胃,增食欲,使皮肤变得白嫩柔润,容颜焕发如玉。
常喝绿茶、薄荷茶、菊花茶也能得到美容的效果。茶叶有抑制亚硝基化合物的致癌功能,还有防治心血管病、清肝明目、养血解毒、固齿杀菌等作用。多喝茶水能加快体液循环,及时清除皮肤排泄物,使皮肤清洁湿润。
饮水美容要求少量多饮。每天饮水五六次,每次以一两杯为宜。饮用过量会加重心脏、肾脏的负担,使新陈代谢发生紊乱,从而削弱皮肤的抵抗力。
用 水美容除了“内洗涤法”,还有“外洗涤法”,那就是游泳与沐浴。游泳时由于水对皮肤的冲击,加速了血液循环,有益于面部、胸部健美,尤其是有益于丰乳。在 各种游泳姿势中,以“蝶泳”和自由式健美最佳。以这两种姿势游泳最有利于胸肌的坚韧和发达。沐浴也能收到面部、胸部健美的良好效果。国外流行一种对丰乳有 益的“水功法”。即在沐浴时让莲蓬头的水喷射胸部,以预防胸肌松弛。实践证明:经常以带有轻度压力的水流给乳房以磨擦,对增进胸部健美能起到甚为有效的作 用。
此外,在不便饮水和游泳沐浴的情况下,用湿毛巾多敷一下面庞,对面部美容也有一定的效果。
水,随处都有。用水美容健身,简便易行。愿君多饮水,容颜美

[ORM]关系数据库与面向对象的映射讨论

mikel阅读(785)

在博客园看到下面的文章尽管还是老生常谈,喊了这么多年的ORM,最终还是无果,框架也出了不少最后还是在讨论这个问题,下面是引用的原文:


引言

面向对象的三个特征: 封装(encapsulation), 继承(inheritance), 多态(polymorphic), 其中继承是我们三个特征中最重要的应该就是继承了.

我们在程序中可以很自然, 很方便的表达继承的关系. 但是针对这样的继承关系, 我们如何设计数据库呢?通常我们有三种方式:

1. 一个继承树映射到一个表(one inheritance tree mapping to one table)

这种方式是将拥有共同父类的所有的类都看做成一张表(包括父类), 然后所有的类的所有的属性取并集, 组成数据表的所有列.

image

如上图类的结构图, Vehicle是父类, 拥有两个属性Engine和wheel, 而子类Truck有属性Container, 子类Car有属性Acoustics.

数据表被映射成

类属性 数据表字段
Engine Engine
Wheel Wheel
Container Contianer
Acoustics Acoustics

优点: 结构简单, 在数据表操作层可以很方便的实现针对这三个对象的数据库的insert, update, delete.

缺点: 这样的设计数据表, 会有大量的数据冗余.

 

2. 一个继承路径映射一个表(one inheritance path mapping to one table)

按照这种方式: 创建两张表, 分别是Truck和Car.

Truck 数据表

类属性 数据表字段
Engine Engine
Wheel Wheel
Container Container

Car 数据表

类属性 数据表字段
Engine Engine
Wheel Wheel
Acoustics Acoustics

优点: 没有数据冗余.

缺点: 当需要查询Vehicle的时候, 就需要在Truck和Car两个表里面进行查询. 当有越多类继承Vehicle的时候, 查询的效率就越低.

 

3. 一个类映射到一个表(one class mapping to one table)

按照这种方式: 创建三张表, 分别是Vehicle, Truck和Car.

Vechile 数据表

类属性 数据表字段
ID(Primary Key)
Engine Engine
Wheel Wheel

Truck 数据表

类属性 数据表字段
ID(Foreign Key)
Container Container

Car 数据表

类属性 数据表字段
ID(Foreign Key)
Acoustics Acoustics

优点: 为每个类创建表, 子表和父表通过ID进行关联, 数据冗余小.

缺点: 当继承体系的非常复杂的时候, 一些SQL语句会非常复杂, 效率也会非常低下.

 

其实在上面三种方式中, 我们使用最多的最常见的应该算是第三种, 但是有些情况下, 我们也需要考虑下其他数据表的创建方式.

毕竟模式是在一些特定的场合下, 才能充分体现它的价值. 我们在开发的过程中, 在类的设计方面愿意花费很多人力物力, 但是数据库的设计

 

这是我的回复:

其实关系数据库结构和对象之间可以利用中间层进行映射
第三种方法,的查询复杂度可以利用视图来降低
其实这三种方法用哪一种都无所谓,完全可以利用中间视图将数据库关系和对象隔离开,让关系的归关系,对象的归对象