首页 > 文库大全 > 精品范文库 > 15号文库

设计模式-创建型模式的优缺点比较

设计模式-创建型模式的优缺点比较



第一篇:设计模式-创建型模式的优缺点比较

比较几种创建型模式的优缺点,仔细考察这几种模式的区别和相关性。

第一类是工厂模式,工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。

工厂模式有三种形态:简单工厂模式;工厂方法模式;抽象工厂模式是。前两者是类的创建模式,后者是对象的创建模式。

简单工厂:

简单工厂模式是由一个工厂类根据传入的参量决定创建出哪一种产品类的实例,涉及工厂角色(Creator)、抽象产品(Product)角色及具体产品(Concrete Product)角色等三个角色。

优点:

模式的核心是工厂类,该类中含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅负责“消费”产品。

简单工厂模式实现了对责任的分割。

缺点:

当产品类有复杂的多层次等级结构时,工厂类只有它自己。

模式中工厂类集中了所有的产品创建逻辑,形成一个无所不知的全能类。

将多个创建逻辑放在一个类中,当产品类有不同接口种类时,工厂类需要判断在什么时候创建某种产品,使得系统在将来进行功能扩展时较为困难。

该模式采用静态方法作为工厂方法,而静态方法无法由子类继承,因此工厂角色无法形成基于继承的等级结构。

简单工厂模式只在有限的程度上符合“开-闭”原则。

工厂方法:

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。工厂方法模式是简单工厂模式的进一步抽象和推广,其基本思想是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。

优点:

多态性:客户代码可以做到与特定应用无关,适用于任何实体类

子类可以重写新的实现,也可以继承父类的实现。加一层间接性,增加了灵活性。良好的封装性,代码结构清晰。扩展性好,在增加产品类的情况下,只需要适当修改具体的工厂类或扩展一个工厂类,就可“拥抱变化”屏蔽产品类。产品类的实现如何变化,调用者都不需要关心,只需关心产品的接口,只要接口保持不变,系统中的上层模块就不会发生变化。

典型的解耦框架。高层模块只需要知道产品的抽象类,其他的实现类都不需要关心,符合迪米特法则,符合依赖倒置原则,符合里氏替换原则。

缺点: 需要Creator和相应的子类作为工厂方法的载体,如果应用模型确实需要creator和子类存在,则很好;否则的话,需要增加一个类层次。

抽象工厂:

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类,客户端不必指定产品的具体类型,创建多个产品族中的产品对象。

优点:

分离了具体的类,一个工厂封装创建产品对象的责任和过程,它将客户与类的实现分离易于交换产品系列,只需改变具体的工厂就可以使用不同的产品配置。

有利于产品的一致性,当一个系列中的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象。

缺点:

难以支持新的产品等级结构,支持新的产品等级结构就要扩展抽象工厂接口。

单例模式:

一个类仅有一个实例,自行实例化并向整个系统提供一个访问它的全局访问点。确保一个类只能被实例化一次。

优点: 跨平台:使用合适的中间件,可以把singleton模式扩展为跨多个JVM和多个计算机工作。适用于任何类:只需把一个类的构造函数变成私有的,并且在其中增加相应的静态函数和变量,就可以把这个类变为singleton。

可以通过派生创建:给定一个类,可以创建它的一个singleton子类。

延迟求值:如果singleton从未使用过,那么就绝不会创建它。

缺点:

摧毁方法未定义: 没有好的方法去摧毁一个singleton,或者解除其责任。

不能继承:从singleton派生的类并不是singleton。如果要使其成为singleton,必须要增加所需的静态函数和变量。

效率问题:每次调用instance方法都会执行if语句,多余。

不透明性: singleton的使用者知道它们正在使用一个singleton,因为它们必须要调用instance方法。

建造者模式:

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造模式利用一个导演者对象和具体建造者对象一个一个地建造出所有的零件,从而建造出完整的对象。

优点: 建造模式的使用使得产品的内部表象可以独立地变化。使用建造模式可以使客户端不必知道产品内部组成的细节。

每一个Builder都相对独立,而与其他的Builder无关。模式所建造的最终产品更易于控制。

缺点:

建造者模式的“加工工艺”是暴露的,这样使得建造者模式更加灵活,也使得工艺变得对客户不透明。

原型模式:

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。以一个已有的对象作为原型,通过它来创建新的对象。在增加新的对象的时候,新对象的细节创建工作由自己来负责,从而使新对象的创建过程与框架隔离开来。

优点:

原型模式允许动态地增加或减少产品类。由于创建产品类实例的方法是产品类内部具有的,因此增加新产品对整个结构没有影响。

原型模式提供简化的创建结构。工厂方法常需要有一个与产品类相同的等级结构,而原型模式不需要。

具有给一个应用软件加载新功能的能力。

产品类不需要非得有任何事先确定的等级结构,因为原型模式适用于任何的等级结构。

缺点:

每一个类必须配备一个克隆方法。

配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。

