[CSS]Css Reset(复位)整理

mikel阅读(524)

Css Reset是什么? 有些同行叫 "css复位",有些可能叫 "默认css"…..
相信看完全文您会对Css Reset有个重新的认识

原文地址:
http://perishablepress.com/press/2007/10/23/a-killer-collection-of-global-css-reset-styles/

PS:

* {   
 padding: 0;   
 margin: 0;   
 } 

这就是最常用的Css Reset,但是这里会有很多问题。

原文前部分说了很多关于Css,以及各浏览器的css规则的不同,而制定"Css Reset"也是为了兼容与统一,正确有效的使用"Css Reset"可以在某种程度上节约时间与金钱.

非常感谢Perishable的整理与归纳

下面是关于几类Css Reset的简单介绍,本人能力有限.只能理解大概意思,还请各位看官见谅.

Minimalistic Reset [ Version 1 ]
相信这一段你经常看到.而且也是我们经常用到的

* {   
 padding: 0;   
 margin: 0;   
 }  

Minimalistic Reset [ Version 2 ]
border:0的设计有些不靠谱了

* {   
 padding: 0;   
 margin: 0;   
 border: 0;   
 }

Minimalistic Reset [ Version 3 ]
当然这个也是不推荐的.会跟某些默认样式有冲突

* {   
 outline: 0;   
 padding: 0;   
 margin: 0;   
 border: 0;   
 }   

Condensed Universal Reset
这是作者当前比较钟意的一种写法.保证了相对普遍浏览器样式的统一性.

* {   
 vertical-align: baselinebaseline;   
 font-weight: inherit;   
 font-family: inherit;   
 font-style: inherit;   
 font-size: 100%;   
 border: 0 none;   
 outline: 0;   
 padding: 0;   
 margin: 0;   
 }  

Poor Man’s Reset
其实这也是我们常用的一类Css Reset.对字体的大小复位,以及图片链接的边框处理.
也经常在某些站点看到

html, body {   
 padding: 0;   
 margin: 0;   
 }   
html {   
 font-size: 1em;   
 }   
body {   
 font-size: 100%;   
 }   
a img, :link img, :visited img {   
 border: 0;   
 }   

Shaun Inman’s Global Reset
作者认为Shaun写这类的Css Reset是有某种目的性.
而且这类规则是针对的是某些重要的常用浏览器.
比如ie,firefox等

body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre,    
form, fieldset, input, p, blockquote, table, th, td, embed, object {   
 padding: 0;   
 margin: 0;    
 }   
table {   
 border-collapse: collapse;   
 border-spacing: 0;   
 }   
fieldset, img, abbr {   
 border: 0;   
 }   
address, caption, cite, code, dfn, em,    
h1, h2, h3, h4, h5, h6, strong, th, var {   
 font-weight: normal;   
 font-style: normal;   
 }   
ul {   
 list-style: none;   
 }   
caption, th {   
 text-align: left;   
 }   
h1, h2, h3, h4, h5, h6 {   
 font-size: 1.0em;   
 }   
q:before, q:after {   
 content: '';   
 }   
a, ins {   
 text-decoration: none;   
 } 
  

Yahoo CSS Reset
yahoo这帮家伙写的Reset个人觉得可以推荐

body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,
fieldset,input,textarea,p,blockquote,th,td {    
 padding: 0;   
 margin: 0;   
 }   
table {   
 border-collapse: collapse;   
 border-spacing: 0;   
 }   
fieldset,img {    
 border: 0;   
 }   
address,caption,cite,code,dfn,em,strong,th,var {   
 font-weight: normal;   
 font-style: normal;   
 }   
ol,ul {   
 list-style: none;   
 }   
caption,th {   
 text-align: left;   
 }   
h1,h2,h3,h4,h5,h6 {   
 font-weight: normal;   
 font-size: 100%;   
 }   
q:before,q:after {   
 content:'';   
 }   
abbr,acronym { border: 0;   
 }

Erik Meyer’s CSS Reset
作者将Erik Meyer的代码重新整理了.但功能上还是一样的
这套Css Reset是业内是使用最多的

html, body, div, span, applet, object, iframe, table, caption, tbody, tfoot, thead, tr, th, td,    
del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var,    
h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code,    
dl, dt, dd, ol, ul, li, fieldset, form, label, legend {   
 vertical-align: baselinebaseline;   
 font-family: inherit;   
 font-weight: inherit;   
 font-style: inherit;   
 font-size: 100%;   
 outline: 0;   
 padding: 0;   
 margin: 0;   
 border: 0;   
 }   
/* remember to define focus styles! */  
:focus {   
 outline: 0;   
 }   
body {   
 background: white;   
 line-height: 1;   
 color: black;   
 }   
ol, ul {   
 list-style: none;   
 }   
/* tables still need cellspacing="0" in the markup */  
table {   
 border-collapse: separate;   
 border-spacing: 0;   
 }   
caption, th, td {   
 font-weight: normal;   
 text-align: left;   
 }   
/* remove possible quote marks (") from <q> & <blockquote> */  
blockquote:before, blockquote:after, q:before, q:after {   
 content: "";  
 }  
blockquote, q {  
 quotes: "" "";   
 }   

Condensed Meyer Reset
总的来说这是对Erik Meyer的Css Reset的修改与提升.

body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6,    
pre, form, fieldset, input, textarea, p, blockquote, th, td {    
 padding: 0;   
 margin: 0;   
 }   
fieldset, img {    
 border: 0;   
 }   
table {   
 border-collapse: collapse;   
 border-spacing: 0;   
 }   
ol, ul {   
 list-style: none;   
 }   
address, caption, cite, code, dfn, em, strong, th, var {   
 font-weight: normal;   
 font-style: normal;   
 }   
caption, th {   
 text-align: left;   
 }   
h1, h2, h3, h4, h5, h6 {   
 font-weight: normal;   
 font-size: 100%;   
 }   
q:before, q:after {   
 content: '';   
 }   
abbr, acronym {    
 border: 0;   
 }
   

最后有份关于Css Reset的使用者调查
http://css-tricks.com/poll-results-what-css-reset-do-you-use/

本文链接:http://www.blueidea.com/tech/web/2008/6165.asp 

[CSS]写自己的CSS框架 Part2:跨越浏览器的reset

mikel阅读(775)

2.1浏览器的差异在何处

 

     我想写CSS的人大多遇见过在IE里写的页面美轮美奂,而用FF打开却是分崩离析,反之亦然.这种痛苦是因为IEFF对一些默认样式的解析并不相同所导致.

      网上有很多为何不一样的例子,下面链接是一个比较全的不同之处,大家可以进去看看。

     http://hi.baidu.com/css%D6%AE%C3%C0/blog/item/f44628e6a506c229b83820ef.html

 

2.2如何实现跨浏览器

2.2.1实现原理

     既然问题出在FFIE对各种不同HTML元素的解析上所有偏差.更不用说一些其他小市场份额的浏览器上.我们只需要针对性的把页面里大多数HTML元素重置即可.这样在各种浏览器里面显示的效果会是相同的.

