2010年9月29日

IE9对CSS3的支持情况概述

IE9对CSS3的支持情况概述

IE9 Beta版已于9月17日在中国发布了。IE9 Beta版的性能有了大幅提升,包括九大亮点。同时它对CSS3的支持范围更广了,但仍有一些CSS3属性尚不支持。让我们一块阅读张鑫旭翻译的的博文《IE9对CSS3的支持情况概述》来了解一下IE9 Beta版对CSS33的支持情况。全文如下:

IE9测试版在9月17日于中国发布,如今在中国,IE已经四世同堂,这是多么温馨美满的画面啊,让人不由得“喜极而泣”啊!关于IE9的野史外传这里不做讨论,本文内容正如题目所示,主要概述下目前IE9版本对CSS3的支持情况。随着时间的推移,IE9必定会做一定的改进与修复等,所以,可能仅仅几个月后,现在还不支持的CSS3属性已经支持了,所以,下文所有的表格和数据仅作参考,如果您想要比较实时权威点的数据,可以点击这里查看:

IE9对CSS3属性的支持情况

对一些生僻属性的支持情况

下面这些属性呢,平时比较腼腆害羞,我们用的不是很多,但是,IE9对其是支持的:

@namespace, text-justify, text-align-last, text-overflow, word-break.

还有很多其他鲜为人知的CSS属性,由于现在版本的IE不支持,所以,就没有罗列出来。

IE9对CSS3选择器支持情况

见下表:

IE9支持的伪类&伪元素

IE9不支持的伪类&伪元素

我的感慨

IE9不支持border-image属性,是在遗憾,这是个非常强大的CSS属性,潜力无限。不过,本身对IE就没报多大期待的我看到其对rgba color以及box-shadow支持有佳,也比较满足了。真如开头所说的,一些数据仅作参考,可能回老家娶个媳妇回来,一些数据就作古了。

原文链接:CSS3 Support in Internet Explorer 9

译文链接:http://www.impressivewebs.com/css3-support-ie9/



2010年9月28日

设计模式-原型模式(Prototype)

设计模式-原型模式(Prototype)

简述

  原型模式最后一个要介绍的创建型模式。它在创建大量拥有相同状态的对象时使用起来非常方便。

功能

  用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象(Baidu 到的相当专业)。

何处使用

  我们把类当作对象的模板,给类的属性赋予值时就产生了一个具体的对象,如果需要创建大量状态相同的对象时,传统的方式需要一个一个对象重新赋值,但是如果我们采取原型模式的话,这样的工作将变得非常的简单。它提供一个克隆的方法,可以方便的让用户对每个对象进行复制并赋予另外对象相同的状态,其实这一方法在 .Net 中就已经提供了,所以我们重写起来也相当方便。举例方面我想就不用了,克隆对象应该很好理解。

设计

  我们直接完成设计图纸吧,抽象的原型类拥有一个可以克隆当前对象的公共方法,其衍生出来的子类重写了它的克隆方法,使其能够真正实现克隆当前对象的方法。Prototype

实现

  .Net 框架中,提供了 MemberwiseClone()  一个方法可以让我们对当前对象进行复制,此方法的访问级别为受保护的,所以需要重新定义一个公共 Clone() 方法使其外部可以访问,我们的代码可以这样实现(非常感谢网上提供代码的人):

01using System;
02 
03public class Test
04{
05    static void Main()
06    {
07        ConcretePrototype1 p1 = new ConcretePrototype1("I");
08        ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
09        Console.WriteLine ("Cloned: {0}", c1.Id);
10         
11        ConcretePrototype2 p2 = new ConcretePrototype2("II");
12        ConcretePrototype2 c2 = (ConcretePrototype2)p2.Clone();
13        Console.WriteLine ("Cloned: {0}", c2.Id);
14    }
15}
16 
17public abstract class Prototype
18{
19    private string id;
20    public string Id
21    {
22        get{ return id; }
23    }
24 
25    public Prototype(string id)
26    {
27        this.id = id;
28    }
29 
30    public abstract Prototype Clone();
31}
32 
33public class ConcretePrototype1 : Prototype
34{
35    public ConcretePrototype1(string id) : base(id) { }
36    public override Prototype Clone()
37    {
38        return (Prototype)this.MemberwiseClone();
39    }
40}
41 
42public class ConcretePrototype2 : Prototype
43{
44    public ConcretePrototype2(string id) : base(id) { }
45    public override Prototype Clone()
46    {
47        return (Prototype)this.MemberwiseClone();
48    }
49}

  看来在 .Net 框架下我们很容易就能够实现这一模式。