关系总结: 工厂方法模式是简单工厂模式的扩展,由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。如果只有一个具体工厂类,工厂方法模式可以改造为简单工厂模式。抽象工厂经常用工厂方法来实现。Prototype:不需要创建Creator的子类,但它们通常需要一个针对Product类的Initialize操作。抽象工厂模式是对象的创建模式,是工厂方法模式的进一步推广。抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。工厂方法模式针对的是一个产品等级结构;抽象工厂模式需要面对多个产品等级结构。Singleton与其他创建型模式并不矛盾,可以用Singleton来实现其他模式中的对象。包括Abstract Factory、Builder、Prototype等。Builder和Abstract Factory都可以创建复杂的对象。但是Builder模式着重于一步步构造一个复杂的对象,强调的是产品的内部组成,Abstract factory着重于多个系列的产品对象。Builder在最后一步返回产品,而Abstract factory立即返回产品。

Abstractor Factory处于更为具体的角度,Builder处于更宏观的角度。一个系统可以由一个建造模式和一个抽象工厂模式组成,客户端通过调用这个建造模式,间接地调用另一个抽象工厂模式的工厂角色。工厂模式返还不同产品族的零件,而建造模式把它们组装起来。8 Prototype和Abstract factory往往是竞争的关系,但是它们也可以一起使用。抽象工厂可以存储一个被克隆的原型的集合,并返回产品的对象。

第二篇:EPC模式优缺点

EPC总承包模式的优、缺点 优点

EPC总承包模式的优点主要有:

1)EPC总承包商负责整个项目的实施过程,不再以单独的分包商身份建设项目,有利于整个项目的统筹规划和协同运作,可以有效解决设计与施工的衔接问题、减少采购与施工的中间环节,顺利解决施工方案中的实用性、技术性、安全性之间的矛盾;

2)工作范围和责任界限清晰,建设期间的责任和风险可以最大程度地转移到总承包商;

3)合同总价和工期固定,业主的投资和工程建设期相对明确,利于费用和进度控制。

4)能够最大限度地发挥工程项目管理各方的优势,实现工程项目管理的各项目标;

5)可以将业主从具体事务中解放出来,关注影响项目的重大因素上,确保项目管理的大方向。缺点

1)业主主要是通过EPC合同对EPC承包商进行监管,对工程实施过程参与程度低,控制力度较低;

2)业主将项目建设风险转移给EPC承包商,因此对承包商的选择至关重要,一旦承包商的管理或财务出现重大问题,项目也将面临巨大风险;

3)EPC承包商责任大,风险高,因此承包商在承接总包工程时会考虑管理投入成本、利润和风险等因素,所以EPC总包合同的工程造价水平一般偏高;

4)与传统的建设模式区别比较大,传统行业的业主比较难以理解和配合承包商的工作。

第三篇:JAVA设计模式之创建模式

设计模式之Builder

Builder模式定义: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们.用户不知道内部的具体构建细节.Builder模式是非常类似抽象工厂模式,细微的区别大概只有在反复使用中才能体会到.为何使用?

是为了将构建复杂对象的过程和它的部件解耦.注意: 是解耦过程和部件.因为一个复杂的对象,不但有很多大量组成部分,如汽车,有很多部件:车轮 方向盘 发动机还有各种小零件等等,部件很多,但远不止这些,如何将这些部件装配成一辆汽车,这个装配过程也很复杂(需要很好的组装技术),Builder模式就是为了将部件和组装过程分开.如何使用?

