迅闻网
让更多人看到你

java设计模式有几种(工厂设计模式java)

  java设计模式有几种

分别为:笼统工厂形式、制作形式、工厂办法形式、原型形式、单例形式、外观形式、适配器形式、桥接形式、组合形式、装修形式、享元形式、署理形式、指令形式、解说器形式、拜访者形式、迭代子形式、中介者形式、备忘录形式、观察者形式、状况形式、战略形式、模板办法形式、职责链形式。
1、笼统工厂形式是供给一个接口,用于创立相关或许依靠目标的宗族,而不需要明确指定详细类。
2、制作形式是将一个复杂目标的构建与表明别离,使得同样的构建进程能够创立不同的表明。
3、工厂办法形式定义一个创立目标的接口,让子类决定实例化那个类。
4、原型形式是用原型实例指定创立目标的品种,而且经过复制这些原型创立新的目标。
5、单例形式,它的定义便是保证某一个类只有一个实例,而且供给一个大局拜访点。
6、外观形式供给了一个一致的接口,用来拜访子系统中的一群接口。
7、适配器形式是将一个类的接口,转化成客户希望的另一个接口。
8、桥接形式是讲笼统部分和实现部分阻隔开来,使得他们能够独立改动。
9、组合形式组合多个目标构成树形结构以表明“整体-部分”的结构层次。
10、装修形式:动态的给目标添加新的功能。
11、享元形式便是运行同享技术有效地支持大量细粒度目标的复用。
12、署理形式便是给一个目标供给一个署理,并由署理目标控制对原目标的引证。
13、指令形式将恳求封装成目标,以便使用不同的恳求、队列或许日志来参数化其他目标。
14、解说器形式便是定义语言的文法,而且建立一个解说器来解说该语言中的语句。
15、拜访者形式即在不改动数据结构的前提下,增加作用于一组目标元素的新功能。
16、迭代子形式是供给一种办法顺序拜访一个聚合目标中的各个元素,而不暴露其内部的表明。
17、中介者形式便是用一个中介目标来封装一系列的目标交互。
18、备忘录形式便是在不破坏封装的前提下,捕获一个目标的内部状况。
19、观察者形式定义了目标之间的一对多依靠联系。
20、状况形式便是允许目标在内部状况发生改动时改动它的行为。
21、战略形式便是定义了算法族,分别封装起来,让他们之前能够相互转化。
22、模板办法形式便是在一个办法中定义一个算法的骨架,而将一些过程延迟到子类中。
23、职责链形式是将恳求的发送者和接收者解耦,使的多个目标都有处理这个恳求的时机。

java

工厂设计模式java