设计模式-工厂方法(Factory Method)

设计模式-工厂方法(Factory Method)

简述

  工厂方法抽象工厂两个设计模式很相似,很多人不了解两者的区别(包括我)。等把这五个创建型模式都介绍完后,我们再做一个总结。

功能

  定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个实例化延迟到其子类。这个定义是一本《设计模式手册》的书中提到的,看起来很官方。

何处使用

  当我们并不知道当前创建的对象到底属于哪一个类,或者希望一个类由它的子类来指定它所创建的对象的时候,可以使用工厂方法。嗯,这样的描述其实由来于《Head First Design Pattern》这本书,这本书非常明确的描述了抽象工厂和工厂方法的区别,希望有兴趣的朋友可以去看看。

  或许这样说还是很多人不太理解,可以这么说工厂方法权力比较大,它像发号命令的老板,经常会命令自己的子类做一些事情,他并不在乎他们如何去做这些事情,只要能够满足他当前的需求就可以。通常我们买手机时为了避免充电的麻烦,会购买一个或两个备用电池,很多人不会购买原厂出产的因为价格会比较高,当然符合同样机型的电池可以出自不同的厂家,他们会在电池的制作工艺或者使用材料上存在一些差异,但是不用担心它们同样符合这台手机的正常使用。也就是说工厂方法用来创建某一对象,但它不需要知道或者根本就不知道自己将要创建出什么样的对象,负责创建这一对象的是它的子类(看来它像老板一样指使员工去做事一样)。

设计

  我们需要一个抽象的产品类,如此一来就可以由它衍生出不同的产品。还需要一个抽象的创建者类它可以通过工厂方法来创建产品,同样由它也要衍生出来不同的具体创建者,通过重写父类的工厂方法来创建各自的具体产品,从下面的 UML 图可以看出来,具体的创建者类依赖于各自的产品类。这样一来我们对各个类之间的关系有了一些了解,通过它们之间的关系就可以绘制出工厂方法的类图

factoryMethod

实现

  当知道要做什么并且如何去做才能达成目标时,我认为实现起来就是时间的问题,下面是 Baidu 到的一段代码,稍作修改:

01using System;
02 
03public class Test
04{
05    static void Main()
06    {
07        Console.WriteLine("Hello");
08 
09        Creator[] creators = new Creator[2];
10        creators[0] = new ConcreteCreatorA();
11        creators[1] = new ConcreteCreatorB();
12 
13        foreach(Creator creator in creators)
14        {
15            Product product = creator.FactoryMethod();
16            Console.WriteLine("Created {0}", product.GetType().Name);
17        }
18    }
19}
20 
21public abstract class Product { }
22public class ConcreteProductA : Product { }
23public class ConcreteProductB : Product { }
24public abstract class Creator
25{
26    public abstract Product FactoryMethod();
27}
28public class ConcreteCreatorA : Creator
29{
30    public override Product FactoryMethod()
31    {
32        return new ConcreteProductA();
33    }
34}
35public class ConcreteCreatorB : Creator
36{
37    public override Product FactoryMethod()
38    {
39        return new ConcreteProductB();
40    }
41}

  由此看来要想实现我们的工厂方法我们必须要做到:

  1. 可以衍生并创造各自产品的创建者类
  2. 可以衍生不同产品的产品类


设计模式-创造者模式


设计模式-创造者模式(Builder)




简述


  创造者模式在软件开发中也是一个很常用的设计模式,当遇到复杂的对象需要创建时它给我们带来极大的方便。创造者模式属于解耦对象创建的创建型模式


功能


  将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。这句话是 Baidu 到了,感觉它能非常准确的形容创造者模式的功能。


何处使用


  当我们需要创建一个对象时,它是由不同部件组合而成,并且通过不同的组合可以产生符合不同场合的对象时,此时就可以使用创造者模式。在适合的场合使用它对代码的扩展性维护性带来很大好处。


  我们去吃快餐时经常会有服务员介绍套餐,这是一个非常好的例子,我在很多介绍创造者模式的文章中看到这样的例子。餐厅的食物有很多,经过不同的组合后可以符合不同客户的口味,我常常去永和大王点卤肉饭套餐,套餐内容是卤肉饭+鸳鸯豆浆,或许这个例子不太能看出其中的奥秘,我们将这个套餐丰富一下,卤肉饭+鸳鸯豆浆+棒棒鸡(如果真这样就好了!)我们暂且叫它套餐 A,这是我喜欢的组合,当然我的朋友可能口味清淡些,他点的是鸡排饭+果汁+蔬菜沙拉我们叫它套餐 B 吧,我们在同样的餐厅里面都吃到了自己喜欢的东西。


  如此看来,他们只是做了组合的工作,我选择 A 套餐,他们按照 A 套餐的菜单来配菜,然而这些东西并不是由客人随意说出来的,都是他们餐厅存在的东西,所以可以做到符合各位客人的口味并且能够快速响应客人需求的服务。当有新的搭配时只需要新安排 E 套餐的菜单就可以。我们完全可以把创建者模式看作是一个按照套餐菜单配菜的配菜师傅,然而这些菜是如何制作的他不用担心,厨师们在厨房会给他提供。看来这样的工作模式也是非常符合现在的市场需求,快捷而又人性化的服务。