首先假设一个复杂对象是由多个部件组成的,Builder模式是把复杂对象的创建和部件的创建分别开来,分别用Builder类和Director类来表示.首先,需要一个接口,它定义如何创建复杂对象的各个部件: public interface Builder {

//创建部件A 比如创建汽车车轮

void buildPartA();

//创建部件B 比如创建汽车方向盘

void buildPartB();

//创建部件C 比如创建汽车发动机

void buildPartC();

//返回最后组装成品结果(返回最后装配好的汽车)

//成品的组装过程不在这里进行,而是转移到下面的Director类中进行.//从而实现了解耦过程和部件

Product getResult();} 用Director构建最后的复杂对象,而在上面Builder接口中封装的是如何创建一个个部件(复杂对象是由这些部件组成的),也就是说Director的内容是如何将部件最后组装成成品: public class Director {

private Builder builder;

public Director(Builder builder){

this.builder = builder;} // 将部件partA partB partC最后组成复杂对象 //这里是将车轮 方向盘和发动机组装成汽车的过程 public void construct(){

builder.buildPartA();

builder.buildPartB();

builder.buildPartC();

} } Builder的具体实现ConcreteBuilder: 通过具体完成接口Builder来构建或装配产品的部件;定义并明确它所要创建的是什么具体东西;提供一个可以重新获取产品的接口: public class ConcreteBuilder implements Builder {

Part partA, partB, partC;public void buildPartA(){

//这里是具体如何构建partA的代码

};public void buildPartB(){

//这里是具体如何构建partB的代码 };public void buildPartC(){

//这里是具体如何构建partB的代码 };public Product getResult(){

//返回最后组装成品结果 };} 复杂对象:产品Product: public interface Product { } 复杂对象的部件: public interface Part { }

我们看看如何调用Builder模式: ConcreteBuilder builder = new ConcreteBuilder();Director director = new Director(builder);

director.construct();Product product = builder.getResult();Builder模式的应用

在Java实际使用中,我们经常用到“池”(Pool)的概念,当资源提供者无法提供足够的资源,并且这些资源需要被很多用户反复共享时,就需要使用池.“池”实际是一段内存,当池中有一些复杂的资源的“断肢”(比如数据库的连接池,也许有时一个连接会中断),如果循环再利用这些“断肢”,将提高内存使用效率,提高池的性能.修改Builder模式中Director类使之能诊断“断肢”断在哪个部件上,再修复这个部件.设计模式之Factory

定义:提供创建对象的接口.为何使用?

工厂模式是我们最常用的模式了,著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。

为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A()工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑实用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。我们以类Sample为例,如果我们要创建Sample的实例对象: Sample sample=new Sample();可是,实际情况是,通常我们都要在创建sample实例时做点初始化的工作,比如赋值 查询数据库等。

首先,我们想到的是,可以使用Sample的构造函数,这样生成实例就写成: Sample sample=new Sample(参数);但是,如果创建sample实例时所做的初始化工作不是象赋值这样简单的事,可能是很长一段代码,如果也写入构造函数中,那你的代码很难看了(就需要Refactor重整)。为什么说代码很难看,初学者可能没有这种感觉,我们分析如下,初始化工作如果是很长一段代码,说明要做的工作很多,将很多工作装入一个方法中,相当于将很多鸡蛋放在一个篮子里,是很危险的,这也是有背于Java面向对象的原则,面向对象的封装(Encapsulation)和分派(Delegation)告诉我们,尽量将长的代码分派“切割”成每段,将每段再“封装”起来(减少段和段之间偶合联系性),这样,就会将风险分散,以后如果需要修改,只要更改每段,不会再发生牵一动百的事情。

在本例中,首先,我们需要将创建实例的工作与使用实例的工作分开, 也就是说,让创建实例所需要的大量初始化工作从Sample的构造函数中分离出去。

这时我们就需要Factory工厂模式来生成对象了,不能再用上面简单new Sample(参数)。还有,如果Sample有个继承如MySample, 按照面向接口编程,我们需要将Sample抽象成一个接口.现在Sample是接口,有两个子类MySample 和HisSample.我们要实例化他们时,如下: Sample mysample=new MySample();Sample hissample=new HisSample();随着项目的深入,Sample可能还会“生出很多儿子出来”, 那么我们要对这些儿子一个个实例化,更糟糕的是,可能还要对以前的代码进行修改:加入后来生出儿子的实例.这在传统程序中是无法避免的.但如果你一开始就有意识使用了工厂模式,这些麻烦就没有了.工厂方法

你会建立一个专门生产Sample实例的工厂: public class Factory{

public static Sample creator(int which){

//getClass 产生Sample 一般可使用动态类装载装入类。if(which==1)

return new SampleA();else if(which==2)

return new SampleB();

} } 那么在你的程序中,如果要实例化Sample时.就使用 Sample sampleA=Factory.creator(1);这样,在整个就不涉及到Sample的具体子类,达到封装效果,也就减少错误修改的机会,这个原理可以用很通俗的话来比喻:就是具体事情做得越多,越容易范错误.这每个做过具体工作的人都深有体会,相反,官做得越高,说出的话越抽象越笼统,范错误可能性就越少.好象我们从编程序中也能悟出人生道理?呵呵.使用工厂方法 要注意几个角色,首先你要定义产品接口,如上面的Sample,产品接口下有Sample接口的实现类,如SampleA,其次要有一个factory类,用来生成产品Sample,如下图,最右边是生产的对象Sample:

进一步稍微复杂一点,就是在工厂类上进行拓展,工厂类也有继承它的实现类concreteFactory了。抽象工厂

工厂模式中有: 工厂方法(Factory Method)抽象工厂(Abstract Factory).这两个模式区别在于需要创建对象的复杂程度上。如果我们创建对象的方法变得复杂了,如上面工厂方法中是创建一个对象Sample,如果我们还有新的产品接口Sample2.这里假设:Sample有两个concrete类SampleA和SamleB,而Sample2也有两个concrete类Sample2A和SampleB2 那么,我们就将上例中Factory变成抽象类,将共同部分封装在抽象类中,不同部分使用子类实现,下面就是将上例中的Factory拓展成抽象工厂: public abstract class Factory{

public abstract Sample creator();

public abstract Sample2 creator(String name);} public class SimpleFactory extends Factory{

public Sample creator(){

.........return new SampleA } public Sample2 creator(String name){

.........return new Sample2A } } public class BombFactory extends Factory{

public Sample creator(){

......return new SampleB } public Sample2 creator(String name){

......return new Sample2B } }

从上面看到两个工厂各自生产出一套Sample和Sample2,也许你会疑问,为什么我不可以使用两个工厂方法来分别生产Sample和Sample2? 抽象工厂还有另外一个关键要点,是因为 SimpleFactory内,生产Sample和生产Sample2的方法之间有一定联系,所以才要将这两个方法捆绑在一个类中,这个工厂类有其本身特征,也许制造过程是统一的,比如:制造工艺比较简单,所以名称叫SimpleFactory。在实际应用中,工厂方法用得比较多一些,而且是和动态类装入器组合在一起应用,举例

我们以Jive的ForumFactory为例,这个例子在前面的Singleton模式中我们讨论过,现在再讨论其工厂模式: public abstract class ForumFactory {

private static Object initLock = new Object();

private static String className = “com.jivesoftware.forum.database.DbForumFactory”;

private static ForumFactory factory = null;

public static ForumFactory getInstance(Authorization authorization){

//If no valid authorization passed in, return null.if(authorization == null){

return null;

}

//以下使用了Singleton 单态模式

if(factory == null){

synchronized(initLock){

if(factory == null){

......}

}

} try {

//动态转载类

Class c = Class.forName(className);

factory =(ForumFactory)c.newInstance();} catch(Exception e){

return null;}

//Now, 返回 proxy.用来限制授权对forum的访问

return new ForumFactoryProxy(authorization, factory,factory.getPermissions(authorization));

}

//真正创建forum的方法由继承forumfactory的子类去完成.public abstract Forum createForum(String name, String description)

throws UnauthorizedException, ForumAlreadyExistsException;

....}

因为现在的Jive是通过数据库系统存放论坛帖子等内容数据,如果希望更改为通过文件系统实现,这个工厂方法ForumFactory就提供了提供动态接口: private static String className = “com.jivesoftware.forum.database.DbForumFactory”;你可以使用自己开发的创建forum的方法代替com.jivesoftware.forum.database.DbForumFactory就可以.在上面的一段代码中一共用了三种模式,除了工厂模式外,还有Singleton单态模式,以及proxy模式,proxy模式主要用来授权用户对forum的访问,因为访问forum有两种人:一个是注册用户 一个是游客guest,那么那么相应的权限就不一样,而且这个权限是贯穿整个系统的,因此建立一个proxy,类似网关的概念,可以很好的达到这个效果.看看Java宠物店中的CatalogDAOFactory: public class CatalogDAOFactory {

/**

* 本方法制定一个特别的子类来实现DAO模式。

* 具体子类定义是在J2EE的部署描述器中。

*/

public static CatalogDAO getDAO()throws CatalogDAOSysException {

CatalogDAO catDao = null;

try {

InitialContext ic = new InitialContext();//动态装入CATALOG_DAO_CLASS //可以定义自己的CATALOG_DAO_CLASS,从而在无需变更太多代码 //的前提下,完成系统的巨大变更。

String className =(String)ic.lookup(JNDINames.CATALOG_DAO_CLASS);

catDao =(CatalogDAO)Class.forName(className).newInstance();

} catch(NamingException ne){

throw new CatalogDAOSysException(“

CatalogDAOFactory.getDAO: NamingException while

getting DAO type : n” + ne.getMessage());

} catch(Exception se){

throw new CatalogDAOSysException(“

CatalogDAOFactory.getDAO: Exception while getting

DAO type : n” + se.getMessage());

}

return catDao;

} } CatalogDAOFactory是典型的工厂方法,catDao是通过动态类装入器className获得CatalogDAOFactory具体实现子类,这个实现子类在Java宠物店是用来操作catalog数据库,用户可以根据数据库的类型不同,定制自己的具体实现子类,将自己的子类名给与CATALOG_DAO_CLASS变量就可以。

由此可见,工厂方法确实为系统结构提供了非常灵活强大的动态扩展机制,只要我们更换一下具体的工厂方法,系统其他地方无需一点变换,就有可能将系统功能进行改头换面的变化。

设计模式之Prototype(原型)

定义: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。如何使用? 因为Java中的提供clone()方法来实现对象的克隆(具体了解clone()按这里),所以Prototype模式实现一下子变得很简单.以勺子为例:

public abstract class AbstractSpoon implements Cloneable {

String spoonName;

public void setSpoonName(String spoonName){this.spoonName = spoonName;}

public String getSpoonName(){return this.spoonName;}

public Object clone()

{

Object object = null;

try {

object = super.clone();

} catch(CloneNotSupportedException exception){

System.err.println(“AbstractSpoon is not Cloneable”);

}

return object;

} } 有两个具体实现(ConcretePrototype): public class SoupSpoon extends AbstractSpoon {

public SoupSpoon()

{

setSpoonName(“Soup Spoon”);

} } public class SaladSpoon extends AbstractSpoon {

public SaladSpoon()

{

setSpoonName(“Salad Spoon”);

} } 调用Prototype模式很简单: AbstractSpoon spoon = new SoupSpoon();AbstractSpoon spoon = new SaladSpoon();当然也可以结合工厂模式来创建AbstractSpoon实例。

在Java中Prototype模式变成clone()方法的使用,由于Java的纯洁的面向对象特性,使得在Java中使用设计模式变得很自然,两者已经几乎是浑然一体了。这反映在很多模式上,如Interator遍历模式。

设计模式之Singleton(单态)

定义: Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。

还有, singleton能够被状态化;这样,多个单态类在一起就可以作为一个状态仓库一样向外提供服务,比如,你要论坛中的帖子计数器,每次浏览一次需要计数,单态类能否保持住这个计数,并且能synchronize的安全自动加1,如果你要把这个数字永久保存到数据库,你可以在不修改单态接口的情况下方便的做到。

另外方面,Singleton也能够被无状态化。提供工具性质的功能,Singleton模式就为我们提供了这样实现的可能。使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage collection)。

