




已阅读5页,还剩103页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
目录第八章 结构型模式38.1 适配器模式(ADAPTER)类对象结构型模式48.1.1 意图48.1.2 别名48.1.3 动机48.1.4 适用性68.1.5 结构68.1.6 参与者78.1.7 协作98.1.8 优点和缺点(效果)98.1.9 实现108.1.10 代码示例108.1.11 已知应用128.1.12 相关模式128.1.13 练习138.2 组合模式(COMPOSITE) 对象结构型模式248.2.1 意图248.2.2 别名248.2.3 动机258.2.4 适用性268.2.5 结构268.2.6 参与者278.2.7 协作308.2.8 效果318.2.9 实现318.2.10 代码示例358.2.11 已知应用388.2.12 相关模式388.2.13 练习388.3 装饰模式(DECORATOR)对象结构型模式428.3.1 意图428.3.2 别名428.3.3 动机428.3.4 适用性448.3.5 结构448.3.6 参与者448.3.7 协作478.3.8 效果478.3.9 实现488.3.10 代码示例508.3.11 已知应用528.3.12 相关模式528.3.13 练习538.4 桥接模式(BRIDGE)对象结构型模式648.4.1 意图648.4.2 别名648.4.3 动机648.4.4 适用性658.4.5 结构668.4.6 参与者668.4.7 协作698.4.8 效果698.4.9 实现698.4.10 代码示例708.4.11 已知应用738.4.12 相关模式738.4.13 练习748.6 外观模式(FACADE)对象结构型模式788.6.1 意图788.6.2 别名788.6.3 动机798.6.4 适用性798.6.5 结构798.6.6 参与者798.6.7 协作828.6.8 效果828.6.9 实现828.6.10 代码示例838.6.11 已知应用838.6.12 相关模式838.6.13 练习838.7 享元模式(FLYWEIGHT)对象结构型模式868.7.1 意图868.7.2 别名868.7.3 动机878.7.4 适用性878.7.5 结构878.7.6 参与者878.7.7 协作908.7.8 效果908.7.9 实现908.7.10 代码示例908.7.11 已知应用918.7.12 相关模式918.7.13 练习918.8 代理模式(PROXY)对象结构型模式958.8.1 意图958.8.2 别名958.8.3 动机958.8.4 适用性968.8.5 结构978.8.6 参与者978.8.7 协作998.8.8 效果1008.8.9 实现1008.8.10 代码示例1008.8.11 已知应用1008.8.12 相关模式1018.8.13 练习1018.9 结构型模式的讨论107第八章 结构型模式结构型模式涉及到如何组合类和对象以获得更大的结构。结构型类模式采用继承机制来组合接口或实现。一般来说,适配器使得一个接口(adaptee的接口)与其他接口兼容,从而给出了多个不同接口的统一抽象。为此,类适配器对一个adaptee类进行私有继承。这样,适配器就可以用adaptee的接口表示它的接口。结构型对象模式不是对接口和实现进行组合,而是描述了如何对一个对象进行组合,从而实现新功能的一些方法。因为可以在运行时刻改变对象组合关系,所以对象组合方式具有更大的灵活性,而这种机制用静态类组合是不可能实现的。Composite模式是结构型对象模式的一个实例。它描述了如何构造一个类层次式结构,这一结构由两种类型的对象所对应的类构成。其中的组合对象使得你可以组合基元对象以及其他的组合对象,从而形成任意复杂的结构。在Proxy模式中,proxy对象作为其他对象的一个方便的替代或占位符。它的使用可以有多种形式。Proxy模式还提供了对对象的一些特有性质的一定程度上的间接访问,从而它可以限制、增强或修改这些性质。Decorator模式描述了如何动态地为对象添加职责。Decorator模式是一种结构型模式。这一模式采用递归方式组合对象,从而允许你添加任意多的对象职责。可以将一个Decorator对象嵌套在另外一个对象中就可以很简单地增加两个装饰,添加其他的装饰也是如此。因此,每个Decorator对象必须与其组件的接口兼容并且保证将消息传递给它。Decorator模式在转发一条消息之前或之后都可以完成它的工作。8.1 适配器模式(ADAPTER)类对象结构型模式8.1.1 意图将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能够一起工作的那些类可以一起工作。8.1.2 别名包装器Wrapper。8.1.3 动机有时,为复用而涉及的工具箱类不能够被复用的原因仅仅是因为它的接口与专业应用领域所需要的接口不匹配。例如,有一个绘图编辑器,这个编辑器允许用户绘制和排列基本图元(线、多边形和正文等)生成图片和图表。这个绘图编辑器的关键抽象是图形对象。图形对象有一个可编译的形状,并可以绘制自身。图形对象的接口由一个称为Shape的抽象类定义。绘图编辑器为每一种图形对象定义了一个Shape的子类:LineShape类对应于直线,PolygonShape类对应于多边形,等等。LineShape和PolygonShape这样的基本几何图形的类比较容易实现,这是由于它们的绘图和编译功能本来就很有限。但是对于可以显示和编辑正文的TextShape子类来说,实现相当困难,因为即使是基本的正文编辑也要涉及到复杂的屏幕刷新和缓冲区管理。同时成品的用户节目工具箱可能已经提供了一个复杂的TextView类用于显示和编辑正文。理想的情况是我们可以复用这个TextView类以实现TextShape类,但是工具箱的设计者当时并没有考虑Shape的存在,因此TextView和Shape对象不能互换。一个应用可能会有一些类具有不同的接口并且这些接口互不兼容,在这样的应用中象TextView这样已经存在并且不相关的类如何协同工作呢?我们可以改变TextView类使它兼容Shape类的接口,但前提是必须有这个工具箱的源代码。然而即使我们得到了这些源代码,修改TextView也是没有什么意义的;因为不应该仅仅为了实现一个应用,工具箱就不得不采用一些与特定领域相关的接口。我们可以不用上面的方法,而定义一个TextShape类,由它来适配TextView的接口和Shape的接口。我们可以用两种方法做这件事:1)继承Shape类的接口和TextView的实现,或2)将一个TextView实例作为TextShape的组成部分,并且使用TextView的接口实现TextShape。这两种方法恰恰对应于Adapter模式的类和对象版本。我们将TextShape称之为适配器Adapter。ShapeBoundingBox()CreateManipulator()LineBoundingBox( )CreateManipulator( )TextShapeBoundingBox( )CreateManipulator( )TextViewGetExtent( )DrawingEditorReturn text-GetExtent()Return new TextManipuplatortext上面的类图说明了对象适配器实例。它说明了在Shape类中声明的BoundingBox请求如何被转换成在TextView类中定义的GetExtent请求。由于TextShape将TextView的接口与Shape的接口进行了匹配,因此绘图编辑器就建议复用原先并不兼容的TextView类。Adapter时常还要负责提供被匹配的类所没有提供的功能,上面的类图中说明了适配器如何实现这些职责。由于绘图编辑器允许用户交互的将每一个Shape对象拖动到一个新的位置,而TextView设计中没有这种功能。我们可以实现TextShape类的CreateManipulator操作,从而增加这个缺少的功能,这个操作返回相应的Manipulator子类的一个实例。Manipulator是一个抽象类,它所描述的对象知道如何驱动Shape类响应相应的用户输入,例如将图形拖动到一个新的位置。对应于不同形状的图形,Manipulator有不同的子类;例如TextManipulator对应于TextShape。TextShape通过返回一个TextManipulator实例,增加了TextView中缺少而Shape需要的功能。8.1.4 适用性1. 你想使用一个已经存在的类,而它的接口不符合你的需要。2. 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类协同工作。3. 你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。8.1.5 结构类适配器使用多重继承对一个接口与另一个接口进行匹配,如下图所示:对象适配器依赖于对象组合,如下图所示:8.1.6 参与者l Target:定义Client使用的与特定领域相关的接口。l Client:与符合Target接口的对象协同。l Adaptee:定义一个已经存在的接口,这个接口需要适配。l Adapter:对Adaptee的接口与Target接口进行适配。对象适配器模型代码原型:/ Adapter pattern - Structural example using System;namespace DoFactory.GangOfFour.Adapter.Structural/ / MainApp startup class for Structural/ Adapter Design Pattern./ class MainApp/ / Entry point into console application./ static void Main()/ Create adapter and place a requestTarget target = new Adapter();target.Request();/ Wait for userConsole.ReadKey();/ / The Target class/ class Targetpublic virtual void Request()Console.WriteLine(Called Target Request();/ / The Adapter class/ class Adapter : Targetprivate Adaptee _adaptee = new Adaptee();public override void Request()/ Possibly do some other work/ and then call SpecificRequest_adaptee.SpecificRequest();/ / The Adaptee class/ class Adapteepublic void SpecificRequest()Console.WriteLine(Called SpecificRequest();Output Called SpecificRequest()8.1.7 协作Client在Adapter实例上调用一些操作。接着适配器调用Adaptee的操作实现这个请求。客户使用适配器的过程: 客户通过目标接口调用适配器的方法对适配器发出请求 适配器使用被适配者接口把请求转换成被适配者的一个或多个调用接口(客户与被适配者是解耦的,一个不知道另一个) 客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用 适配器实现了目标接口,而此目标接口是由被适配者所组合的8.1.8 优点和缺点(效果)类适配器和对象适配器有不同的权衡。类适配器:1. 用一个具体的Adapter类对Adaptee和Target进行匹配。结果是当我们想要匹配一个类以及所有它的子类时,类Adapter将不能胜任工作。2. 使得Adapter可以重定义Adaptee的部分希望,因为Adapter是Adaptee的一个子类。3. 仅仅引入了一个对象,并不需要额外的指针以间接得到Adaptee.对象适配器则:1. 允许一个Adapter与多个Adaptee即Adaptee本身以及它的所有子类同时工作。Adapter也可以一次给所有的Adaptee添加功能。2. 使得重定义Adaptee的希望比较困难。这就需要生成Adaptee的子类并且使得Adapter引用这个子类而不是引用Adaptee本身。使用Adapter模式时需要考虑的其他一些因素有:1. Adapter的匹配程度。Adapter的工作量取决于Target接口与Adaptee接口的相似程度。2. 可插入的Adapter。3. 使用双向适配器通过透明操作。使用适配器的一个潜在问题是,它们不对所有的客户都透明。被适配的对象不再兼容Adaptee的接口,因此并不是所有Adaptee对象可以被使用的地方它都可以被使用。双向适配器提供了这样的透明性。在两个同步的客户需要用不同的方法查看同一个对象时,双向适配器尤其有用。优点: 使用对象组合 以修改的接口包装被适配者 被适配者的任何子类都可以搭配着适配器使用 这个模式将客户和接口绑定起来,而不是和实现绑定起来类的Adapter模式通常是通过继承机制来实现,而对象Adapter模式则是使用聚合对象来实现,两者都有优的一面也有劣的一面。详细这里就不多说,给出一句前辈留下的原则大家一起学习“优先使用组合而非继承”。8.1.9 实现尽管Adapter模式的实现方式通常简单直接,但是仍需要注意以下一些问题:1. 使用C+实现适配器类。 在使用C+实现适配器类时,Adapter类应该采用公共方式继承Target类,并且用私有方式继承Adaptee类。因此,Adapter类应该是Target的子类型,但不是Adaptee的子类型。2. 可插入的适配器。 首先为Adaptee找到一个窄接口,即可用于适配的最小操作集。对于这个窄接口,有以下三个实现途径:l 使用抽象操作。l 使用代理对象。l 参数化的适配器。8.1.10 代码示例对于动机一节中例子,从类Shape和TextView开始,给出类适配器和对象适配器实现代码的简要框架。Class ShapePublic:Shape( );Virtual void BoundingBox( Point & bottomLeft, Point & topRight ) const;/有一个边框,由它相对的两角定义Virtual Manipulator * CreateManipulator ( ) const;/创建一个Manipulator对象,当用户操作一个图形时,Manipulator对象知道如何驱动这个图形;Class TextView/边框由原点和宽度、高度定义。Public:TextView( );Void GetOrigin(Coord & x, Coord & y) const;/原点Void GetExtent( Coord & width, Coord & height ) const;/宽度,高度Virtal bool IsEmpty( ) const;TextShape类是这些不同接口间的适配器。类适配器采用多重继承适配接口。类适配器的关键是用一个分支继承接口,而用另外一个分支继承接口的实现部分。通常C+中作出这一区分的方法是:用公共方式继承接口,用私有方式继承接口的实现。下面按照这种常规方法定义TextShape适配器。Class TextShape: public Shape, private TextView Public:TextShape( );Virtual void BoundingBox( Point & bottomLeft, Point & topRight ) const;Virtual bool IsEmpty ( ) const;Virtual Manipulator * CreateManipulator ( ) const;BoundingBox操作对TextView的接口进行转换使之匹配 Shape的接口。void TextShape : : BoundingBox( Point & bottomLeft, Point & topRight ) constShape的接口Coord bottom, left, width, height;GetOrigin(bottom, left);GetExtent(width, height);TextView的接口bottomLeft = Point (bottom, left); topRight = Point(bottom+ height, left+ width);IsEmpty操作给出了在适配器实现过程中常用的一种方法:直接转发请求。bool TextShape : IsEmpty ( ) constreturn TextView: IsEmpty ( );最后,我们定义CreateManipulator(TextView不支持该操作),假定我们已经实现了支持TextShape操作的类TextManipulator,类TextManipulator是类Manipulator的子类。Manipulator * TextShape : CreateManipulator ( ) const/ 是工厂方法的一个实例return new TextManipulator ( this );对象适配器采用对象组合的方法将具有不同接口的类组合在一起。在该方法中,适配器TextShape维护一个指向TextView的指针。Class TextShape: public Shape Public:TextShape(TextView* );Virtual void BoundingBox( Point & bottomLeft, Point & topRight ) const;Virtual bool IsEmpty ( ) const;Virtual Manipulator * CreateManipulator ( ) const;Private:TextView * _text;TextShape必须在构造器中对指向TextView实例的指针进行初始化,当它自身的操作被调用时,它还必须对它的TextView对象调用相应的操作。在本例子中,假设客户创建了TextView对象并且将其传递给TextShape的构造器。即在客户的应用程序中有:TextView TextV;Adaptee对象适配器类TextShape TextS;TextV=new TextView;/当需要TextView类的子类与TextShape一起工作时,只需要修改此语句被继承的接口。TextS=new TextShape(TextV);Point* bottomLeft, topRight;TextS. BoundingBox(bottomLeft, topRight);适配器在TextShape的构造器中有:TextShape:TextShape(TextView* t )_text=t;TextShape的BoundingBox操作有:void TextShape : : BoundingBox( Point & bottomLeft, Point & topRight ) constShape的接口Coord bottom, left, width, height;_text -GetOrigin(bottom, left);_text -GetExtent(width, height);TextView的接口bottomLeft = Point (bottom, left); topRight = Point(bottom+ height, left+ width);bool TextShape : IsEmpty ( ) constreturn _text -IsEmpty ( );CreateManipulator的实现代码与类适配器版本的实现代码一样,因为它的实现从零开始,没有复用任何TextView已有的函数。Manipulator * TextShape : CreateManipulator ( ) const/ 是工厂方法的一个实例return new TextManipulator ( this );将这段代码与类适配器的相应代码进行比较,可以看出编写对象适配器代码相对麻烦一些,但是比较灵活。例如,客户仅需将TextView类的子类的一个实例传递给TextShape的构造函数中,对象适配器版本的TextShape就同样可以与TextView类的子类一起很好的工作。8.1.11 已知应用8.1.12 相关模式模式Bridge的结构与对象适配器类似,但是Bridge模式的出发点不同:Bridge目的是将接口部分和实现部分分离,从而对它们可以较为容易也相对独立的加以改变。而Adapter则意味着改变一个已有对象的接口。Decorator模式增强了其它对象的功能而同时又不改变它的接口。因此decorator对应用程序的透明性比适配器要好。结果是decorator支持递归组合,而纯粹使用适配器是不可能实现这一点的。Proxy在不改变它的接口的条件下,为另一个对象定义了一个代理。8.1.13 练习1./ Adapter pattern - Real World example using System;namespace DoFactory.GangOfFour.Adapter.RealWorld/ / MainApp startup class for Real-World / Adapter Design Pattern./ class MainApp/ / Entry point into console application./ static void Main()/ Non-adapted chemical compoundCompound unknown = new Compound(Unknown);unknown.Display();/ Adapted chemical compoundsCompound water = new RichCompound(Water);water.Display();Compound benzene = new RichCompound(Benzene);benzene.Display();Compound ethanol = new RichCompound(Ethanol);ethanol.Display();/ Wait for userConsole.ReadKey();/ / The Target class/ class Compoundprotected string _chemical;protected float _boilingPoint;protected float _meltingPoint;protected double _molecularWeight;protected string _molecularFormula;/ Constructorpublic Compound(string chemical)this._chemical = chemical;public virtual void Display()Console.WriteLine(nCompound: 0 - , _chemical);适配器/ / The Adapter class/ class RichCompound : Compoundprivate ChemicalDatabank _bank;/ Constructorpublic RichCompound(string name): base(name)public override void Display()/ The Adaptee_bank = new ChemicalDatabank();_boilingPoint = _bank.GetCriticalPoint(_chemical, B);_meltingPoint = _bank.GetCriticalPoint(_chemical, M);_molecularWeight = _bank.GetMolecularWeight(_chemical);_molecularFormula = _bank.GetMolecularStructure(_chemical);base.Display();Console.WriteLine( Formula: 0, _molecularFormula);Console.WriteLine( Weight : 0, _molecularWeight);Console.WriteLine( Melting Pt: 0, _meltingPoint);Console.WriteLine( Boiling Pt: 0, _boilingPoint);/ / The Adaptee class/ class ChemicalDatabank/ The databank legacy APIpublic float GetCriticalPoint(string compound, string point)/ Melting Pointif (point = M)switch (compound.ToLower()case water: return 0.0f;case benzene: return 5.5f;case ethanol: return -114.1f;default: return 0f;/ Boiling Pointelseswitch (compound.ToLower()case water: return 100.0f;case benzene: return 80.1f;case ethanol: return 78.3f;default: return 0f;public string GetMolecularStructure(string compound)switch (compound.ToLower()case water: return H20;case benzene: return C6H6;case ethanol: return C2H5OH;default: return ;public double GetMolecularWeight(string compound)switch (compound.ToLower()case water: return 18.015;case benzene: return 78.1134;case ethanol: return 46.0688;default: return 0d;OutputCompound: Unknown -Compound: Water -Formula: H20Weight : 18.015Melting Pt: 0Boiling Pt: 100Compound: Benzene -Formula: C6H6Weight : 78.1134Melting Pt: 5.5Boiling Pt: 80.1Compound: Alcohol -Formula: C2H6O2Weight : 46.0688Melting Pt: -114.1Boiling Pt: 78.32. 我们来看看一个很不精确的例子(这是在一位前辈的Blog留言中检到的,具体不记不清楚了),如虎添翼是怎么实现的呢?示意性代码如下:会飞的麻雀1namespace DesignPattern.Adapter.FlyingTigers23/*/ 4/ 麻雀会飞5/ 6public class Sparrow78private string name;9public string Name1011get return name; 12set name = value; 1314public Sparrow() 15public Sparrow(string name)1617 = name;181920public void Fly()2122Console.WriteLine(我是0,我能飞!, this.Name);232425老虎接口1namespace DesignPattern.Adapter.FlyingTigers23/*/ 4/ 老虎接口5/ 6public interface ITiger78void Eat();910有了一个麻雀的飞行(Fly)接口存在,而现在系统提供的却是一个老虎接口(ITiger-Eat(),如何才能让这两个不匹配的接口能够在一起工作呢?此时,我们就引入Adapter模式(本示例中采用的是类Adapter模式)。这是飞天虎吗?1namespace DesignPattern.Adapter.FlyingTigers23/带点多继承的味道-是好?是坏?4public class FlyTiger:Sparrow,ITiger56public FlyTiger() 7public FlyTiger(string name)89base.Name = name;101112public void Eat()1314base.Fly();15Console.WriteLine(我是0,我能吃!, base.Name);161718上面的如虎添翼是这样的吗?其实这就是一个类Adapter模式的UML草图,客户端(Client)角色:.Client Code1namespace DesignPattern.Adapter.FlyingTigers23class Program45static void Main(string args)67/如果是麻雀,麻雀是能飞的.8new Sparrow(麻雀).Fly();910/如果是使用了Adapter的老虎呢?呵呵,能飞能吃,飞天虎吗?11ITiger it = new FlyTiger(老虎);12it.Eat();1314153. Adapter模式分为类Adapter模式和对象的Adapter模式,至于两者到底该怎么用,什么情况下用什么类型的模式,这还需根据实习的需求而定,如上所说这两种模式的实现机制,在上一个不精确的例子中使用了类的Adapter模式,接下来在让麻雀变凤凰的故事里我们就以对象Adapter模式的方式来实现。代码如下:凤凰-源(Adaptee)角色:需要适配的类。1namespace DesignPattern.Adapter.SparrowPhoenix23/*/ 4/ 凤凰-源(Adaptee)角色:需要适配的类。5/ 6public class Phoenix78public void Display()910Console.WriteLine(我是美丽的凤凰,也有人叫我火鸟,是吉祥托车南笳鳌?quot;);111213目标(Target)角色:这是客户所期待的接口。1namespace DesignPattern.Adapter.SparrowPhoenix23/*/ 4/ 目标(Target)角色:这是客户所期待的接口。5/ 目标可以是具体的或抽象的类,也可以是接口。6/ 7public interface ISparrowPhoenix89void Show();1011麻雀-适配器(Adapter)角色,聚合一个凤凰(Phoenix).1namespace DesignPattern.Adapter.SparrowPhoenix23/*/ 4/ 麻雀-适配器(Adapter)角色,聚合一个凤凰(Phoenix).5/ 通过在内部包装(Wrap)一个Adaptee(源对象)对象,把源接口转换成目标接口.6/ 7public class Sparrow:ISparrowPhoenix89private Phoenix phoenix = new Phoenix();10public void Show()1112phoenix.Display();1314151namespace DesignPattern.Adapter.SparrowPhoenix23class Program45static void Main(string args)67ISparrowPhoenix isp = new Sparrow();8isp.Show();/麻雀变凤凰了?91011121314运行结果:我是美丽的凤凰,也有人叫我火鸟,是吉祥和谐的象征。麻雀变凤凰(对象Adapter模式)的UML草图:呵呵,原本丑陋的麻雀,通过了Adapter的包装,将其改装为了凤凰的血统,神奇了,他还真变成了凤凰勒。现在我们可回头去仔细分析下,给老虎加入了翅膀,他真的变飞虎了吗?给麻雀换上凤凰的血液,麻雀真的变凤凰了吗?8.2 组合模式(COMPOSITE) 对象结构型模式8.2.1 意图将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。8.2.2 别名8.2.3 动机在绘图编辑器和图形捕捉系统这样的图形应用程序中,用户可以使用简单的组件创建复杂的图表。用户可以组合多个简单组件以形成一些较大的组件,这些组件又可以组合成更大的组件。一个简单的实现方法是为Text和Line这样的图元定义一些类,另外定义一些类作为这些图元的容器类(Container)。然而这种方法存在一个问题:使用这些类的代码必须区别对待图元对象与容器对象,而实际上大多数情况下用户认为它们是一样的。对这些类区别使用,使得程序更加复杂。Composite模式描述了如何使用递归组合,使得用户不必对这些类进行区别。Composite 模式的关键是一个抽象类,它既可以代表图元,又可以代表图元的容器。在图形系统中的这个类就是Graphic,它声明一些与特定图形对象相关的操作,例如Draw。同时它也声明了所有的组合对象共享的一些操作,例如一些操作用于访问和管理它的子部件。子类Line、Rectangle和Text定义了一些图元对象,这些类实现Dr
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 炼焦工知识考核试卷及答案
- 水声换能器密封工专业知识考核试卷及答案
- 纺织印染废水零排放处理技术方案
- 农业土壤重金属污染治理方案
- 初级财务人员账务处理操作规范
- 校企合作实践教学方案设计与总结
- 办公自动化软件应用培训指南
- 三年级语文标点符号专项练习指导
- 弱电系统安全施工操作规范
- 施工安全知识考试题库大全
- GB/T 4745-2012纺织品防水性能的检测和评价沾水法
- 神经调节的基本方式练习题(含答案)
- GB/T 10609.3-1989技术制图复制图的折叠方法
- 钢结构基本原理及设计PPT全套课件
- 教师节课件模板
- 初中课外阅读指导课-课件
- 房建满堂脚手架专项验算书
- 全科医学的基本原则和特点课件
- 国家综合性消防救援队伍消防员管理规定
- 《非线性动力学》课程教学大纲
- 北京工业地产工业园区调研报告
评论
0/150
提交评论