设计


  通过上面的例子,我们可以规划下餐厅的工作模式,餐厅需要一个厨房里面有很多厨师可以做出所有提供的,然后是必不可少的是配菜师傅,他的任务就是按照客人给的菜单配成不同的套餐,看来他在厨师和客人之间起着很重要的作用。接下来看 UML 图,我们用产品和创造者来为例子:


Builder


实现


  知道餐厅到底如何规划了,当然最重要的是 Do it,接下来可以把我们的需求和设计真正实现,多么令人兴奋的时刻:



01using System;
02using System.Collections;
03 
04public class BuilderPattern
05{
06    static void Main()
07    {
08        Console.Write("Hello");
09        Client client = new Client();
10        Builder b1 = new ConcreteBuilder1();
11        Builder b2 = new ConcreteBuilder2();
12 
13        client.Construct(b1);
14        Product p1 = b1.GetResult();
15        p1.Show();
16        client.Construct(b2);
17        Product p2 = b2.GetResult();
18        p2.Show();
19    }
20}
21 
22public class Client
23{
24    public void Construct(Builder builder)
25    {
26        builder.BuildPartA();
27        builder.BuildPartB();
28    }
29}
30 
31public abstract class Builder
32{
33    public abstract void BuildPartA();
34    public abstract void BuildPartB();
35    public abstract Product GetResult();
36}
37 
38public class ConcreteBuilder1 : Builder
39{
40    private Product product = new Product();
41    public override void BuildPartA()
42    {
43        product.Add("PartA");
44    }
45    public override void BuildPartB()
46    {
47        product.Add("PartB");
48    }
49    public override Product GetResult()
50    {
51        return product;
52    }
53}
54 
55public class ConcreteBuilder2 : Builder
56{
57    private Product product = new Product();
58    public override void BuildPartA()
59    {
60        product.Add("PartX");
61    }
62    public override void BuildPartB()
63    {
64        product.Add("PartY");
65    }
66    public override Product GetResult()
67    {
68        return product;
69    }
70}
71 
72public class Product
73{
74    ArrayList parts = new ArrayList();
75    public void Add(string part)
76    {
77        parts.Add(part);
78    }
79    public void Show()
80    {
81        Console.WriteLine("\nProduct Parts -------");
82        foreach (string part in parts)
83        Console.WriteLine(part);
84    }
85}


  当然这段代码只是起到示意的作用,从中可以看出创造者模式需要做到以下两点:


  1. 符合客户需要的产品,此类产品的创建过程应该是差不多的;
  2. 一个或者多个搭配产品的配餐员


抽象工厂是创建型模式


设计模式-抽象工厂(Abstract Factory)




简述


  抽象工厂是创建型模式,在软件设计过程当中,它使用得非常普遍并且在解耦对象的创建时是最佳的选择,但是初学者(像我)会感觉到为什么把一段创建对象的代码搞得那么复杂繁琐,但是抽象工厂这样的开销在大型的系统项目中是相当有用的,对代码维护和管理上将带来前所未有的方便。


功能


  提供创建对象的接口。


何处使用


  当然在哪里使用它这个才是我们学习的目的。可以打一个比方,当我们需要玩PC游戏时,必须要相关装备比如说一台性能优秀的电脑、准确灵敏的鼠标
和键盘、拥有HiFi效果的音箱、或许还需要一个舒适的座椅和电脑桌子,这一系列的东西都需要买来并且组装起来,这样就成了我们梦寐以求的游戏室。


  Ok需要的器材清单已经列好了,我们需要一个一个购买然后组装。当然不同的玩家每个人的要求不一样,骨灰级玩家可能需要顶级配置的电脑以及功能