我们常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。如何使用?

一般Singleton模式通常有几种形式: public class Singleton {

private Singleton(){}

//在自己内部定义自己一个实例,是不是很奇怪?

//注意这是private 只供内部调用

private static Singleton instance = new Singleton();

}

第二种形式: public class Singleton {

private static Singleton instance = null;public static synchronized Singleton getInstance(){

//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次

//使用时生成实例,提高了效率!if(instance==null)

instance=new Singleton();return instance;} //这里提供了一个供外部访问本class的静态方法,可以直接访问

public static Singleton getInstance(){

return instance;

} }

使用Singleton.getInstance()可以访问单态类。

上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。

注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking(DCL)的讨论,有兴趣者进一步研究。

一般认为第一种形式要更加安全些。使用Singleton注意事项:

有时在某些情况下,使用Singleton并不能达到Singleton的目的,如有多个Singleton对象同时被不同的类装入器装载;在EJB这样的分布式系统中使用也要注意这种情况,因为EJB是跨服务器,跨JVM的。

我们以SUN公司的宠物店源码(Pet Store 1.3.1)的ServiceLocator为例稍微分析一下:

在Pet Store中ServiceLocator有两种,一个是EJB目录下;一个是WEB目录下,我们检查这两个ServiceLocator会发现内容差不多,都是提供EJB的查询定位服务,可是为什么要分开呢?仔细研究对这两种ServiceLocator才发现区别:在WEB中的ServiceLocator的采取Singleton模式,ServiceLocator属于资源定位,理所当然应该使用Singleton模式。但是在EJB中,Singleton模式已经失去作用,所以ServiceLocator才分成两种,一种面向WEB服务的,一种是面向EJB服务的。