一、规划形式的分类
总的来说,规划形式能够分为三大类:创立型形式、结构型形式、行为型形式,详细如下图:
二、工厂形式
工厂形式分为简略工厂形式、工厂办法形式和笼统工厂形式。其间简略工厂形式并不归于23种规划形式,但并不影响它的广泛运用。在JDK的源码当中,就存在着许多这样的比如。
2.1简略工厂形式
咱们先来看一段代码:
publicstaticvoidmain(String[]args){//日历类Calendarcalendar=Calendar.getInstance();SimpleDateFormatsimpleDateFormat=newSimpleDateFormat(“yyyy-MM-ddHH:mm:ss”);System.out.println(“当时时刻为:”+simpleDateFormat.format(calendar.getTime()));calendar.add(Calendar.HOUR,2);System.out.println(“当时时刻加了两个小时后,时刻是:”+simpleDateFormat.format(calendar.getTime()));}
这段代码,咱们应该比较了解,经过对Calendar的一系列操作,打印出当时时刻和当时时刻加两个小时后的时刻,这儿咱们来看看成果:
成果正和咱们幻想的相同,两次打印出来的时刻相隔两个小时。但咱们今天的重点是Calendarcalendar=Calendar.getInstance()这段代码,经过getInstance()办法拿到了Calendar类的实例。来看看详细的源代码:
publicstaticCalendargetInstance(){returncreateCalendar(TimeZone.getDefault(),Locale.getDefault(Locale.Category.FORMAT));}//代码不全,有兴趣的朋友能够去看JDK源码privatestaticCalendarcreateCalendar(TimeZonezone,LocaleaLocale){//中心的代码省掉…..Calendarcal=null;if(aLocale.hasExtensions()){Stringcaltype=aLocale.getUnicodeLocaleType(“ca”);if(caltype!=null){switch(caltype){case”buddhist”:cal=newBuddhistCalendar(zone,aLocale);break;case”japanese”:cal=newJapaneseImperialCalendar(zone,aLocale);break;case”gregory”:cal=newGregorianCalendar(zone,aLocale);break;}}}//中心的代码省掉…..returncal;}
能够看出,getInstance()办法里边调用了createCalendar()办法来得到Calendar类的实例,最后回来给调用者。而createCalendar()办法中经过switch(){case}的判别来回来所对应的Calendar类的实例,这其实便是简略工厂形式的一种应用。
看完简略工厂形式在JDK中的应用之后,咱们来规划一下自己的比如:
小明家新开了一家小工厂,接了一单生意,帮助海尔(Haier)集团出产冰箱,并需求规划相应的计划。小明自身也是程序员出身,考虑一会后就写出了下面的代码:
/***冰箱*/publicinterfaceIFridge{//出产冰箱publicvoidcreateFridge();}
/***海尔*/publicclassHaierimplementsIFridge{@OverridepublicvoidcreateFridge(){System.out.println(“出产海尔冰箱…”);}}
客户端调用代码:
publicstaticvoidmain(String[]args){IFridgeiFridge=newHaier();iFridge.createFridge();}
看上面的代码,父类IFridge类指向子类Haier类的引用,应用层需求依赖于Haier。假如事务扩展,后续增加格力(Gree)甚至更多,那么客户端这儿的代码会越来越臃肿。所以,咱们要想办法将这种依赖削弱,将创立IFridge目标的细节躲藏掉。咱们用简略工厂形式优化一下:
创立Gree格力类
/***格力*/publicclassGreeimplementsIFridge{@OverridepublicvoidcreateFridge(){System.out.println(“出产格力冰箱…”);}}
创立FridgeFactory工厂类
/***冰箱工厂*/publicclassFridgeFactory{//创立对应的IFridge实例publicstaticIFridgecreateFridge(Stringname){if(“haier”.equals(name)){returnnewHaier();}elseif(“gree”.equals(name)){returnnewGree();}returnnull;}}
修正客户端调用的代码:
publicstaticvoidmain(String[]args){//海尔IFridgehaier=FridgeFactory.createFridge(“haier”);haier.createFridge();//格力IFridgegree=FridgeFactory.createFridge(“gree”);gree.createFridge();}
这样来看,虽然代码多了,但维护起来以及扩展起来就便利很多,来看一看类图:
当然,上面的FridgeFactory代码中仍旧有些问题,假如咱们需求增加出产美的(Midea)冰箱,那么咱们就需求去修正createFridge()办法的代码,明显违反了开闭准则,咱们来改造一下:
修正FridgeFactory工厂类
/***冰箱工厂*/publicclassFridgeFactory{//创立对应的IFridge实例publicstaticIFridgecreateFridge(StringclassName){try{if(null!=className&&!””.equals(className)){//反射return(IFridge)Class.forName(className).newInstance();}}catch(Exceptione){e.printStackTrace();}returnnull;}}
修正客户端调用的代码
publicstaticvoidmain(String[]args){//com.xxx.Haier换成自己项目中Haier所在的位置海尔IFridgehaier=FridgeFactory.createFridge(“com.xxx.Haier”);haier.createFridge();//com.xxx.Gree换成自己项目中Gree所在的位置格力IFridgegree=FridgeFactory.createFridge(“com.xxx.Gree”);gree.createFridge();}
优化之后,咱们再也不需求跟着事务的提高而去修正FridgeFactory类中的代码了。但是仍旧有一个问题,createFridge()办法中的参数是字符串,假如有人乱填怎么办,那不就报错了,所以再来优化一下:
修正FridgeFactory工厂类
/***冰箱工厂*/publicclassFridgeFactory{//创立对应的IFridge实例publicstaticIFridgecreateFridge(Classclazz){try{if(clazz!=null){returnclazz.newInstance();}}catch(Exceptione){e.printStackTrace();}returnnull;}}
修正客户端调用的代码
publicstaticvoidmain(String[]args){//海尔FridgeFactory.createFridge(Haier.class).createFridge();//格力FridgeFactory.createFridge(Gree.class).createFridge();}
再来看一下类图:
简略工厂形式虽然好用,但也有它的局限性:工厂类的责任过重,不利于扩展更为杂乱产品结构。
2.2工厂办法形式
界说一个创立目标的接口,但让完成这个接口的类来决定实例化哪个类,工厂办法让类的实例化推迟到子类中进行。
在工厂办法形式中用户只需求关心所需产品对应的工厂,无须关心创立细节,而且参加新的产品契合开闭准则。
跟着小明家新工厂的生意火爆,各类的订单都纷涌而至,各个牌子的厂家都想让小明家的工厂出产冰箱,小明无法只能开了分工厂,并依据客户的品牌名给工厂取了对应的姓名,其间海尔工厂出产海尔的冰箱,格力工厂出产格力的冰箱,美的工厂出产美的的冰箱。用代码演化便是下面这般:
IFridgeFactory类接口
publicinterfaceIFridgeFactory{publicIFridgecreateIFridge();}
海尔
//海尔工厂publicclassHaierFactoryimplementsIFridgeFactory{@OverridepublicIFridgecreateIFridge(){returnnewHaier();}}
格力
//格力工厂publicclassGreeFactoryimplementsIFridgeFactory{@OverridepublicIFridgecreateIFridge(){returnnewGree();}}
美的
/***美的*/publicclassMideaimplementsIFridge{@OverridepublicvoidcreateFridge(){System.out.println(“出产美的冰箱…”);}}
//美的publicclassMideaFactoryimplementsIFridgeFactory{@OverridepublicIFridgecreateIFridge(){returnnewMidea();}}
客户端调用:
publicstaticvoidmain(String[]args){//格力newGreeFactory().createIFridge().createFridge();//海尔newHaierFactory().createIFridge().createFridge();//美的newMideaFactory().createIFridge().createFridge();}
这儿其实便是细化了工厂,将事务拆分,利用了规划形式准则中的单一责任准则,让每个品牌对应工厂只干一件事,不去掺和其他品牌的事情。来看一看类图:
工厂办法形式适用于一下场景:
创立目标需求大量重复的代码
客户端(应用层)不依赖于产品类实例怎么被创立、完成等细节
一个类经过其子类来指定创立哪个目标
工厂办法形式也有缺点:
类的个数简单过多,增加杂乱度
增加了体系的笼统性和了解难度
2.3笼统工厂形式
界说:提供一个创立一系列相关或许相互依赖目标的接口,无需指定他们详细的类。
这个界说读起来相当的拗口,很笼统,不好了解。还是和上面的比如结合来阐明:
在出产完一批冰箱并上市售卖之后,美的、格力、海尔等公司非常满足,慢慢的将自己家的空调、热水器也交给小明家的工厂去出产了。小明为此在对应的品牌工厂有拓荒了对应的出产设备的空间(这儿为了咱们看的便利,我将一切的代码都放上去):
冰箱、空调、热水器接口
//冰箱publicinterfaceIFridge{//出产冰箱publicvoidcreateFridge();}//空调publicinterfaceIAirConditioner{//出产空调publicvoidcreateAirConditioner();}//热水器publicinterfaceIWaterHeater{//出产热水器publicvoidcreateWaterHeater();}
海尔
/***海尔冰箱*/publicclassHaierFridgeimplementsIFridge{@OverridepublicvoidcreateFridge(){System.out.println(“出产海尔冰箱…”);}}//海尔空调publicclassHaierAirConditionerimplementsIAirConditioner{@OverridepublicvoidcreateAirConditioner(){System.out.println(“出产海尔空调…”);}}//海尔热水器publicclassHaierWaterHeaterimplementsIWaterHeater{@OverridepublicvoidcreateWaterHeater(){System.out.println(“出产海尔热水器…”);}}
格力
/***格力冰箱*/publicclassGreeFridgeimplementsIFridge{@OverridepublicvoidcreateFridge(){System.out.println(“出产格力冰箱…”);}}//格力空调publicclassGreeAirConditionerimplementsIAirConditioner{@OverridepublicvoidcreateAirConditioner(){System.out.println(“出产格力空调…”);}}//格力热水器publicclassGreeWaterHeaterimplementsIWaterHeater{@OverridepublicvoidcreateWaterHeater(){System.out.println(“出产格力热水器…”);}}
美的
/***美的冰箱*/publicclassMideaFridgeimplementsIFridge{@OverridepublicvoidcreateFridge(){System.out.println(“出产美的冰箱…”);}}//美的空调publicclassMideaAirConditionerimplementsIAirConditioner{@OverridepublicvoidcreateAirConditioner(){System.out.println(“出产美的空调…”);}}//美的热水器publicclassMideaWaterHeaterimplementsIWaterHeater{@OverridepublicvoidcreateWaterHeater(){System.out.println(“出产美的热水器…”);}}
工厂接口
12345678publicinterfaceIFactory{//冰箱publicIFridgecreateIFridge();//空调publicIAirConditionercreateIConditioner();//热水器publicIWaterHeatercreateIWaterHeater();}
海尔工厂
//海尔工厂publicclassHaierFactoryimplementsIFactory{//冰箱@OverridepublicIFridgecreateIFridge(){returnnewHaierFridge();}//空调@OverridepublicIAirConditionercreateIConditioner(){returnnewHaierAirConditioner();}//热水器@OverridepublicIWaterHeatercreateIWaterHeater(){returnnewHaierWaterHeater();}}
格力工厂
//格力publicclassGreeFactoryimplementsIFactory{//冰箱@OverridepublicIFridgecreateIFridge(){returnnewGreeFridge();}//空调@OverridepublicIAirConditionercreateIConditioner(){returnnewGreeAirConditioner();}//热水器@OverridepublicIWaterHeatercreateIWaterHeater(){returnnewGreeWaterHeater();}}
美的工厂
publicclassMideaFactoryimplementsIFactory{//冰箱@OverridepublicIFridgecreateIFridge(){returnnewMideaFridge();}//空调@OverridepublicIAirConditionercreateIConditioner(){returnnewMideaAirConditioner();}//热水器@OverridepublicIWaterHeatercreateIWaterHeater(){returnnewMideaWaterHeater();}}
客户端调用
publicstaticvoidmain(String[]args){//海尔工厂HaierFactoryhaierFactory=newHaierFactory();haierFactory.createIFridge().createFridge();haierFactory.createIConditioner().createAirConditioner();haierFactory.createIWaterHeater().createWaterHeater();//格力工厂GreeFactorygreeFactory=newGreeFactory();greeFactory.createIFridge().createFridge();greeFactory.createIConditioner().createAirConditioner();greeFactory.createIWaterHeater().createWaterHeater();//美的工厂MideaFactorymideaFactory=newMideaFactory();mideaFactory.createIFridge().createFridge();mideaFactory.createIConditioner().createAirConditioner();mideaFactory.createIWaterHeater().createWaterHeater();}
类图
从上面一大堆的代码,尤其是类图,咱们能够很明显的感觉到,笼统工厂能够完美清晰的描绘海尔、格力、美的三个品牌的冰箱、空调、热水器的巨大体系。但也正因为如此,笼统工厂给咱们的视觉冲击有些大,能很明显的感觉到体系的杂乱性、笼统性以及体系的极难扩展性;而且这儿还躲藏着一个违反开闭准则的问题:
在工厂接口IFactory类中,假如在日后的产品升级当中,需求增加出产洗衣机的事务,那这儿修正之后,一切完成IFactory接口的类都需求变化,很大程度增加了体系的不稳定性。
也正因为如此,在实践的事务开发中,咱们不应该有着激烈的强迫症和洁癖,认为一个体系的结构规划必须要完美的契合各种准则。要结合实践的事务去考虑,假如体系结构的等级更新不频繁的话,不遵守某些准则也是有必要性的,究竟一切的技术都是为事务而服务的。

未经允许不得转载:迅闻网 » java设计模式有几种(工厂设计模式java)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

迅闻网-让更多人看到你

登录/注册返回首页