灵敏度最好的鼠标和键盘之类的,但是初级玩家可能只需要一台主流电脑,至于鼠标键盘原配就足以。如此看来他们所需要的东西类别都一样,只是配置价格或者外
观等不一样而已,当然电脑的组装大家都知道它们拥有相同的接口,组装过程也相同。


  如此看来抽象工厂将在此会发挥巨大作用,当初始化这些配件时可以在各自的配件类中完成,只要它是继承自一个抽象配件类,抽象工厂也会按照这些抽象配件的规则来装配。当有新的配置清单时只需要新增一个工厂车间来选择配件库的配件来组装就可以满足新用户的需求。看来抽象工程它是由产品仓库工厂车间组成,我们可以新增产品同样也可以新增工厂车间,从而满足不同的需求。


  当系统越来越复杂庞大时,需要抽象工厂来帮我们完成如此复杂的装配工作,当客户选中不同的Pc部件想自定义自己的游戏室时,看来使用抽象工厂会让我们的工作相当的容易和有条理。


设计


  如此一来我们知道将要达到什么样的效果了,设计起来也是相当容易的,以产品和工厂的关系为例:


 AbstractFactory


实现


 知道了自己将要做什么,并且将整个过程设计出来,接下来就要将按照设计图纸完成自己要达到的目的,进入编码工作,这是一个需要基本功和耐心的工作。接下来看下代码部分,这些代码是出自某本书,感谢那本书的作者提供代码:



01public class Client
02{
03    private AbstractProductA AbstractProductA;
04    private AbstractProductB AbstractProductB;
05    public Client(AbstractFactory factory)
06    {
07        AbstractProductB = factory.CreateProductB();
08        AbstractProductA = factory.CreateProductA();
09    }
10    public void Run()
11    {
12        AbstractProductB.Interact(AbstractProductA);
13    }
14}
15 
16public abstract class AbstractFactory
17{
18    public abstract AbstractProductA CreateProductA();
19    public abstract AbstractProductB CreateProductB();
20}
21 
22public class ConcreteFactory1 : AbstractFactory
23{
24    public override AbstractProductA CreateProductA()
25    {
26        return new ProductA1();
27    }
28    public override AbstractProductB CreateProductB()
29    {
30        return new ProductB1();
31    }
32}
33 
34public class ConcreteFactory2 : AbstractFactory
35{
36    public override AbstractProductA CreateProductA()
37    {
38        return new ProductA2();
39    }
40    public override AbstractProductB CreateProductB()
41    {
42        return new ProductB2();
43    }
44}
45 
46public abstract class AbstractProductA { }
47 
48public abstract class AbstractProductB
49{
50    public abstract void Interact(AbstractProductA a);
51}
52 
53public class ProductA1: AbstractProductA { }
54 
55public class ProductB1 : AbstractProductB
56{
57    public override void Interact(AbstractProductA a)
58    {
59        Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name);
60    }
61}
62public class ProductA2: AbstractProductA { }
63 
64public class ProductB2 : AbstractProductB
65{
66    public override void Interact(AbstractProductA a)
67    {
68        Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name);
69    }
70}


  想要实现抽象工厂我们必须要做到以下两点:


  1. 拥有众多类的产品库
  2. 拥有组装产品的组装车间

设计模式-单件模式(Singleton)

 设计模式-单件模式(Singleton)
简述

  单件模式属于创建型模式,它是设计模式中最简单的一种模式,当然它的使用也是无处不在的。
功能

  保证一个类仅有一个实例,并提供一个访问它的全局访问点。
何处使用

  当需要控制一个类的实例数量,且调用者可以从一个公共的众所周知的访问点访问时,我们就可以考虑使用单件模式了。
设计

  我们用 UML 来设计单件模式,当然在以后的设计模式的设计部分都将采用 UML 来描述设计,这样就更为形象化了。

singleton
实现

  从 UML 设计图中我们可以看出,为了让一个类只有一个实例,它必须创建一个静态变量,然后我们用一个公共静态的 Instance() 的方法来创建它,但是为了避免这个类自身的构造函数可以创建对象,将构造函数设置成 protected 或者 private,这样外部就只能通过 Instance() 的方法来创建一个静态的 Singleton 类。看来这样我们达到了我们的目的,接下来看代码:
view source
print?
01    public class Singleton
02    {
03        private static Singleton instance;
04        protected Singleton() {}
05        public static Singleton Instance()
06        {
07            if(instance == null)
08                instance = new Singleton();
09     
10            return instance;
11        }
12    }

  由此看来,实现单件模式我们可以做下列几步:

   1. 在类中创建一个静态变量,变量类型为当前类;
   2. 在类中创建一个公共的静态方法,让用户可以通过此方法创建此类的静态对象;
   3. 最后将构造函数设置为 protected 或者 private。