Singleton模式看起来简单,使用方法也很方便,但是真正用好,是非常不容易,需要对Java的类 线程 内存等概念有相当的了解。进一步深入可参考:

Double-checked locking and the Singleton pattern When is a singleton not a singleton?

第四篇:不同RAID模式的优缺点

不同RAID模式的优缺点

近来想建立一个私有云系统,涉及到安装使用一台网络存储服务器。对于服务器中硬盘的连接,选用哪种RAID模式能准确满足需求收集了资料,简单整理后记录如下:

一、RAID模式优缺点的简要介绍

目前被运用较多的RAID模式其优缺点大致是这样的:

1、RAID0模式

优点:在RAID 0状态下,存储数据被分割成两部分,分别存储在两块硬盘上,此时移动硬盘的理论存储速度是单块硬盘的2倍,实际容量等于两块硬盘中较小一块硬盘的容量的2倍。

缺点:任何一块硬盘发生故障,整个RAID上的数据将不可恢复。

备注:存储高清电影比较适合。

2、RAID1模式

优点:此模式下,两块硬盘互为镜像。当一个硬盘受损时,换上一块全新硬盘(大于或等于原硬盘容量)替代原硬盘即可自动恢复资料和继续使用,移动硬盘的实际容量等于较小一块硬盘的容量,存储速度与单块硬盘相同。RAID 1的优势在于任何一块硬盘出现故障是,所存储的数据都不会丢失。

缺点:该模式可使用的硬盘实际容量比较小,仅仅为两颗硬盘中最小硬盘的容量。

备注:非常重要的资料,如数据库,个人资料,是万无一失的存储方案。

3、RAID 0+1模式

RAID 0+1是磁盘分段及镜像的结合,采用2组RAID0的磁盘阵列互为镜像,它们之间又成为一个RAID1的阵列。硬盘使用率只有50%,但是提供最佳的速度及可靠度。

4、RAID 3模式

RAID3是把数据分成多个“块”,按照一定的容错算法,存放在N+1个硬盘上,实际数据占用的有效空间为N个硬盘的空间总和,而第N+1个硬盘存储的数据是校验容错信息,当这N+1个硬盘中的其中一个硬盘出现故障时,从其它N个硬盘中的数据也可以恢复原始数据。

5、RAID 5模式

RAID5不对存储的数据进行备份,而是把数据和相对应的奇偶校验信息存储到组成RAID5的各个磁盘上,并且奇偶校验信息和相对应的数据分别存储于不同的磁盘上。当RAID5的一个磁盘数据发生损坏后,利用剩下的数据和相应的奇偶校验信息去恢复被损坏的数据。

6、RAID 10模式

RAID10最少需要4块硬盘才能完成。把2块硬盘组成一个RAID1,然后两组RAID1组成一个RAID0。虽然RAID10方案造成了50%的磁盘浪费,但是它提供了200%的速度和单磁盘损坏的数据安全性。

