??xml version="1.0" encoding="utf-8" standalone="yes"?> cdQ?/strong>创徏cL?/p> cdQ?/strong> 抽象工厂模式与工厂方法模式的区别 抽象工厂模式是工厂方法模式的升版本Q他用来创徏一l相x者相互依赖的对象。他与工厂方法模式的区别在于,工厂Ҏ模式针对的是一个品等U结构;而抽象工厂模式则是针对的多个产品{l构。在~程中,通常一个品结构,表现Z个接口或者抽象类Q也是_工厂Ҏ模式提供的所有品都是衍生自同一个接口或抽象c,而抽象工厂模式所提供的品则是衍生自不同的接口或抽象cR?/p> 在抽象工厂模式中Q有一?strong>产品?/strong>的概念:所谓的产品族,是指位于不同产品{l构中功能相兌的品组成的家族。抽象工厂模式所提供的一pd产品q成一个品族Q而工厂方法提供的一pd产品UCؓ一个等U结构。我们依然拿生汽R的例子来说明他们之间的区别?/p> 在上面的cd中,两厢车和三厢车称Z个不同的{l构Q?.0排量车和2.4排量车则UCؓ两个不同的品族。再具体一点,2.0排量两厢车和2.4排量两厢车属于同一个等U结构,2.0排量三厢车和2.4排量三厢车属于另一个等U结构;?.0排量两厢车和2.0排量三厢车属于同一个品族Q?.4排量两厢车和2.4排量三厢车属于另一个品族?/p> 明白了等U结构和产品族的概念Q就理解工厂Ҏ模式和抽象工厂模式的区别了,如果工厂的品全部属于同一个等U结构,则属于工厂方法模式;如果工厂的品来自多个等U结构,则属于抽象工厂模式。在本例中,如果一个工厂模式提?.0排量两厢车和2.4排量两厢车,那么他属于工厂方法模式;如果一个工厂模式是提供2.4排量两厢车和2.4排量三厢车两个品,那么q个工厂模式是抽象工厂模式Q因Z提供的品是分属两个不同的等U结构。当Ӟ如果一个工厂提供全部四UR型的产品Q因Z品分属两个等U结构,他当然也属于抽象工厂模式了?/p> 抽象工厂模式代码 抽象工厂模式的优?/strong> 抽象工厂模式除了h工厂Ҏ模式的优点外Q最主要的优点就是可以在cȝ内部对品族q行U束。所谓的产品族,一般或多或的都存在一定的兌Q抽象工厂模式就可以在类内部对品族的关联关p进行定义和描述Q而不必专门引入一个新的类来进行管理?/p> 抽象工厂模式的缺?/strong> 产品族的扩展是一件十分费力的事情Q假如品族中需要增加一个新的品,则几乎所有的工厂c都需要进行修攏V所以用抽象工厂模式时Q对产品{l构的划分是非常重要的?/p> 适用场景 当需要创建的对象是一pd怺兌或相互依赖的产品族时Q便可以使用抽象工厂模式。说的更明白一点,是一个承体pMQ如果存在着多个{l构Q即存在着多个抽象c)Qƈ且分属各个等U结构中的实现类之间存在着一定的兌或者约束,可以用抽象工厂模式。假如各个等U结构中的实现类之间不存在关联或U束Q则使用多个独立的工厂来对品进行创建,则更合适一炏V?/p> ȝ 无论是简单工厂模式,工厂Ҏ模式Q还是抽象工厂模式,他们都属于工厂模式,在Ş式和特点上也是极为相似的Q他们的最l目的都是ؓ了解耦。在使用Ӟ我们不必d意这个模式到底工厂方法模式还是抽象工厂模式,因ؓ他们之间的演变常常是令h琢磨不透的。经怽会发玎ͼ明明使用的工厂方法模式,当新需求来_E加修改Q加入了一个新Ҏ后,׃cM的品构成了不同{l构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减一个方法的提供的产品不再构成产品族之后,它就演变成了工厂Ҏ模式?/p> 所以,在用工厂模式时Q只需要关心降低耦合度的目的是否辑ֈ了?/p> cdQ?/strong>创徏cL?/p> cdQ?/strong> 工厂Ҏ模式代码 工厂模式Q?/strong> 首先需要说一下工厂模式。工厂模式根据抽象程度的不同分ؓ三种Q简单工厂模式(也叫静态工厂模式)、本文所讲述?strong>工厂Ҏ模式 工厂Ҏ模式Q?/strong> 通过工厂Ҏ模式的类囑֏以看刎ͼ工厂Ҏ模式有四个要素: 前文提到的简单工厂模式跟工厂Ҏ模式极ؓ怼Q区别是Q简单工厂只有三个要素,他没有工厂接口,q且得到产品的方法一般是静态的。因为没有工厂接口,所以在工厂实现的扩展性方面稍弱,可以所工厂Ҏ模式的简化版Q关于简单工厂模式,在此一W带q?/p> 适用场景Q?/strong> 不管是简单工厂模式,工厂Ҏ模式q是抽象工厂模式Q他们具有类似的Ҏ,所以他们的适用场景也是cM的?/p> 首先Q作ZU创建类模式Q在M需要生?strong>复杂对象 其次Q工厂模式是一U典型的解耦模式,q米Ҏ则在工厂模式中表现的ؓ明显。假如调用者自q装品需要增加依赖关pLQ可以考虑使用工厂模式。将会大大降低对象之间的耦合度?/p> 再次Q由于工厂模式是依靠抽象架构的,它把实例化品的d交由实现cd成,扩展性比较好。也是_当需要系l有比较好的扩展性时Q可以考虑工厂模式Q不同的产品用不同的实现工厂来组装?/p> 典型应用 要说明工厂模式的优点Q可能没有比l装汽R更合适的例子了。场景是q样的:汽R由发动机、轮、底盘组成,现在需要组装一辆R交给调用者。假如不使用工厂模式Q代码如下: 使用工厂Ҏ后,调用端的耦合度大大降低了。ƈ且对于工厂来_是可以扩展的Q以后如果想l装其他的汽车,只需要再增加一个工厂类的实现就可以。无论是灉|性还是稳定性都得到了极大的提高?/p> cdQ?/strong>创徏cL?/p> cdQ?/strong> cd知识点: 1.cd分ؓ三部分,依次是类名、属性、方?/span> 2.?lt;<开头和?gt;>l尾的ؓ注释信息 3.修饰W?代表publicQ?代表privateQ?代表protectedQ什么都没有代表包可见?/span> 4.带下划线的属性或Ҏ代表是静态的?/span> 5.对类图中对象的关pM熟悉的朋友可以参考文章:设计模式中类的关p?/strong>?/span> 单例模式应该?3U设计模式中最单的一U模式了。它有以下几个要素: 单例模式Ҏ实例化对象时机的不同分ؓ两种Q一U是饿汉式单例,一U是懒汉式单例。饿汉式单例在单例类被加载时候,实例化一个对象交l自q引用Q而懒汉式在调用取得实例方法的时候才会实例化对象。代码如下: 饿汉式单?/strong> 懒汉式单?/strong> 单例模式的优点: 适用场景Q?/strong>׃单例模式的以上优点,所以是~程中用的比较多的一U设计模式。我ȝ了一下我所知道的适合使用单例模式的场景: 单例模式注意事项Q?/strong> 关于java中单例模式的一些争议: 单例模式的对象长旉不用会被jvm垃圾攉器收集吗 看到不少资料中说Q如果一个单例对象在内存中长久不用,会被jvm认ؓ是一个垃圾,在执行垃圾收集的时候会被清理掉。对此这个说法,W者持怀疑态度Q笔者本人的观点是:在hotspot虚拟?.6版本中,除非Zؓ地断开单例中静态引用到单例对象的联接,否则jvm垃圾攉器是不会回收单例对象的?/strong> 对于q个争议Q笔者单独写了一文章进行讨论,如果您有不同的观Ҏ者有q这斚w的经历请q入文章单例模式讨论:单例模式与垃圾收?/a>参与讨论?/p> 在一个jvm中会出现多个单例?/strong> 在分布式pȝ、多个类加蝲器、以及序列化的的情况下,会生多个单例,q一Ҏ无庸|疑的。那么在同一个jvm中,会不会生单例呢Q用单例提供的getInstance()Ҏ只能得到同一个单例,除非是用反方式,会得到新的单例。代码如?/p> q样Q每ơ运行都会生新的单例对象。所以运用单例模式时Q一定注意不要用反生新的单例对象?/p> 懒汉式单例线E安全吗 主要是网上的一些说法,懒汉式的单例模式是线E不安全的,即是在实例化对象的Ҏ上加synchronized关键字,也依然是危险的,但是W者经q编码测试,发现?strong>synchronized 单例模式只有饿汉式和懒汉式两U吗 饿汉式单例和懒汉式单例只是两U比较主和常用的单例模式方法,从理ZԌM可以实现一个类只有一个实例的设计模式Q都可以UCؓ单例模式?/p> 单例cd以被l承?/strong> 饿汉式单例和懒汉式单例由于构造方法是private的,所以他们都是不可承的Q但是其他很多单例模式是可以l承的,例如登记式单例?/p> 饿汉式单例好q是懒汉式单例好 在java中,饿汉式单例要优于懒汉式单例。C++中则一般用懒汉式单例?/p> 单例模式比较单,在此׃举例代码演示了?br /> Jvm的垃圑֛收机制到底会不会回收掉长旉不用的单例模式对象,q的是一个比较有争议性的问题。将q一部分内容单独成篇的目的也是ؓ了与q大博友q泛的讨Z下这个问题。ؓ了能让更多的人看到这文章,请各位博友看完文章之后,点一?#8220;?#8221;Q让本篇文章排名量的靠前。笔者在此谢q?/span> 讨论命题Q当一个单例的对象长久不用Ӟ会不会被jvm的垃圾收集机制回收?/span> 首先说一下ؓ什么会产生q一疑问Q笔者本人再此之前从来没有考虑q垃圑֛收对单例模式的媄响,直到dM一本书Q《设计模式之》秦L著。在书中提到在j2ee应用中,jvm垃圾回收机制会把长久不用的单例类对象当作垃圾Qƈ在cpuI闲的时候对其进行回收?/strong>之前读过的几本设计模式的书,包括《java与模式》,书中都没有提到jvm垃圾回收机制对单例的影响。ƈ且在工作q程中,也没有过单例对象被回收的l历Q加上工作中很多前辈曄告诫q笔者:量不要声明太多的静态属性,因ؓq些静态属性被加蝲后不会被释放。因此对jvm垃圾攉会回收单例对象这一说法持怀疑态度。渐渐地Q发现在同事中和|上的技术h员中Q对q一问题也基本上是鲜明的对立两派。那么到底jvm会不会回攉久不用的单例对象呢?/p> 对这一问题Q笔者本人的观点是:不会回收?/strong> 下面l出本h的测试代?/p> 本段E序的目的是模拟j2ee容器Q首先实例化单例c,q个单例cd6M内存Q然后程序进入死循环Q不断的创徏对象QDjvmq行垃圾回收Q然后观察垃圾收集信息,如果q行垃圾攉后,内存仍然大于6MQ则说明垃圾回收不会回收单例对象?/p> q行本程序用的虚拟机是hotspot虚拟机,也就是我们用的最多的java官方提供的虚拟机Q俗UjdkQ版本是jdk1.6.0_12 q行时vm arguments参数为:-verbose:gc -Xms20M -Xmx20MQ意思是每次jvmq行垃圾回收时显C内存信息,jvm的内存设为固?0M?/p> q行l果Q?/strong> …… [Full GC 18566K->6278K(20352K), 0.0101066 secs] [GC 18567K->18566K(20352K), 0.0001978 secs] [Full GC 18566K->6278K(20352K), 0.0088229 secs] …… 从运行结果中可以看到L6MI间没有被收集。因此,W者认为,臛_在hotspot虚拟ZQ垃圑֛收是不会回收单例对象的?/p> 后来查阅了一些相关的资料Qhotspot虚拟机的垃圾攉法使用Ҏ索算法。这个算法的基本思\是:对Q?#8220;z?#8221;的对象,一定能最l追溯到其存zd堆栈或静态存储区之中的引用。通过一pd名ؓ根(GC RootsQ的引用作ؓLQ从q些根开始搜索,l过一pd的\径,如果可以到达java堆中的对象,那么q个对象是“z?#8221;的,是不可回收的。可以作为根的对象有Q?/p> Ҏ区是jvm的一块内存区域,用来存放cȝ关的信息。很明显Qjava中单例模式创建的对象被自q中的静态属性所引用Q符合第二条Q因此,单例对象不会被jvm垃圾攉?/p> 虽然jvm堆中的单例对象不会被垃圾攉Q但是单例类本n如果长时间不用会不会被收集呢Q因为jvmҎ法区也是有垃圾收集机制的。如果单例类被收集,那么堆中的对象就会失d根的路径Q必然会被垃圾收集掉。对此,W者查阅了hotspot虚拟机对Ҏ区的垃圾攉ҎQjvm卸蝲cȝ判定条g如下Q?/p> 只有三个条g都满Ijvm才会在垃圾收集的时候卸载类。显Ӟ单例的类不满x件一Q因此单例类也不会被卸蝲。也是_只要单例cM的静态引用指向jvm堆中的单例对象,那么单例cd单例对象都不会被垃圾攉Q依据根搜烦法Q对象是否会被垃圾收集与未被使用旉长短无关Q仅仅在于这个对象是不是“z?#8221;的。假如一个对象长久未使用而被回收Q那么收集算法应该是最q最长未使用法Q最q最长未使用法一般用在操作系l的内外存交换中Q如果用在虚拟机垃圾回收中,岂不是太不安全了Q以上是W者的观点?/p> 因此W者的观点是:在hotspot虚拟?.6版本中,除非Zؓ地断开单例中静态引用到单例对象的联接,否则jvm垃圾攉器是不会回收单例对象的?/strong> 单工厂模式有一个问题就是,cȝ创徏依赖工厂c,也就是说Q如果想要拓展程序,必须对工厂类q行修改Q这q背了闭包原则,所以,从设计角度考虑Q有一定的问题Q如何解冻Iq到工厂方法模式,创徏一个工厂接口和创徏多个工厂实现c,q样一旦需要增加新的功能,直接增加新的工厂cd可以了,不需要修改之前的代码?/p> L例子Q?/p> 两个实现c: 两个工厂c: 在提供一个接口: 试c: 其实q个模式的好处就是,如果你现在想增加一个功能:发及时信息,则只需做一个实现类Q实现Sender接口Q同时做一个工厂类Q实现Provider接口Q就OK了,无需L动现成的代码。这样做Q拓展性较好! 工厂Ҏ模式和抽象工厂模式不好分清楚Q他们的区别如下Q?/p> 单工厂模式模式分ZU: 是建立一个工厂类Q对实现了同一接口的一些类q行实例的创建。首先看下关pdQ?/p> 举例如下Q(我们举一个发送邮件和短信的例子) 首先Q创Z者的共同接口Q?/p> 其次Q创建实现类Q?/p> 最后,建工厂类Q?/p> 我们来测试下Q?/p> 输出Qthis is sms sender! 是对普通工厂方法模式的改进Q在普通工厂方法模式中Q如果传递的字符串出错,则不能正创建对象,而多个工厂方法模式是提供多个工厂ҎQ分别创建对象。关pdQ?/p> 上面的代码做下修改Q改动下SendFactorycd行,如下Q?/p> 试cd下: 输出Qthis is mailsender! 上面的多个工厂Ҏ模式里的Ҏ|ؓ静态的Q不需要创建实例,直接调用卛_?/p> 输出Qthis is mailsender! M来说Q工厂模式适合Q凡是出C大量的品需要创建,q且h共同的接口时Q可以通过工厂Ҏ模式q行创徏。在以上的三U模式中Q第一U如果传入的字符串有误,不能正确创徏对象Q第三种相对于第二种Q不需要实例化工厂c,所以,大多数情况下Q我们会选用W三U?#8212;—静态工厂方法模式?/p>
]]>
可以看到Q调用者ؓ了组装汽车还需要另外实例化发动机、底盘和轮胎Q而这些汽车的lg是与调用者无关的Q严重违反了q米Ҏ则,耦合度太高。ƈ且非怸利于扩展。另外,本例中发动机、底盘和轮胎q是比较具体的,在实际应用中Q可能这些品的lg也都是抽象的Q调用者根本不知道怎样l装产品。假如用工厂方法的话,整个架构显得清C许多?/p>
单例模式与垃圑֛?/a>
]]>
]]>
]]>2、抽象工厂模?/h3>
工厂Ҏ模式Q?一个抽象品类Q可以派生出多个具体产品cR? 一个抽象工厂类Q可以派生出多个具体工厂cR? 每个具体工厂cd能创Z个具体品类的实例? 抽象工厂模式Q?多个抽象产品c,每个抽象产品cd以派生出多个具体产品cR? 一个抽象工厂类Q可以派生出多个具体工厂cR? 每个具体工厂cd以创建多个具体品类的实例,也就是创建的是一个品线下的多个产品? 区别Q?工厂Ҏ模式只有一个抽象品类Q而抽象工厂模式有多个? 工厂Ҏ模式的具体工厂类只能创徏一个具体品类的实例,而抽象工厂模式可以创建多个?/pre>
工厂Ҏ创徏 "一U? 产品Q他的着重点在于"怎么创徏"Q也是说如果你开发,你的大量代码很可能围l着q种产品的构造,初始化这些细节上面。也因ؓ如此Q类似的产品之间有很多可以复用的特征Q所以会和模版方法相随?nbsp;
抽象工厂需要创Z些列产品Q着重点在于"创徏哪些"产品上,也就是说Q如果你开发,你的主要d是划分不同差异的产品U,q且量保持每条产品U接口一_从而可以从同一个抽象工厂ѝ?/span>对于java来说Q你能见到的大部分抽象工厂模式都是这LQ?---它的里面是一堆工厂方法,每个工厂Ҏq回某种cd的对象? 比如说工厂可以生产鼠标和键盘。那么抽象工厂的实现c(它的某个具体子类Q的对象都可以生产鼠标和键盘Q但可能工厂A生的是|技的键盘和鼠标Q工厂B是微软的? q样A和B是工厂Q对应于抽象工厂Q?每个工厂生的鼠标和键盘是产品Q对应于工厂ҎQ? 用了工厂Ҏ模式Q你替换生成键盘的工厂方法,可以把键盘从罗技换到微Y。但是用了抽象工厂模式,你只要换家工厂,可以同时替换鼠标和键盘一套。如果你要的产品有几十个Q当然用抽象工厂模式一ơ替换全部最方便Q这个工厂会替你用相应的工厂ҎQ? 所以说抽象工厂像工厂Q而工厂方法则像是工厂的一U品生产线
]]>01、普?/em>
02、多个方?/em>
03、多个静态方?/em>
单工厂模式(Simple Factory PatternQ属于类的创新型模式Q又叫静态工厂方法模式(Static FactoryMethod PatternQ?是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类?/p>
单工厂模式的UML图:
单工厂模式中包含的角色及其相应的职责如下Q?/p>
工厂角色QCreatorQ:q是单工厂模式的核心Q由它负责创建所有的cȝ内部逻辑。当然工厂类必须能够被外界调用,创徏所需要的产品对象?/p>
抽象QProductQ品角Ԍ单工厂模式所创徏的所有对象的父类Q注意,q里的父cd以是接口也可以是抽象c,它负责描q所有实例所共有的公共接口?/p>
具体产品QConcrete ProductQ角Ԍ单工厂所创徏的具体实例对象,q些具体的品往往都拥有共同的父类?/p>
单工厂模式深入分?/strong>Q?/p> 单工厂模式解决的问题是如何去实例化一个合适的对象?/p> 单工厂模式的核心思想是Q有一个专门的cL负责创徏实例的过E?/p> 具体来说Q把产品看着是一pd的类的集合,q些cL由某个抽象类或者接口派生出来的一个对象树。而工厂类用来产生一个合适的对象来满_L要求?/p> 如果单工厂模式所涉及到的具体产品之间没有共同的逻辑Q那么我们就可以使用接口来扮演抽象品的角色Q如果具体品之间有功能的逻辑或,我们必Lq些共同的东西提取出来,攑֜一个抽象类中,然后让具体品承抽象类。ؓ实现更好复用的目的,共同的东西L应该抽象出来的?/p> 在实际的的用中Q抽闲品和具体产品之间往往是多层次的品结构,如下图所C: 单工厂模式用场景分析及代码实现Q?nbsp; GG误qx友和众多女吃饭Q但是GG自己是不会做饭的或者做的饭很不好,q说明GG不用自己d建各U食物的对象Q各个美女都有各自的爱好Q到麦当力_她们喜欢吃什么直接去点就行了Q麦当劳是生各种食物的工厂,q时候GG不用自己动手Q也可以误么多女吃饭Q所要做的就是买单O(∩_∩)O哈哈~,其UML囑֦下所C: 实现代码如下Q?/p> 新徏立一个食物的接口Q?/p> package com.diermeng.designPattern.SimpleFactory; /* * 产品的抽象接?/p> */ public interface Food { /* * 获得相应的食?/p> */ public void get(); } 接下来徏立具体的产品Q麦香鸡和薯?/p> package com.diermeng.designPattern.SimpleFactory.impl; import com.diermeng.designPattern.SimpleFactory.Food; /* * 麦香鸡对抽象产品接口的实?/p> */ public class McChicken implements Food{ /* * 获取一份麦香鸡 */ public void get(){ System.out.println("我要一份麦香鸡"); } } package com.diermeng.designPattern.SimpleFactory.impl; import com.diermeng.designPattern.SimpleFactory.Food; /* * 薯条Ҏ象品接口的实现 */ public class Chips implements Food{ /* * 获取一份薯?/p> */ public void get(){ System.out.println("我要一份薯?); } } 现在建立一个食物加工工厂: package com.diermeng.designPattern.SimpleFactory.impl; import com.diermeng.designPattern.SimpleFactory.Food; public class FoodFactory { public static Food getFood(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException { if(type.equalsIgnoreCase("mcchicken")) { return McChicken.class.newInstance(); } else if(type.equalsIgnoreCase("chips")) { return Chips.class.newInstance(); } else { System.out.println("哎呀Q找不到相应的实例化cdQ?); return null; } } } 最后我们徏立测试客LQ?/p> package com.diermeng.designPattern.SimpleFactory.client; import com.diermeng.designPattern.SimpleFactory.Food; import com.diermeng.designPattern.SimpleFactory.impl.FoodFactory; /* * 试客户?/p> */ public class SimpleFactoryTest { public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException { //实例化各U食?/p> Food mcChicken = FoodFactory.getFood("McChicken"); Food chips = FoodFactory.getFood("Chips"); Food eggs = FoodFactory.getFood("Eggs"); //获取食物 if(mcChicken!=null){ mcChicken.get(); } if(chips!=null){ chips.get(); } if(eggs!=null){ eggs.get(); } } } 输出的结果如下: 哎呀Q找不到相应的实例化cdQ?/p> 我要一份麦香鸡 我要一份薯?/p> 单工厂模式的优缺点分析: 优点Q工厂类是整个模式的关键所在。它包含必要的判断逻辑Q能够根据外界给定的信息Q决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类d建所需的实例,而无需了解q些对象是如何创Z及如何组l的。有利于整个软g体系l构的优化?/p> ~点Q由于工厂类集中了所有实例的创徏逻辑Q这q接导致一旦这个工厂出了问题,所有的客户端都会受到牵q;而且׃单工厂模式的产品室基于一个共同的抽象cL者接口,q样一来,但品的U类增加的时候,x不同的品接口或者抽象类的时候,工厂cd需要判断何时创ZU种cȝ产品Q这和创徏何种U类产品的品相互淆在了一Pq背了单一职责Q导致系lqzL和可维护性。而且更重要的是,单工厂模式违背了“开攑ְ闭原?#8221;Q就是违背了“pȝҎ展开放,对修改关?#8221;的原则,因ؓ当我新增加一个品的时候必M改工厂类Q相应的工厂cd需要重新编译一遍?/p> ȝ一下:单工厂模式分M品的创徏者和消费者,有利于Y件系l结构的优化Q但是由于一切逻辑都集中在一个工厂类中,D了没有很高的内聚性,同时也违背了“开攑ְ闭原?#8221;。另外,单工厂模式的Ҏ一般都是静态的Q而静态工厂方法是无法让子cȝ承的Q因此,单工厂模式无法Ş成基于基cȝl承树结构?/p> 单工厂模式的实际应用介: 作ؓ一个最基本和最单的设计模式Q简单工厂模式却有很非常q泛的应用,我们q里以Java中的JDBC操作数据库ؓ例来说明?/p> JDBC是SUN公司提供的一套数据库~程接口APIQ它利用Java语言提供单、一致的方式来访问各U关pd数据库。JavaE序通过JDBC可以执行SQL语句Q对获取的数据进行处理,q将变化了的数据存回数据库,因此QJDBC是Java应用E序与各U关pL据进行对话的一U机制。用JDBCq行数据库访问时Q要使用数据库厂商提供的驱动E序接口与数据库理pȝq行数据交互?/p> 客户端要使用使用数据Ӟ只需要和工厂q行交互卛_Q这导致操作步骤得到极大的化,操作步骤按照序依次为:注册q加载数据库驱动Q一般用Class.forName();创徏与数据库的链接Connection对象Q创建SQL语句对象preparedStatement(sql)Q提交SQL语句Q根据实际情况用executeQuery()或者executeUpdate()Q显C相应的l果Q关闭数据库?/p>
1. 泛化Q?/strong>GeneralizationQ?/strong>
【泛化关pR:是一U承关p,表示一般与Ҏ的关p,它指定了子类如何特化父类的所有特征和行ؓ。例如:老虎是动物的一U,x老虎的特性也有动物的共性?/p>
【箭头指向】:带三角箭头的实线Q箭头指向父c?/p>
2. 实现Q?/strong>RealizationQ?/strong>
【实现关pR:是一U类与接口的关系Q表C类是接口所有特征和行ؓ的实?
【箭头指向】:带三角箭头的虚线Q箭头指向接?/p>
3. 兌Q?/strong>Association)
【关联关pR:是一U拥有的关系Q它使一个类知道另一个类的属性和ҎQ如Q老师与学生,丈夫与妻子关联可以是双向的,也可以是单向的。双向的兌可以有两个箭头或者没有箭_单向的关联有一个箭头?/p>
【代码体现】:成员变量
【箭头及指向】:带普通箭头的实心U,指向被拥有?/p>
上图中,老师与学生是双向兌Q老师有多名学生,学生也可能有多名老师。但学生与某评间的关系为单向关联,一名学生可能要上多门课E,评是个抽象的东西他不拥有学生?nbsp;
下图w关联:
4. 聚合Q?/strong>AggregationQ?/strong>
【聚合关pR:是整体与部分的关p,且部分可以离开整体而单独存在。如车和轮胎是整体和部分的关p,轮胎d车仍然可以存在?/p>
聚合关系是关联关pȝ一U,是强的关联关p;兌和聚合在语法上无法区分,必须考察具体的逻辑关系?/p>
【代码体现】:成员变量
【箭头及指向】:带空心菱形的实心U,菱Ş指向整体
5. l合(Composition)
【组合关pR:是整体与部分的关p,但部分不能离开整体而单独存在。如公司和部门是整体和部分的关系Q没有公司就不存在部门?/p>
l合关系是关联关pȝ一U,是比聚合关系q要强的关系Q它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期?/p>
【代码体现】:成员变量
【箭头及指向】:带实心菱形的实线Q菱形指向整?/p>
6. 依赖(Dependency)
【依赖关pR:是一U用的关系Q即一个类的实现需要另一个类的协助,所以要量不用双向的互相依赖.
【代码表现】:局部变量、方法的参数或者对静态方法的调用
【箭头及指向】:带箭头的虚线Q指向被使用?/p>
各种关系的强弱顺序:
泛化 = 实现 > l合 > 聚合 > 兌 > 依赖
下面q张UML图,比较形象地展CZ各种cd关系Q?/p>