2.2.2实现方式

     重置我们选择的名称和大多数框架一样,reset.css,用我们Develper的思想理解——–框架中所有元素的基类,就像.net里的Object对象一样

     下面我们来说说reset.css的构成.

1.       首先定义最基本的body,因为所有其他元素都由此继承.我喜欢的框架遵循“尽量保持小”的原则,所以我只简单清除paddingmargin,以及设置字体(设置成具体数值,因为在后面用’em’做单位的时候都要以这里做比较,页面风格需要整体变化时,重载这里.)

2.       将大量浏览器预定义的块状元素清除maginpadding(块装元素即在未定义样式的情况下浏览器render出来的方式为display:block;的元素)

3.       让列表前面的符号消失,图片边框消失,p的上下边距为一行字.

     我喜欢reset.css尽量保持简洁.只要实现了基本的重置即可.

     PS:不过也不能过于简洁.记得曾经的框架喜欢对”*”这个CSS选择符重置.可是这个杀伤力太大,往往是杀敌1000自伤800,遇到input之类的表单元素时还得重置回来.最后据传说这样还有性能问题-.-!!不过难以考证

     下面是满足上面条件最基本的reset.css

 

 


1.body { 
2.    padding: 0; 
3.    margin: 0; 
4.    font: 13px Arial, sans-serif; 
5.    } 
6.    body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset ,p,blockquote { 
7.    padding: 0;
8.     margin: 0; 
9.    font-weight: normal; 
10. font-style: normal; 
11. line-height: 1em; 
12. font-size: 100%; 
13. } 
14. table { 
15. font-size: inherit; 
16. font: 100%; 
17. } 
18. ul { 
19. list-style: none; 
20. } 
21. img { 
22. border: 0; 
23. } 
24. p { 
25. margin: 1em 0; }

 

   这个reset.css是目前我个人最喜欢,因为reset.css就像.net中的Framework中的Object类一样,应该尽量保持精简,这个精简了很多.只留下了必要的重置.

   在这里值得一说的是:在body里将font的大小和字体设置了具体的值,在其他元素里通过继承的方式来重写这样的方式是我最喜欢的,这样可以很容易的保持页面整体风格的统一