二、另外三种硬件快速硬件设置模式简介

在收集资料时看到有的硬件设备提供快速磁盘模式设置,也很方便大家的使用,具体情况如下:

1、Clone模式

克隆模式,磁盘全部数据一样,以最小硬盘的为准。

2、Large模式

硬盘容量简单相加,将几个硬盘变成一个硬盘,容量为几个硬盘容量之和,此模式下可以获得最大的硬盘空间。

3、Normal模式

硬盘分别处于正常、独立的状态,可以分别独立的写入或读取资料,能使用的实际容量分别为4个硬盘的容量。如果其中一个硬盘受损,其他几个硬盘不会受影响。

三、RAID使用简明注意事项

★使用前请先备份硬盘的资料,一旦进行RAID设定或是变更RAID模式,将会清除硬盘里的所有资料,以及无法恢复;

★建立RAID时,建议使用相同品牌、型号和容量的硬盘,以确保性能和稳定;

★请勿随意更换或取出硬盘,如果取出了硬盘,请记下硬盘放入两个仓位的顺序不得更改,以及请勿只插入某一块硬盘使用,以避免造成资料损坏或丢失;

★如果旧硬盘曾经在RAID模式下使用,请先进清除硬盘RAID信息,让硬盘回复至出厂状态,以免RAID建立失败;

★RAID0模式下,其中一个硬盘损坏时,其它硬盘所有资料都将丢失;

★RAID1模式下,如果某一块硬盘受损,可以用一块大于或等于受损硬盘容量的新硬盘替换坏硬盘然后开机即可自动恢复和修复资料以及RAID模式。此过程需要一定时间,请耐心等待

四、细数RAID模式

1、概念

磁盘阵列(Redundant Arrays of Inexpensive Disks,RAID),有“价格便宜且多余的磁盘阵列”之意。原理是利用数组方式来作磁盘组,配合数据分散排列的设计,提升数据的安全性。磁盘阵列是由很多便宜、容量较小、稳定性较高、速度较慢磁盘,组合成一个大型的磁盘组,利用个别磁盘提供数据所产生加成效果提升整个磁盘系统效能。同时利用这项技术,将数据切割成许多区段,分别存放在各个硬盘上。磁盘阵列还能利用同位检查(Parity Check)的观念,在数组中任一颗硬盘故障时,仍可读出数据,在数据重构时,将数据经计算后重新置入新硬盘中。

2、规范

RAID技术主要包含RAID 0~RAID 50等数个规范,它们的侧重点各不相同,常见的规范有如下几种:

RAID 0:RAID 0连续以位或字节为单位分割数据,并行读/写于多个磁盘上,因此具有很高的数据传输率,但它没有数据冗余,因此并不能算是真正的RAID结构。RAID 0只是单纯地提高性能,并没有为数据的可靠性提供保证,而且其中的一个磁盘失效将影响到所有数据。因此,RAID 0不能应用于数据安全性要求高的场合。

RAID 1:它是通过磁盘数据镜像实现数据冗余,在成对的独立磁盘上产生互为备份的数据。当原始数据繁忙时,可直接从镜像拷贝中读取数据,因此RAID 1可以提高读取性能。RAID 1是磁盘阵列中单位成本最高的,但提供了很高的数据安全性和可用性。当一个磁盘失效时,系统可以自动切换到镜像磁盘上读写,而不需要重组失效的数据。

RAID 0+1: 也被称为RAID 10标准,实际是将RAID 0和RAID 1标准结合的产物,在连续地以位或字节为单位分割数据并且并行读/写多个磁盘的同时,为每一块磁盘作磁盘镜像进行冗余。它的优点是同时拥有RAID 0的超凡速度和RAID 1的数据高可靠性,但是CPU占用率同样也更高,而且磁盘的利用率比较低。

RAID 2:将数据条块化地分布于不同的硬盘上,条块单位为位或字节,并使用称为“加重平均纠错码(海明码)”的编码技术来提供错误检查及恢复。这种编码技术需要多个磁盘存放检查及恢复信息,使得RAID 2技术实施更复杂,因此在商业环境中很少使用。

RAID 3:它同RAID 2非常类似,都是将数据条块化分布于不同的硬盘上,区别在于RAID 3使用简单的奇偶校验,并用单块磁盘存放奇偶校验信息。如果一块磁盘失效,奇偶盘及其他数据盘可以重

新产生数据;如果奇偶盘失效则不影响数据使用。RAID 3对于大量的连续数据可提供很好的传输率,但对于随机数据来说,奇偶盘会成为写操作的瓶颈。

RAID 4:RAID 4同样也将数据条块化并分布于不同的磁盘上,但条块单位为块或记录。RAID 4使用一块磁盘作为奇偶校验盘,每次写操作都需要访问奇偶盘,这时奇偶校验盘会成为写操作的瓶颈,因此RAID 4在商业环境中也很少使用。

RAID 5:RAID 5不单独指定的奇偶盘,而是在所有磁盘上交叉地存取数据及奇偶校验信息。在RAID 5上,读/写指针可同时对阵列设备进行操作,提供了更高的数据流量。RAID 5更适合于小数据块和随机读写的数据。RAID 3与RAID 5相比,最主要的区别在于RAID 3每进行一次数据传输就需涉及到所有的阵列盘;而对于RAID 5来说,大部分数据传输只对一块磁盘操作,并可进行并行操作。在RAID 5中有“写损失”,即每一次写操作将产生四个实际的读/写操作,其中两次读旧的数据及奇偶信息,两次写新的数据及奇偶信息。

RAID 6:与RAID 5相比,RAID 6增加了第二个独立的奇偶校验信息块。两个独立的奇偶系统使用不同的算法,数据的可靠性非常高,即使两块磁盘同时失效也不会影响数据的使用。但RAID 6需要分配给奇偶校验信息更大的磁盘空间,相对于RAID 5有更大的“写损失”,因此“写性能”非常差。较差的性能和复杂的实施方式使得RAID 6很少得到实际应用。

RAID 7:这是一种新的RAID标准,其自身带有智能化实时操作系统和用于存储管理的软件工具,可完全独立于主机运行,不占用主机CPU资源。RAID 7可以看作是一种存储计算机(Storage Computer),它与其他RAID标准有明显区别。除了以上的各种标准(如表1),我们可以如RAID 0+1那样结合多种RAID规范来构筑所需的RAID阵列,例如RAID 5+3(RAID 53)就是一种应用较为广泛的阵列形式。用户一般可以通过灵活配置磁盘阵列来获得更加符合其要求的磁盘存储系统。

RAID 5E(RAID 5 Enhencement): RAID 5E是在RAID 5级别基础上的改进,与RAID 5类似,数据的校验信息均匀分布在各硬盘上,但是,在每个硬盘上都保留了一部分未使用的空间,这部分空间没有进行条带化,最多允许两块物理硬盘出现故障。看起来,RAID 5E和RAID 5加一块热备盘好象差不多,其实由于RAID 5E是把数据分布在所有的硬盘上,性能会比RAID5 加一块热备盘要好。当一块硬盘出现故障时,有故障硬盘上的数据会被压缩到其它硬盘上未使用的空间,逻辑盘保持RAID 5级别。

RAID 5EE: 与RAID 5E相比,RAID 5EE的数据分布更有效率,每个硬盘的一部分空间被用作分布的热备盘,它们是阵列的一部分,当阵列中一个物理硬盘出现故障时,数据重建的速度会更快。

RAID 50:RAID50是RAID5与RAID0的结合。此配置在RAID5的子磁盘组的每个磁盘上进行包括奇偶信息在内的数据的剥离。每个RAID5子磁盘组要求三个硬盘。RAID50具备更高的容错能力,因为它允许某个组内有一个磁盘出现故障,而不会造成数据丢失。而且因为奇偶位分部于RAID5子磁盘组上,故重建速度有很大提高。优势:更高的容错能力,具备更快数据读取速率的潜力。需要注意的是:磁盘故障会影响吞吐量。故障后重建信息的时间比镜像配置情况下要长。

3、优点

提高传输速率。RAID通过在多个磁盘上同时存储和读取数据来大幅提高存储系统的数据吞吐量(Throughput)。在RAID中,可以让很多磁盘驱动器同时传输数据,而这些磁盘驱动器在逻辑上又是一个磁盘驱动器,所以使用RAID可以达到单个磁盘驱动器几倍、几十倍甚至上百倍的速率。这也是RAID最初想要解决的问题。因为当时CPU的速度增长很快,而磁盘驱动器的数据传输速率无法大幅提高,所以需要有一种方案解决二者之间的矛盾。RAID最后成功了。

通过数据校验提供容错功能。普通磁盘驱动器无法提供容错功能,如果不包括写在磁盘上的CRC(循环冗余校验)码的话。RAID容错是建立在每个磁盘驱动器的硬件容错功能之上的,所以它提供更高的安全性。在很多RAID模式中都有较为完备的相互校验/恢复的措施,甚至是直接相互的镜像备份,从而大大提高了RAID系统的容错度,提高了系统的稳定冗余性。

4、实现

磁盘阵列有两种方式可以实现,那就是“软件阵列”与“硬件阵列”。

软件阵列是指通过网络操作系统自身提供的磁盘管理功能将连接的普通SCSI卡上的多块硬盘配置成逻辑盘,组成阵列。软件阵列可以提供数据冗余功能,但是磁盘子系统的性能会有所降低,有的降低幅度还比较大,达30%左右。

硬件阵列是使用专门的磁盘阵列卡来实现的。硬件阵列能够提供在线扩容、动态修改阵列级别、自动数据恢复、驱动器漫游、超高速缓冲等功能。它能提供性能、数据保护、可靠性、可用性和可管理性的解决方案。阵列卡专用的处理单元来进行操作,它的性能要远远高于常规非阵列硬盘,并且更安全更稳定。