2.3一些注意事项

   Reset.css一经写好,除了BUG之外.永远不要去修改它.而是在其它页面中重载它(不知道用OO的方式理解CSS是否正确,即利用CSS的优先级特性覆盖.这个在下一章说到.

[PHP]国外优秀开源PHP建站程序一览

mikel阅读(841)

大量的PHP开源(开放源代码/Open Source)应用改变了这个世界,改变了互联网,以下我们总结从数据库到购物、博客等众多类型的开源PHP软件,供网站开发者们参考。

博客:WordPress

WordPress是使用PHP开发的著名博客平台,免费开源,功能强大,不仅仅用于博客搭建,还可以广泛应用于各类网络信息发布平台。

论坛:phpBB

phpBB是一种广泛流行的开源论坛软件,具有易于使用的管理面板和友好的用户安装界面,可以轻松地在数分钟内建立起一个论坛,功能上具有很高的可配置性,能够完全定制出相当个性化的论坛。

CMS:Drupal

Drupal是一个开源的内容管理系统(CMS)平台,拥有强大并可自由配置的功能,能支持从个人博客到大型社区驱动的网站等各种不同应用的网站项目。

Wiki:MediaWiki

MediaWiki是PHP语言写成开源Wiki引擎,全世界最大的Wiki项目维基百科就是使用MediaWiki引擎。

Digg:Pligg

Pligg是一套灵活的类似Digg的Web2.0 CMS系统,系统使用PHP开发,模仿了国外流行的DIGG系统。

图像:Gallery

Gallery 是一个非常有名的免费开源图库相册软件,基于 PHP 和 MySQL, PostgreSQL 等数据库。功能非常强大,有丰富的扩展可以下载,安装很简单,有很多插件可用。

RSS:Gregarius

Gregarius是一个RSS聚合程序,免费开源,具备不错的用户体验,易于操作和管理。可以把其当成RSS阅读器使用。

电子商务osCommerce

osCommerce是一套由自由软件开发社团开发并维护的在线商店的解决方案,免费开源,并可以应用到任何的商业环境中,可以在短时间内生成一个功能强大的电子商务网站。

广告:OpenX

OpenX(原名phpAdsNew)是一个用PHP开发的广告管理与跟踪系统,适合各类网站使用,能够管理每个广告主拥有的多种任何尺寸横幅广告,按天查看,详细和概要统计并通过电子邮件发送报表给广告主。

数据库:phpMyadmin

phpMyAdmin是用PHP开发的MySQL的数据库管理工具。可以在Web界面上实现各种各样对MySQL数据库的管理和操作。

英文原文:Top Ten Open Source PHP Apps

[CSS]CSS框架

mikel阅读(1031)

CSS框架之一 YAML

CSS框架汇总

大家比较熟悉的是js框架,例如prototype、JQuery呀。其实XHTML+CSS也是有框架的,最著名的可能就是YUI了,是 yahoo开发 小组的。但是那个稍微有点庞大,而且牵扯到一些的JS框架。所以刚开始研究的时候可能稍微有点累。而这个yaml就比较单纯了。可能是现在还在发展初期所 以框架很简单,东西不多,对XHMTL+CSS框架感兴趣的可以去看看哦。在国内好像还没有那个朋友在做这个东西,如果你有兴趣,自己钻研一下说不定中国 的CSS框架之祖就是你了哦。呵呵。。
网址:http://www.yaml.de/en/ 里面有源码,开发文档以及一些使用此框架搭建的页面实例。

CSS框架之二 blueprintcss

CSS框架汇总
Features:

  • An easily customizable grid
  • Sensible typography
  • Relative font-sizes everywhere
  • A typographic baseline
  • An extendable plugin system
  • Perfected CSS reset
  • A stylesheet for printing
  • Compressed version
  • No bloat of any kind

CSS框架之三 Elements

一、什么是Elements
Elements是一款纯净的CSS框架,可以帮助设计师快速高效率的书写css文档。你可以将他理解成一套模板,里面包含了大多数站点中所需要的那些css类。他很小,只有四个文件而已。总共不到6KB。

二、这四个文件分别是做什么用?
Elements.css 归纳了一些站点css中常用的css类
Reset 对一些常用的html标签进行预设。例如html, body, div, span, applet, h1, h2, h3, h4, h5, h6….等等。
Typography 文字排版常用标签的预设。例如body,ul,ol,dl,td,th,caption,pre,p,blockquote,input,textarea等
External Links 对于各种文档形式的链接的预设。这个东西很早已经有人单独提出过。
CSS框架汇总

三、如何使用Elements CSS框架?

<link rel="stylesheet" type="text/css" href="/css/elements/elementsImport.css" />
大家可能注意到上面的图片中有5个css文件,其中的elementsImport.css只是将其他的四个css文件分别导入进来。

@import "reset.css";
@import "typography.css";
@import "elements.css";
@import "externalLinks.css";

Elements框架也许并不一定适合我们的站点开发,但是通过它我们可以找到一种好的架构方式。如果你经常会和css打交道,不论你是在做企业站还是门户站,好好的整理一下你以前的文档,根据你的需求制定自己的CSS框架,会很大程度上的提高你的开发效率。

3个CSS框架YAML+Blueprintcss+Elements (1806) – 308.08 KB


ShareThis

[MVC]在ASP.NET MVC中实现基于URL的权限控制

mikel阅读(858)

本示例演示了在ASP.NET MVC中进行基于URL的权限控制,由于是基于URL进行控制的,所以只能精确到页。这种权限控制的优点是可以在已有的项目上改动极少的代码来增加权限控 制功能,和项目本身的耦合度低,并且实现起来也比较简单。缺点是权限控制不够精确,不能具体到某一具体的按钮或者某一功能。

在数据库中新建2个表。PermissionItem表用于保存权限ID和页面路径的关系,一个权限ID可以有多个页面,一般同一个权限ID下的页面是为了实现同一个功能。PermissionList表用于保存用户所具有的权限。

 


USE [UrlAuthorize]
GO
/****** Object:  Table [dbo].[PermissionList]    Script Date: 07/07/2009 00:07:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create TABLE [dbo].[PermissionList](
    
[ID] [int] IDENTITY(1,1NOT NULL,
    
[PermissionID] [int] NOT NULL,
    
[UserID] [int] NOT NULL,
 
CONSTRAINT [PK_PermissionList] PRIMARY KEY CLUSTERED 
(
    
[ID] ASC
)
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]
ON [PRIMARY]
GO
SET IDENTITY_Insert [dbo].[PermissionList] ON
Insert [dbo].[PermissionList] ([ID][PermissionID][UserID]VALUES (121)
Insert [dbo].[PermissionList] ([ID][PermissionID][UserID]VALUES (231)
SET IDENTITY_Insert [dbo].[PermissionList] OFF
/****** Object:  Table [dbo].[PermissionItem]    Script Date: 07/07/2009 00:07:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
Create TABLE [dbo].[PermissionItem](
    
[ID] [int] IDENTITY(1,1NOT NULL,
    
[PermissionID] [int] NOT NULL,
    
[Name] [nvarchar](50NOT NULL,
    
[Route] [varchar](100NOT NULL,
 
CONSTRAINT [PK_PermissionItem] PRIMARY KEY CLUSTERED 
(
    
[ID] ASC
)
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]
ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_Insert [dbo].[PermissionItem] ON
Insert [dbo].[PermissionItem] ([ID][PermissionID][Name][Route]VALUES (11, N'测试页1', N'/Test/Page1')
Insert [dbo].[PermissionItem] ([ID][PermissionID][Name][Route]VALUES (22, N'测试页2', N'/Test/Page2')
Insert [dbo].[PermissionItem] ([ID][PermissionID][Name][Route]VALUES (33, N'测试页3', N'/Test/Page3')
Insert [dbo].[PermissionItem] ([ID][PermissionID][Name][Route]VALUES (51, N'测试页4', N'/Test/Page4')
Insert [dbo].[PermissionItem] ([ID][PermissionID][Name][Route]VALUES (62, N'测试页5', N'/Test/Page5')
SET IDENTITY_Insert [dbo].[PermissionItem] OFF

数据库中的示例表示Page1和Page4同属于权限1,Page2和Page5同属于权限2,Page3属于权限3。用户ID为1的用户具有权限2和3。

ASP.NET MVC项目中新建一个AccountHelper类,这是一个辅助类。GetPermissionItems方法用于获取权限ID和页面路径的对应关系。 这是全局的,并且每个用户在访问页面时都会用到这些信息,所以存入Cache中。数据库的相关操作这里使用的是ADO.NET Entity Framework。

 

 1/// <summary>
 2/// 获取权限项
 3/// </summary>
 4/// <returns>权限项列表</returns>

 5public static List<PermissionItem> GetPermissionItems()
 6{
 7     // 如果缓存中已经存在权限列表信息,则直接从缓存中读取。
 8      if (HttpContext.Current.Cache["PermissionItems"== null)
 9     {
10          // 如果缓存中没有权限列表信息,则从数据库获取并写入缓存
11           UrlAuthorizeEntities db = new UrlAuthorizeEntities();
12          var items = db.PermissionItem.Where(c => c.PermissionID > 0).ToList();
13          HttpContext.Current.Cache["PermissionItems"= items;
14     }

15
16     // 这个缓存中保存了所有需要进行权限控制的页面所对应的权限ID
17     return (List<PermissionItem>)HttpContext.Current.Cache["PermissionItems"];
18}

19

 

GetUserPermission方法是将用户所具有的权限ID保存到一个一维Int32数组中。这个信息每个用户是不同的,但是会经常使用到,所以存入Session。

 

 1/// <summary>
 2/// 获取用户权限
 3/// </summary>
 4/// <param name="userID">用户ID</param>
 5/// <returns>用户权限数组</returns>

 6public static Int32[] GetUserPermission(int userID)
 7{
 8    // 如果缓存中已经存在权限列表信息,则直接从缓存中读取。
 9    if (HttpContext.Current.Session["Permission"== null)
10    {
11        // 从数据库获取用户权限并将权限ID放到int数组并存入Session
12        UrlAuthorizeEntities db = new UrlAuthorizeEntities();
13        var permissions = db.PermissionList.Where(c => c.UserID == userID).Select(c=>c.PermissionID).ToArray();
14        HttpContext.Current.Session["Permission"= permissions;
15    }

16    return (Int32[])HttpContext.Current.Session["Permission"];
17}

18

 

再新建一个UrlAuthorizeAttribute类,继承自AuthorizeAttribute,这是一个Filter。我们重写它的OnAuthorization方法,以在ASP.NET页生命周期身份验证阶段执行它。

 

 1/// <summary>
 2/// 重写OnAuthorization
 3/// </summary>
 4/// <param name="filterContext"></param>

 5public override void OnAuthorization(AuthorizationContext filterContext)
 6{
 7    // 获取权限项列表
 8    List<PermissionItem> pItems = AccountHelper.GetPermissionItems();
 9
10    // 获取当前访问页面对应的权限ID。如果item为空则表示当前页面没有权限控制信息,不需要进行权限控制
11    var item = pItems.FirstOrDefault(c => c.Route == filterContext.HttpContext.Request.Path);
12
13    if (item != null)
14    {
15        if (Array.IndexOf<Int32>(AccountHelper.GetUserPermission(int.Parse(filterContext.HttpContext.Session["UserID"].ToString())), item.PermissionID) == 1)
16        {
17            // 提示权限不够,也可以跳转到其他页面
18            filterContext.HttpContext.Response.Write("没有权限访问该页面");
19            filterContext.HttpContext.Response.End();
20        }

21    }

22    else
23    {
24        // 如果权限项列表中不存在当前页面对应的权限ID则所有用户都不允许访问,直接提示无权访问。***注1***
25        filterContext.HttpContext.Response.Write("没有权限访问该页面");
26        filterContext.HttpContext.Response.End();
27    }

28}

29

 

至此,主要的工作都已经完成了的。接下来我们只需要在需要进行权限控制的Action或Controller前加上[UrlAuthorize], 这些Action或Controller中的所有Actions就会自动被UrlAuthorize这个Filter进行处理。如果某一个Action被 标上了[UrlAuthorize],而数据库中又不存在该页面对应的权限ID,那么根据示例的代码,所有用户都将无法访问这个页面,如果需要更改这个设 置,可以修改上面“注1”下面的2行代码。

示例代码下载

[SEO]关于网页*静态化*及SEO问题的一些补充

mikel阅读(909)

  前一篇讨论“静态页”的文章反响不错,不少朋友发表了自己的看法,也给老赵更多的想法。虽然也在前一篇文章后面回复了不少内容,但是就以往经验来看,总结为一篇新的文章会让我想表达的内容更为明确,对于“静态化”这一非常容易被人误解的概念来说也是非常重要的。

seo

   我们还是先来讨论一下,什么叫做“静态页”。有朋友说,放在硬盘上的htm或html文件便是一种静态页,Web服务器不需要做额外的处理,直接读取文 件内容并输出就可以了,而这样的静态文件对于SEO是有帮助的。至于理由,是搜索引擎会对html结尾的文件给更好的权值(这好像还是结论,不是理由), 而这是“常识”,“了解一点SEO的人都知道这个”,“人们普遍在使用的做法”,因此“它一定是正确的”。不过其实Google并不这么认为,百度倒没有给出专业说法。

   当然,我们已经重复强调,但还是需要不断明确的一点是,即使搜索引擎对于“静态页”有更好的倾向性,那也是因为其“URL样式”,而不是“在硬盘上放置 了一个html文件”。请求方(也就是爬虫)只是向服务器端发送一个URL,并获取服务器端给出的内容。它不会关心,也无法了解服务器端究竟是如何得到页 面内容的,对于客户端来说,世界上没有“静态”或“动态”页面之分。有些朋友可能还是会说“不会啊,html就是静态页面,像aspx之类的就是动态页 面,前者不需要在Web服务器上运算,后者需要”。

  真是这样的吗?并非如此,因为html文件也是需要Web服务器来运算的。例如,您请求一个html文件,Web服务器至少做了几件事情:

  • 如果请求包含缓存信息,那么处理缓存状态。
  • 根据URL定位到磁盘上的文件。
  • 进行用户认证和授权(如,是否匿名?)。
  • 判断是否有权限读取。
  • 读取文件。
  • 根据文件类型设置MIME的值。
  • 根据文件最后修改日期设置Last-Modified值。
  • 根据文件内容及其他状态设置其E-Tag值。
  • 如果文件内部有include标记,那么读取另一个文件填充进来。

   看看,处理一个文件需要多少“动态运算”啊,这些可都是在Web服务器(如IIS)加载一个html所做的事情。如果您想要观察这些过程,可以阅读一些 Web服务器的源代码,或者去观察一下ASP.NET中System.Web.StaticFileHandler类所做的事情,它也体现了Web服务器 处理html时的关键之处。事实上,如果您在IIS中将html配置给ASP.NET ISAPI的话,或者使用VS自带的Web服务器,最后便是由StaticFileHandler来输出硬盘上的文件的。

  所以,虽然 我们看起来Web服务器只是简单地读取了硬盘上的文件,但其实它还是不如我们想象的那么简单。不过对于客户端来说,这一切都是不可知的。例如 Squid,Nginx这样部署在前端的缓存或反向代理服务器,它们都不会关心后端Web服务器是Windows,Linux还是Unix,也不会关心是 IIS,Apache,Lightted甚至是我们自己写的高效或低劣的Web服务器。对于浏览器,爬虫,或前端负载均衡器来说,它们只知道TCP/IP 协议,它们只知道HTTP协议等东西,其他一概不知。

  不过,也有朋友坚持认为“生成静态页”来“进行页面缓存”对SEO有帮助。理由 是,“进行页面缓存”能够提高网站性能,爬虫更倾向于访问速度更快的页面。从这个角度看来,这种说法的确有一定道理。只是我还是不喜欢这样的看法,因为这 种说法没有把握事物关键。在这里,SEO的关键在于优化网站性能,而生成静态页只是一种手段之一。这并不是适用性最广的,也并非是最容易实现的。如果您直 接把“生成静态页”与“SEO”联系起来,很有可能会对他人造成误解。

  当然,如果您的思路没有问题,“静态页”三个字的指代也足够明 确,“静态页有利于SEO”这个命题毫无疑问是正确的。不过我们现在并没有讨论一个命题的逻辑是否正确,我们也不必纠缠于一个表达形式是否严谨,我们的目 的是要说明道理。也正因为如此,老赵才会一遍一遍地写这么多内容。也就是说,这几篇文章的关键在于“说清道理”,我们把握它既可。

  最后,老赵再谈一下对SEO这个工作的看法。

seo

   从老赵与各SEO人员的接触感觉来看,他们总是有各种理由来说明“问题所在”,只是如果在改进问题之后还是没有效果的话,他们又可以找出各种理由来告诉 你为什么没有效果——但是要知道SEO是一个实践性工作,它的唯一判断依据便是“效果”,而不是“理论”。SEO的理论很容易掌握,但是如果无法真切提高 一个网站在搜索引擎上的表现,这一切还是白搭。老赵认为,一个好的SEO是需要了解网页制作,或者说网站开发的基本技术的,至少要有常识,否则基本上就是 在扯蛋。老赵曾经接触过一个“专业”的SEO公司,那里的“SEO咨询师”给我留下了深刻的印象——负面印象。其“非专业性”从以下几个事件中便可见一 斑:

  1. 还是“静态页”的问题。由于把URL变为.html结尾之后并没有得到明显的效果,他询问我们的实现方式。在得知我们使 用了URL重写,而不是在硬盘上放置html文件时他“惊呼”这种欺骗搜索引擎的行为是会起到反效果的。他强烈要求我们在硬盘上放置html文件。这个要 求自然遭到了我们的拒绝,原因之一是我们是非常动态的网站,很难实现这个需求,但是更重要的是,懂得一点技术的人就知道,Web服务器的处理方式对于搜索 引擎爬虫时完全不可见的,我们是否真正放置html文件与搜索引擎没有任何关系。
  2. 内容的位置问题。在SEO界有种说法是,搜索引擎 会更倾向于把页面靠前的内容看的更重,而把页面靠后的内容权值放低。因此那位专业SEO咨询师指着我们的某张页面说,这部分内容太靠“下方”,很容易被搜 索引擎忽略。请注意,他说的是“内容在页面显示的时候出现在下方”。您觉得这种说法有道理吗?如今页面布局往往使用XHTML+CSS的方式,而搜索引擎 只会关注HTML的内容,而“位置”很大程度上是由CSS,甚至是由JS来控制的。出现在HTML内容前段的内容,在页面呈现时也可以出现在下方,这也和 搜索引擎没有任何关系。可惜这一点也解释了半天。
  3. 最后一条可以说是最可笑的。因为SEO效果不好,那位SEO咨询师觉得只能“来真 的”了,于是向我们索要网站的IIS日志。分析日志对于SEO有些帮助,因为可以看出爬虫的抓取顺序,频率,甚至结果等等,因此查看日志的做法本没有问 题。可惜问题在于,对方从MSN上给出一个邮箱,让我们把过去几个星期的日志发给他。当看到这个要求的时候,老赵几乎要破口大骂。从这点可以看出,这位 SEO咨询师缺少必要的尝试,他根本不知道一个中小型的网站,每天便要生成几百兆到几个G的日志。如此没有常识,为什么会有那么多“成功案例”?

   老赵的博客(也就是您正在看的这个)在搜索引擎上的表现也非常糟糕,即使是老赵经常写作的话题,在Google上也很难找到几篇文章,排名也不太靠前。 如果不使用site:cnblogs.com进行限制的话,几乎没有一篇文章是找到我的blog,都是各种地方的转载。为此我也比较苦恼,咨询了一些专业 搞SEO的朋友,做出一些修改之后还是没有太大改善。不过我相信那只是我没有遇上优秀的SEO人员而已,我的博客的潜力还远没有挖掘到底。

  如果您是一个专业的SEO人员,或者是专业的SEO公司,不妨给我一些建议——如果可以的话,我也不介意在这方面进行一点投资。不过,如果是一些“肮脏”的优化方式就不必了,例如去论坛上贴链接,发垃圾邮件。我也知道这些做法很有效果,但是我不想这样做。

[面向对象]九种不够面向对象的对象

mikel阅读(760)

本文发表在《程序员》2009年第四期(总第100期)

本文列出了我在平时发现和积累的在面向对象编程中一些常见的“不够面向对象”的情况。

需要指出两点:

1.我们虽然列出了这九种情况,但并不是说出现了下面的情况就一定有问题了;我们希望读者这可以将其作为一种信号——仔细考虑一下是不是有更好的设计。

2.我们这里所说的面向对象的对象特指领域对象,即对象中包含领域数据和业务逻辑。

要 确定不够面向对象的对象,首先要了解什么样的对象算是面向对象的,或者说好的面向对象的对象。关于面向对象设计的原则从不同的角度有很多种说法,我们这里 采用一种比较简单的说法,即高内聚低耦合。所谓高内聚是指对象内的数据和方法是紧密相关的;所谓低耦合是指对象之间的依赖应当比较小,一个对象发生改变时 不应当对不相关的对象产生影响。

一. 低内聚对象

我们把低内聚对象分为两种:一种是应该属于该对象的行为和数据分散到了其他对象中;另一种是该对象内部的行为和数据关系不够紧密。下面的1、2是属于前一种情况,3、4、5则是属于后一种情况。

1.贫血对象(Anemic Object)

瞧,那条贫血的狗!
故事的发生是这样的…
你养了一条宠物狗,在学习了面向对象编程之后,你打算为这条狗设计一个面向对象的系统。于是,根据你在C语言编程时的开发经验,结合你对“封装”二字的理解,你设计了这样一条狗:)这条狗由四部分组成:头、身子、腿和尾巴。

clip_image002

图 1

隔壁住着一位面向对象大师——法号鉴摩,你拿着设计图给他看。鉴摩大师只扫了一眼便说:
没有行为的对象不是好对象。

你似懂非懂地点了点头,正要往下说,大师挥了挥手说:“你明天再来罢。”

如 果一个对象只有数据没有行为,它就是一个贫血对象,它只能被别人操作,或者作为某个操作的结果。对于简单的getter和setter,我们一般不将其归 为领域行为。所以,上面这个对象就是一个贫血对象。这条狗还不会叫、不会跑,甚至还不会摇尾巴讨好你,真不知道你养这样一条狗干啥。

处理贫血对象时可以考虑把操作对象数据的行为移动到这个对象里面。对数据的封装只是面向对象中“封装”这个概念的一部分,我们的对象中除了封装数据还应当封装行为。

对于跟物理世界一一对应的对象,一般来说,我们不容易犯这样的错误。我们不妨来看一个实际工作中遇到的例子。在某个商店收银系统中,有一个对象叫做Product,它被设计成这样:

clip_image004

图 2

这个Product就是一个贫血类。单纯看这个类,是没有什么问题的。我们需要结合其他的类来观察。由于不同类型的产品打印方式不同,计税规则也不同,所以我们还有一个处理Product的类: 

clip_image006

图 3

我们可以明显的看出在这两个类的方法中存在非常相似的代码结构。如果Product的类型出现扩展,我们在这两个类(Product、 ProductHandler)里面都需要做修改。这不符合面向对象编程中OCP原则。对于贫血对象的改进应当考虑将相关的行为移动到对象里面。 

clip_image008

图 4

如果我们发现相关行为移动到Product中去后ProductHandler所做的事情仅仅是将调用转发给Product,可以考虑将这个类消除。这里我们没有将Product形成继承结构,有兴趣的同学可以参考《重构》一书中的“以多态取代条件式”。

引申阅读:

1.《重构》一书种关于“以多态取代条件式”的内容。

2.管理者对象(Manager Object)

狗摇尾巴,还是摇狗尾巴,这是个问题!

第二天,你拿着另一个对象的类图去找鉴摩大师。你对鉴摩大师说:“我想大师昨天的意思是说我设计的Dog对象没有行为吧,其实所有的行为我都放到这个DogController对象中了。”

clip_image010

图 5

大师看了一下你的图,说道:“到底是狗摇尾巴,还是你在摇狗尾巴?”
你不解道:“这样有什么不同吗?”
鉴摩大师闭着眼睛说道:
不要问我,告诉我。
你更加迷惑了。不过你知道“知之为知之,不知Google之”的名言,所以你用大师的话为关键字Google了一下,还真有不少内容。
我 们经常会看到一些类命名为:XxxxManager、XxxxHandler。这样类表面上是面向对象的,但其实质往往是面向过程的,只不过在外面包了一 个Class而已。管理者对象往往是跟贫血对象成对出现的,业务数据保存在贫血对象中,而业务逻辑行为(或者从数据的角度来说也可以称为“对数据的操作 ”)则在管理者对象中。
管理者对象的问题是其中的各个方法之间的关系非常不明显,它们往往只是共享一个被操作的数据对象。去掉其中的几个方法,这个对象似乎还是一个完整的对象。上例中ProductHandler就是一个管理者对象的例子。

对于管理者对象,最基本的解决方法就是职责分组。首先创建或者从系统中找出相关的领域对象,尽量地将职责划分到多个领域对象中去。当管理者对象和贫血对象成对出现时,往往部分跟业务紧密相关的贫血对象既是领域对象。分层、数据字典都是常用的提取领域对象的方法。

3.储柜对象(Cabinet Object)

狗尾巴不见了!

第三天,你的朋友送了一条狗给你,并告诉你是在路边捡到的。所以,你需要在你的系统中再添加一只小狗啦。根据你丰富的内存管理方面的经验,你认为在内存中保留两个实例,实在是浪费,所以你扩展了一下API。你把新的设计方案交给鉴摩大师去看。

clip_image012

图 6

鉴摩大师冷漠地看了你一眼,仿佛看到一个陌生人似的,大师慢悠悠地说道:
今天的你不是昨天的你。
你一脸茫然地回到自己家里,突然发现狗尾巴不见了。谁调用了setTail(NULL)!

所谓储柜对象,是指它所有的数据都是可以通过setter动态设置的。也就是说getter返回什么或者对象的行为如何表现,完全取决于当时的设置了什么。这个对象中的数据,看起来就像临时分配的一块可读写的内存。

储 柜对象的问题在于,我们编写和阅读代码的时候很难把握这种对象,因为其状态随时可能会被修改,而修改其状态的行为又分散在其他的地方。解决这个问题,可以 先把储柜对象处理为Immutable Value,即在构造函数中传入必要的参数,只为那些可以动态修改的状态保留setter方法。如果有必要,还可以通过“以多态取代条件式”重构形成一个 继承结构。

4.多管闲事的对象(Meddling Object)

你们家的狗会拿耗子吗?
你的朋友真 好,第四天又送了一只猫给你。你已经开始庆幸自己学习了面向对象,这门支持“派生”的技术。你本来想直接从Dog派生一个Cat出来,觉得似乎有点问题。 算了,你决定来个重新设计吧。为了用到面向对象里面最好用的技术——继承,你决定对狗和猫进行抽象,产生一个宠物(Pet)对象。好的,狗和猫有什么共同 点呢?很快,结果出来了:

clip_image014

图 7

你甚至记得把Pet中makeSound和catchRat设计为抽象函数,让Dog和Cat分别实现。你高兴地拿给鉴摩大师去看。大师瞅了你一眼,问到:“你们家的狗会拿耗子?”
你狡黠一笑:“大师您看,我的catchRat是抽象函数,在Dog中实现地行为是‘do nothing’。”
“如果你们家有一百条狗,一百只猫呢?”大师说这句话的时候甚至连看都没看你一眼。过了一会儿,大师继续说道:
把变化的和不变的分离开。
你悻悻地回到家里,陷入了沉思…
对 于一个对象而言,多管的闲事不属于自己的业务逻辑(虽然很可能有某种联系),我们应当把相关的代码完全隔离出去或者将相关职责委托给新的对象实现。隔离和 委托的区别在于原对象是否持有新对象的引用。一般来说,委托的方式使用的更多一些,而且实现上也比较直观。对于上例而言,我们可以做如下的改进:

clip_image016

图 8

不恰当的抽象只是造成“多管闲事的对象”的原因之一。更常见的情况是,我们懒得为一个小功能创建一个新的类。比如下图就是一个实际工作中遇到的例子。

clip_image018

图 9

在计税的时候,我们需要做一些四舍五入的工作,这些职责本应该委托给一个工具类来完成。
引申阅读:
1.爱管闲事的对象违反了单一职责原则(SRP),容易导致设计不稳定。请参考有关SRP的文章。推荐《敏捷软件开发:原则、模式与实现》第8章。
2.《设计模式:可复用面向对象软件的基础》中关于在实现Composite模式时,安全性和透明性之间的权衡。

5.工具类(Utility Class)

你的设计越来越完善了!
第五天,你开始设计一些工具方法,给狗狗洗澡、喂食,可是这些方法放到哪儿呢?既然不能违反SRP原则,你决定每个工具方法设计一个类,但是看上去这些类也太简单了。  

clip_image020

图 10

你把自己的想法和顾虑告诉鉴摩大师,大师摇了摇头,随后说道:
物以类聚。易懂易维护才是我们的目标。

说 工具类不够OO听上去有点奇怪,因为它根本不需要实例化,所以也不会形成真的对象。工具类的典型特征是里面的函数都是静态的。这些静态的函数之间往往没有 必然的联系,甚至都不会共享数据,所以它们本质上是非内聚的。这里,并不是说不应当有工具类,而是工具类的角色很多时候都是提供一种转换或者值操作,不包 含领域逻辑,因而不属于领域对象。把这些方法放到一个对象里面,就像给它们归归类而已。所以,如果一个类是工具类,就让它扮演好这个光荣的角色吧,别往里 面放业务逻辑。如果有些转换明显跟业务逻辑靠得比较紧,而又不适合放到领域对象里面,可以将其单独做一个工具类,将其跟通用的、业务无关的工具类分开。

简单工厂类是工具类的一种,所谓简单工厂是相对于抽象工厂和工厂方法来说的,它只是根据输入值返回一个领域对象。

二.高耦合

高耦合一般表现为对其他类型的强烈依赖,一个对象发生变化会对其他对象产生剧烈的影响。我们的原则是尽量依赖于稳定的类型(或接口)。

6.原生类型依赖对象(Primitive Obsession Object)

这只狗的生日是01/02/03。
第六天,你决定在Pet对象中加入狗狗和猫咪的生日。这项工作对于你来说已经算不上什么难事了。

clip_image022

图 11

你把程序交给大师去看,大师输入了一串字符串,运行的结果是:这只狗的生日是01/02/03。大师问你:“这是什么意思?01年2月3日还是03年1月2日?”
你满脸冒汗,因为你已经不记得自己怎么定义的了。大师微笑着说:
不要依赖于你自己都会忘记的事情。封装之。
你回到家里,百思不得其解。“难道我值得为一个生日设计一个类吗?”

有 的对象强烈依赖于语言的原生类型,比如字符串、整型数字等。正常情况下,依赖于原生类型是没有危险的,因为这些类型相当稳定,向着稳定依赖正是我们的原 则。但是,如果我们同时依赖于这些原生类型的表达方式,比如字符格式、用整型表达的类型,会使得我们的系统设计变得不稳定。

我们再来看一个实际工作中的例子吧。

我们要分析两个城市之间的路径,有的同学将从城市A经城市B到达城市C的路径用“ABC”来表示,有的同学则用“A-B-C”来表示。如果对象依赖于这样的字符串,编程中就很容易出错,而且一旦表达格式发生了变化,程序还需要作出相应的修改。

一般来说,在系统中总是有一些对象要依赖于原生类型,但是我们应当尽量早地使用领域对象对原生类型做封装。比如,一开始的设计是这样的:

clip_image024

图 12

我们可以对route进行封装,使其不再依赖于字符串的格式。

clip_image026

图 13

这时候,要添加城市A只要调用Route:addCity("A")就可以了。

7.链式依赖对象(Message Chain Object)

一只狗拴一条链子就够了!
第七天,你的朋友跑过来说,他找到了那只路边捡到的小狗的主人,并告诉了你他的电话。你决定把这个电话记录在你的系统中。

clip_image028

图 14

你把设计交给大师去看。大师看了看类图就去翻你的代码,然后皱了皱眉头,用手指着一行代码“dog.getOwner().getAddresss();”说道:
决定一个对象好坏的是它的使用者。
你看着那行代码,若有所思的点点头。

且 不说,这个代码违反了“Tell,Don't Ask”原则,就这种链式导航结构就会使得客户端与链条上的所有对象直接耦合。一旦对象之间的关系发生任何变化,都会引起客户端的变化,这违反了迪米特法 则,又称最少知识原则。要解决这个问题可以在链条中找一个合适的对象添加一个函数。比如,上例中我们可以为Dog添加一个 getOwnerAddress()函数。这样在客户端要取得主人的地址就只要依赖于Dog对象就可以了:dog.getOwnerAddress()。

我们要特别强调,上述解决方案只是最简单的方案之一,而且不一定是最佳方案。如果链式调用出现的次数不多甚至可以不做修改。

引申阅读:

1.《重构》中关于Message Chains的内容。

2.《程序员修炼之道》中关于迪米特法则的内容。

8.假对象(Dummy Object)

需要为邻居家的宠物单独设计一个类吗?
第 八天,你的邻居看到了你设计的系统,非常感兴趣,希望你能把他们家的宠物也纳入进来。你非常高兴地答应了,因为邻居家的女主人非常热情。因为你的系统里面 已经有了Owner的概念,你决定为邻居家的宠物派生一个专门的类。而且你把这个决定告诉了邻居mm,让她觉得你专门为她做了一件天大的事情。

clip_image030

图 15

你把新的设计交给大师去看,大师瞅了一眼,说:
多一个类就多一份牵挂。
你的脸一红,因为你不知道大师是在说设计还是说你。

系 统中每增加一个类,系统的复杂性就会提高一点。每个类都是有代价的。尽管小对象往往是我们追求的目标,但是如果对象小到不仅没有专属自己的数据,也没有专 属自己的行为,这样的对象还是不要的好。假对象经常出现在类的派生体系中。在倒数第二层的抽象类中已经做足了数据和方法,假对象往往只要在构造函数中填空 就行了。图15正是这样的情况。

解决这种问题的一个方法是引入合适的“工厂”模式。比如,对于这个例子,我们可以将其修改为:

clip_image032

图 16

引申阅读:
1.《重构》一书中关于折叠继承体系、将类内联化的内容。

9.积木对象(Bricks Object)

创建一只狗到底要分多少步?
第九天,你对修改后的设计已经充满了信心。你把整个设计拿给鉴摩大师去看。鉴摩大师问到:“你怎么创建一只宠物?”
你说:“我先创建PetHead、PetBody、PetLegs和PetTail,然后把它们跟相应的生日和主人信息一起传入PetFactory的工厂方法中,就可以返回一只完整的宠物了。”
大师问:“你怎么保证别人创建宠物的时候记得这么复杂的步骤呢?”
你简直怀疑大师在故意为难你了:“难道我的PetFactory的参数列表不够清晰吗?你是说让我增加点注释吗?”
大师摇了摇头,轻轻地吐出两个字:
封装。
封装?你简直不相信自己的耳朵,难道我做了九天了,又回到了面向对象的原点?
当对象的创建可以分为多个步骤时,为了防止在步骤上出错,我们经常要对这些步骤进行封装。否则对象的创建将依赖于(耦合于)代码中未指明的步骤,这可不是闹着玩的。同样道理,如果某件事情要求对几个函数按照某个顺序进行调用,也需要对其进行封装。
封 装对象创建的步骤经常采用Builder模式,当然我们也可以采用比较简单的方案,即尽量在被创建对象的内部创建自己的各个组成部分。封装对几个函数的顺 序调用,为其另外提供一个函数在该函数中按照要求的顺序完成调用。图17是采用内部创建各组成部分的方式设计的对象继承结构。

clip_image034

图 17

引申阅读:
1.《重构与模式》中关于组合方法、链构造函数、用Creation Method替换构造函数、用Builder封装Composite的内容。
2.《设计模式:可复用软件对象的基础》种关于创建型模式的内容。
第十天,大师问你:“什么样的对象算是好对象呢?”
你说:
好的对象添一分则嫌多,减一分则嫌少。
大师笑而不语。翌日,你再去找大师,大师已经离去了。

结语

实 际上,对于如何认识和理解面向对象,业界也有很多争论,其中有代表性的是斯堪的纳维亚学派(Scandinavian school)和美国学派(American School)。前者强调对真实世界中的“对象”建模——即类是由一组数据和支持这些数据的方法组成;后者强调行为封装——即类是由一组方法和支持这些方 法的数据组成。前者的典型代表语言是Simula,后者的典型代表语言则是Smalltalk(我并不想较真,但是较真的读者可能会看到一些说法认为 Simula是Smalltalk之母的说法,恕我不擅考究)。以GoF、Martin Fowler、Robert C. Martin等人为代表的美国学派在这场争论中占有优势。实际上,本文从某种程度上也是引导读者从斯堪的纳维亚学派向美国学派靠拢。
面向对象技术 出现的目的是让编写代码更容易,然而有意思的是,对于初学者来说面向对象语言要比面向过程语言更难理解和接受。实际上,要做出好的面向对象设计需要长时间 的经验积累。我在上面列出了一些相关的书籍,除了阅读之外更重要的是要在实践中摸索和体会。掌握了基本地面向对象设计的技能之后,可以继续学习有关设计模 式、重构、测试驱动开发等内容,这些对于深入理解面向对象概念有很大的帮助。
在面向对象编程中,考察对象设计的好坏关键是看该对象的客户端是否能 够方便地使用它;它所应用的环境中是否体现出自己的价值,特别是在环境和需求变化时是否能够比较容易地适应。这句话反过来也是成立的,即我们在设计对象的 时候也应当从环境和客户端的角度去思考。这种思路往往能给我们带来额外的好处,比如容易测试、容易面向接口编程、容易实现依赖倒置。这是一个更加深入的话 题,希望有机会跟大家分享和交流。

后记

当我开始写这篇文章的时候我就意识到这不是一个容易成文的话题,因为不够 面向对象的情况实在是太多了,不可能用九种来概括。从某种意义上讲,Martin Fowler在《重构》一书中所列出的“坏味道”都属于不够面向对象的情况,或者至少说是“不够好的面向对象”。所以本文列出的九种情况不追求全面,更不 追求正交,而是追求实用。我的目的是为刚刚接触面向对象编程的程序员——特别是从非面向对象编程转到面向对象编程的同学——提供一个容易比照的检查列表。
感谢我的同事和朋友们在本文成文过程中给予的帮助。

[性能]Five Minutes程延辉 介绍开心农场架构

mikel阅读(834)

Five Minutes 公司程延辉(小名康天) 介绍开心农场架构,social game的技术挑战,支持千万级DAU的social game技术架构。这是一个对于开发者来说,非常精彩,非常有实用性指导的一次演讲,详细介绍了很多技术内幕。
>>猛击这里下载演讲ppt<<

Five Minutes 公司的著名social game 开心农场,目前非常受用户欢迎,包括国外的Facebook,国内的开心网都是如此,是全球最大的social game,台下热烈掌声。呵呵。开心农场这个游戏从介绍看,相当成功,最早是08年9月在xiaonei上线,而后在51等平台推广,包括 Facebook。现在已经有1570万游戏用户了,其中包括50万的Facebook用户。
开心农场架构主要难点:1。如何存储大规模的用户数据千万级2。如果应对大量访问每天数亿请求量3。如果应对数据的频繁修改,每秒数万次数据修改。
解决的方式
优化:
1。负载均衡,web服务器平行扩展。
2。服务器性能优化。
3。异步处理,缓存数据接口,Linux内核参数优化,挖掘PHP的效率,用fastcgi模式运行php,用EAccelerator加速。固定不变数据做成php配置文件,用C开发PHP扩展等。
数据库性能优化:
1。数据库分库分表,所有数据全部设计成 key-》value形式,不用join。
2。使用INNODB,经常操作的数据表中所有字段尽量设计成数值型,用update替代Insert和Delete操作
异步处理:整个系统最关键的部分,
原则:把客户端暂时不需要的数据进行异步处理。
实例:讲非核心数据先写入memcached,异步更新到数据库,合并数据库更新操作,Feed和Notification的异步发送。
利用客户端资源:Flash屏蔽重复操作和不必要请求,Flash进行一些计算减轻服务器的复旦,例如好友排序等。Flash缓存一些数据。
social game = social + game。实时互动(大负载)和非实时互动(大负载)。
服务器角色:场景服务器,逻辑服务器,admin服务器,gateway,架构逻辑还是挺复杂的,每天处理亿级请求的架构,完全和百万级不一样!完全能够通过平行扩展的方式应对,gateway和场景服务器都完全可以增加。
Blue Whale是他们们正在开发的解决长连接的social game架构。

[C#]23个.NET开源项目

mikel阅读(976)

Eric Nelson是微软技术的传道者,也是MSDN UK Flash的技术编辑,他编写了一个列表,列出23个UK开发人员推荐的.NET开源项目。微软的一些开源项目如ASP.NET MVC、DLR、IronRuby、IronPython、MEF等则未列入其中。

Eric尝试只包含一个测试框架和一个mock框架,即使有很多其它的项目同样入围。他列出了以下项目:

  1. [TEST] xUnit.net – 用于TDD的最好的测试框架之一。
  2. [TEST] RhinoMocks mocking framework – 通过创建mock使测试更简单。
  3. [TEST] White for automation of Windows applications – 用代码驱动Windows程序来测试。
  4. [TEST] Gallio Automation Platform – 可以运行很多测试框架,如MSTest、xUnit、NUnit以及MbUnit。
  5. [DATA] Fluent NHibernate – Fluent NHibernate让你可以用C#代码来设置映射关系。
  6. [OOP] StructureMap Dependency Injection/Inversion of Control – 解耦类和依赖。
  7. [OOP] Managed Extensibility Framework – 从静态编译程序转换到动态语言程序
  8. [APPFX] s#arp architecture for web applications – 用ASP.NET MVC和NHibernate快速开发web应用程序。
  9. [APPFX] OpenRasta REST based framework for building web applications – 让你的程序拥有一个REST API接口。
  10. [APPFX] CSLA.NET Application Framework – .NET开发综合框架
  11. [APPFX] Spring.NET Application Framework – Web开发综合框架
  12. [RUNTIME] Mono enables .NET on Linux and Mac – 在Linux、BSD和OS X上使用.NET.
  13. [UTIL] Sandcastle Help File Builder – 创建MSDN样式的文档。
  14. [HELPER] EasyHook for Windows API Hooking – 用托管代码扩展非托管代码。
  15. [HELPER] Json.NET for working with JSON formatted data – 用一条语句序列化.NET对象。
  16. [HELPER] Excel Data Reader for Excel 97 to 2007 – 将Excel文件读取到Dataset中
  17. [HELPER] #SNMP Library – 对SNMP的包装。
  18. [HELPER] DotNetZip Library – ZIP库和示例。
  19. [HELPER] Visio Automation Library – 用C#、VB和其它语言驱动Viso
  20. [HELPER] PHPExcel is not just about Excel! – 读写Execel 2007、PDF、HTML等文档的PHP类
  21. [HELPER] Argotic Syndication Framework for RSS, Atom, OPML and more – 读写聚合内容的库
  22. [HELPER] NLog logging library -让你的程序易于调试
  23. A great directory of C# Open Source software – 一个非常好的库、框架和工具列表

还有一些提交的项目没有进入列表:

一些使用MS-PL许可证的微软项目:

MS-PL是OSI认可的许可证,GNU也认可它为免费软件许可证,它允许任何人查看源代码、修改源代码并发布修改后的源代码。而且此许可证并不限 制代码只能运行在Windows上,这样就可以将代码移植到其它操作系统,例如Mono(Linux上的.NET)和Monolight(Linux上的 Silverlight)。MonoDevelop有一个插件,可以用来在Linux和Mac OS X上开发ASP.NET MVC程序。

查看英文原文:23 .NET Open Source Projects

[CSS]15款非常有用的前端开发CSS网格(grid system)生成器

mikel阅读(814)

前端开发-网格生成器
现在的互联网上已经有很多能帮助设计师们的各种在线生成器,比如:图标(icon)生成器、背景生成器、按钮生成器和标志生成器等。Balkhis曾经为我们写过一片很不错的关于各种实用的在线生成器的文章。

如果没有这些在线的生成器,设计师们可能就要浪费很多精力在重复性的工作中了。今天彬Go将向大家分享一系列(15款)CSS网格布局生成器。如果大家不了解CSS网格布局的话,可以先看看彬Go之前的文章《960网格系统》、《使用Photoshop+960 Grid System模板进行网页设计》、《960 Grid System 基本原理及使用方法

1.网格布局生成器 By Pagecolumn

CSS-网格

2.网格生成器 By DesignByGrid

div-css-网格生成器

3.Blueprint CSS网格生成器

blueprint-grid-css-generator

4.网格生成器 by netProtozo

CSS-网格-生成器

5.Grid Designer (featured in Creative Review magazine)

grid-designer-by-mindplay1

6.网格系统生成器

前端开发-网格系统

7.YUI CSS 网格生成器

yui-css-框架-网格

8.Variable Grid System

网格系统

9.YAML 生成器

yaml-网格系统-生成器

10.布局生成器 by Pagecolumn

CSS-div-布局

11.Fisheye

网格系统

12.CSS 布局生成器 by CSSCreator

css-布局-网格-生成

13.Firdamatic

css网格系统

14.支持边框的CSS1~3列页面生成器

CSS-框架

15.CSS 布局生成器 by CSSPortal

CSS-布局

英文原文:15 Extremely Useful CSS Grid Layout Generator For Web Designers
翻译原文:15款非常有用的前端开发CSS网格(grid system)生成器

转载声明:
原载:彬Go——集前端开发/网页设计/网站可用性/用户体验于一体的趣味互联网生活
本文链接:http://blog.bingo929.com/15-extremely-useful-css-grid-layout-generator.html
如需转载必须以链接形式注明原载或原文地址,谢谢合作