磁盘阵列其实也分为软阵列(Software Raid)和硬阵列(Hardware Raid)两种.软阵列即通过软件程序并由计算机的 CPU提供运行能力所成.由于软件程式不是一个完整系统故只能提供最基本的 RAID容错功能.其他如热备用硬盘的设置, 远程管理等功能均一一欠奉.硬阵列是由独立操作的硬件提供整个磁盘阵列的控制和计算功能.不依靠系统的CPU资源.由于硬阵列是一个完整的系统, 所有需要的功能均可以做进去.所以硬阵列所提供的功能和性能均比软阵列好.而且, 如果你想把系统也做到磁盘阵列中, 硬阵列是唯一的选择.故我们可以看市场上 RAID 5 级的磁盘阵列均为硬阵列.软 阵列只适用于 Raid 0 和 Raid 1.对于我们做镜像用的镜像塔, 肯定不会用 Raid 0或 Raid 1。作为高性能的存储系统,已经得到了越来越广泛的应用。RAID的级别从RAID概念的提出到现在,已经发展了六个级别,其级别分别是0、1、2、3、4、5等。但是最常用的是0、1、3、5四个级别。

五、个人用户该选那种RAID模式

首先要分析清楚,我们需要存储的文件有什么样的属性。这其中需要大量存储的和占用存储量大的文件是两回事儿。

从使用角度粗略分,个人需要存储的文件大致有文本文件、照片录像、影音文件、应用程序等。

1、文本文件:大量长期存放,阶段性更新,但其占用空间小,安全性要求个别较高,大部分一般;

2、照片录像:大量长期存放,永久性记录,占用空间大,安全性要求高,一旦损失很难弥补;

3、影音文件:一部分大量长期存放,一部分大量短期存放,阶段性更新,占用空间大,安全性要求一般,即便损失了,也可以再从网络上下载恢复;

4、应用程序:这其中包括一些软件和硬件的驱动等,对于软件,目前基本可以从网络上获得,驱动程序有时需要预先备份,安装设备时随时可用,属于量少但要长期存放的,阶段性更新,安全性要求一般。

看看自己需要对哪种类型的文件进行存储,再选择自己需要的RAID模式即可。

本人的照片和私人录影资料较多,平时喜欢收集APE等无损格式的音乐文件,对于个人来说这都是至宝,不可有所损失,再有就是一些硬件的驱动程序,相对比较重要,另外会编辑少量的个人文件,阶段性比较重要,最后是影片,看完也就删除了,不太重要。而照片录像和无损音乐占用的空间又是巨大的,安全性要求又很高,权衡后,在节约资金确保安全的前提下,准备购置五块大容量硬盘,组成NAS存储服务器,选择RAID5模式。

顺便说,购置五快硬盘的原因还有一个,就是我使用的是老机箱改造NAS服务器,市面上有3转5的硬盘笼子可以简单将原有的3个光驱位变成5块硬盘的存储位,考虑到家用存储8T的容量已经足够了,10T基本上可以无忧了,所以选择了5块硬盘,每块2T容量。当然组成RAOD5后会少于10T,那也足够了!

NAS的好处很多,这里就不在赘述,有兴趣的朋友建议深入了解。它既可以完成集中存储还可以完成诸如自动BT下载,网络打印机,苹果媒体服务器等众多私有云功能,是很好的家庭网络应用解决方案。

RIAD10比RAID01好在哪里

01模式坏一个盘会导致初级raid0挂,然后导致次级raid1降级,10模式坏一个盘会导致初级raid1降级,然而次级raid0不受影响

第五篇:故障模式影响分析优缺点分析

三 故障模式影响分析优缺点分析

故障模式与影响分析(fault modes and effects analysis简称 FMEA)是指:研究产品的每个组成部分可能存在的故障模式并确定各个故障模式对产品其他组成部分和产品要求的影响的一种定性的可靠性分析方法,是可靠性定性分析的一种技术。【5】通过对设备进行FMEA分析时,可系统的了解设备的设计制造缺陷、构造功能和潜在的故障模式。【14】

FMEA 的原理简单明了而且容易掌握,但较繁琐、耗时多。如果与因果图及故障树分析配合使用,将是十分有用的可靠性定性分析方法。

FMEA 采用 “自下而上” 由因到果的逻辑归纳法。即从系统结构的最基层(元器件)开始跟踪系统级,以决定每个故障模式对系统性能的影响,是对单一故障而言。而故障树是 “ 自上而下 ”由果到因的逻辑演绎法,是对所有的故障进行分析,两者可以结合起来使用。

一 评价模型

模型是客观系统某一方面本质属性的描述,它以某种确定的形式提供关于该系统的知识,是我们用来认识客观世界的有力工具。【1】我国学者杨明增,李拴保【2】等人根据系统风险评估的阶段和目标将评估模型分为风险概念模型、评估过程模型、风险分析模型和风险评价 模型,解决了现有风险评估研究中模型混杂的问题,为风险评估的研究提供了重要的知识框架。

    版权声明:此文自动收集于网络,若有来源错误或者侵犯您的合法权益,您可通过邮箱与我们取得联系,我们将及时进行处理。

    本文地址:https://www.feisuxs.com/wenku/jingpin/15/1409581.html

相关内容

热门阅读

最新更新

随机推荐