java抽象工厂模式的实现实例
简单工厂模式、工厂模式和抽象工厂模式区别及优缺点

简单⼯⼚模式、⼯⼚模式和抽象⼯⼚模式区别及优缺点各位⼩伙伴好,今天给⼤家主要介绍⼀下简单⼯⼚模式、⼯⼚模式和抽象⼯⼚模式的区别及各⾃的优缺点。
(本⽂实现语⾔为Python3)【前⾔】众所周知今天所讲的内容是设计模式的⼀类;对于设计模式这个概念,我想⾸先请⼤家问问⾃⼰:1、什么是设计模式 2、我们为什么要了解并学习设计模式?从我上学的时候我相信⼤家跟我⼀样也接触过设计模式的课程,当时可能懵懵懂懂只是知其然,当时还会想明明可以直接写出来为什么要搞成这样的形式,我就算学会了它到底什么时候能⽤呢?⼀系列的问题...Emm算了到时候再想想(lazy)。
随着实践的不断增多,现在我想可以对这些问题有个初步的回答了: 1、在我看来,设计模式外在看是经过前⼈不断实践总结出的针对某些指定场景极其好⽤的⼀种代码结构设计模板;内在看其实是⼀种设计思想(即为什么他们会这么想,这样想较之其他⽅法有什么好处)。
当我们真正的理解设计思想的时候,就可能会在⾯对问题和场景时⾃然⽽然的灵活运⽤到多种设计模式,⽽不是单⼀的刻板结构。
2、在⼯程化的开发中,需求往往是会不断变化的,这也是让很多开发⼈员及其烦躁的地⽅,所以才会有开发与产品的亲密关系。
设计模式就是为了抵御外部需求变化产⽣的。
设计模式应符合开闭原则(类、模块和函数等应该对扩展开放,对修改关闭。
)⼀个好的设计在之后的开发中,包括发⽣重⼤需求变化的时候,往往代码只需要进⾏简单重构去进⾏适配,⽽不是通过打补丁的⽅式去堆砌,也很容易避免破窗效应,充分的发挥了灵活的扩展和适配,⼤⼤增强了维护性。
综上所述,我们了解并学习设计模式,可以使我们的代码变得更加健壮、结构清晰,可以从容、灵活的适配需求变更(可复⽤、可扩展、可维护、够灵活)【正⽂】⾸先,这三种模式解决的问题是实例化对象的问题;那么为什么不直接实例化⽽⽤这样的⼯⼚形式去实例化对象呢?因为【待实例化对象太多(⼦类多且变动、调⽤频繁)或者实例化对象的过程、准备⽐较复杂】,直接实例化意味着每次都⽤重复的去执⾏实例化这个操作,如果有很多待实例化的操作,那么就要重复执⾏很多次,更不要说万⼀在实例化之前还要执⾏⼀堆配置项的初始化。
解决jmap命令打印JVM堆信息异常的问题

解决jmap命令打印JVM堆信息异常的问题jmap命令可以打印java进程的JVM堆信息,今天在某台机器上运⾏该命令查看 19560进程的堆信息jmap -heap 19560出现以下异常Attaching to process ID 19560, please wait...Debugger attached successfully.Server compiler detected.JVM version is 24.79-b02using thread-local object allocation.Parallel GC with 33 thread(s)Heap Configuration:MinHeapFreeRatio = 0MaxHeapFreeRatio = 100MaxHeapSize = 32038191104 (30554.0MB)NewSize = 1310720 (1.25MB)MaxNewSize = 17592186044415 MBOldSize = 5439488 (5.1875MB)NewRatio = 2SurvivorRatio = 8PermSize = 21757952 (20.75MB)MaxPermSize = 174063616 (166.0MB)G1HeapRegionSize = 0 (0.0MB)Heap Usage:Exception in thread "main" ng.reflect.InvocationTargetExceptionat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at ng.reflect.Method.invoke(Method.java:606)at sun.tools.jmap.JMap.runTool(JMap.java:197)at sun.tools.jmap.JMap.main(JMap.java:128)Caused by: ng.RuntimeException: unknown CollectedHeap type : class sun.jvm.hotspot.gc_interface.CollectedHeapat sun.jvm.hotspot.tools.HeapSummary.run(HeapSummary.java:146)at sun.jvm.hotspot.tools.Tool.start(Tool.java:221)at sun.jvm.hotspot.tools.HeapSummary.main(HeapSummary.java:40)... 6 more是因为机器上缺少 openjdk-debuginfo 包或者机器上的 openjdk-debuginfo 包与jdk版本不⼀致导致是⽤ java -version 查看机器上的java版本java version "1.7.0_79"OpenJDK Runtime Environment (rhel-2.5.5.4.el6-x86_64 u79-b14)OpenJDK 64-Bit Server VM (build 24.79-b02, mixed mode)java-1.7.0-openjdk-debuginfo-1.7.0.79-2.5.5.1.el6_6.x86_64.rpmjava-1.7.0-openjdk-debuginfo-1.7.0.79-2.5.5.3.el6_6.x86_64.rpmjava-1.7.0-openjdk-debuginfo-1.7.0.79-2.5.5.4.el6.x86_64.rpm均满⾜我的jdk版本,下载第⼀个进⾏尝试,下载完成后使⽤ rpm命令安装rpm -ivh java-1.7.0-openjdk-debuginfo-1.7.0.79-2.5.5.1.el6_6.x86_64.rpm安装完成后使⽤查看是否在已安装列表中,执⾏命令显⽰的确安装成功[root@identity_test tmp]# rpm -qa |grep debuginfojava-1.7.0-openjdk-debuginfo-1.7.0.79-2.5.5.1.el6_6.x86_64再次执⾏我最初想执⾏的命令jmap -heap 19560已经能正常显⽰JVM堆区信息Attaching to process ID 19560, please wait...Debugger attached successfully.Server compiler detected.JVM version is 24.79-b02using thread-local object allocation.Parallel GC with 33 thread(s)Heap Configuration:MinHeapFreeRatio = 0MaxHeapFreeRatio = 100MaxHeapSize = 32038191104 (30554.0MB)NewSize = 1310720 (1.25MB)MaxNewSize = 17592186044415 MBOldSize = 5439488 (5.1875MB)NewRatio = 2SurvivorRatio = 8PermSize = 21757952 (20.75MB)MaxPermSize = 174063616 (166.0MB)G1HeapRegionSize = 0 (0.0MB)Heap Usage:PS Young GenerationEden Space:capacity = 537919488 (513.0MB)used = 532557632 (507.88653564453125MB)free = 5361856 (5.11346435546875MB)99.00322332252071% usedFrom Space:capacity = 89128960 (85.0MB)used = 0 (0.0MB)free = 89128960 (85.0MB)0.0% usedTo Space:capacity = 89128960 (85.0MB)used = 0 (0.0MB)free = 89128960 (85.0MB)0.0% usedPS Old Generationcapacity = 1431306240 (1365.0MB)used = 844440 (0.8053207397460938MB)free = 1430461800 (1364.194679260254MB)0.058997856391655217% usedPS Perm Generationcapacity = 22020096 (21.0MB)used = 8512616 (8.118263244628906MB)free = 13507480 (12.881736755371094MB)38.65839640299479% used3145 interned Strings occupying 252104 bytes.补充知识:JVM参数,jmap打印堆快照,jstack实战死锁1 jinfo指令:如何运⾏时查看参数值jinfo -flag MaxHeapSize 23789(查看最⼤堆:23789即线程id)jinfo -flag ThreadStackSize 23789(查询线程栈⼤⼩:默认值1024)2 查看jvm运⾏时参数(1)-XX:+PrintFlagsInitial 查看初始值=表⽰默认值:=被⽤户或者JVM修改后的值(2)-XX:+PrintFlagsFinal表⽰打印出运⾏时参数⽣效的值-XX:+UnlockExperimentalVMOptions解锁实验参数(并⾮所有的参数都可以直接修改)(3)jpsjps是⽤于查看有权访问的hotspot虚拟机的进程. 当未指定hostid时,默认查看本机jvm进程,否者查看指定的hostid机器上的jvm进程,此时hostid所指机器必须开启jstatd服务。
23种(只有常用的十种)应用场景举例(详细)

目录1【装饰模式应用场景举例】 ......................................................................................................... 1 2【策略模式应用场景举例】 ......................................................................................................... 5 3【代理模式应用场景举例】 ......................................................................................................... 8 4【外观模式应用场景举例】 ....................................................................................................... 12 5【抽象工厂模式应用场景举例】 ............................................................................................... 14 6【观察者模式应用场景举例】 ................................................................................................... 22 7【建造者模式应用场景举例】 ................................................................................................... 27 8【原型模式应用场景举例】 ....................................................................................................... 32 9【工厂方法模式应用场景举例】 ............................................................................................... 35 10【模板方法模式应用场景举例】 ............................................................................................. 401【装饰模式应用场景举例】 【 】比如在玩“极品飞车”这款游戏,游戏中有对汽车进行喷涂鸦的功能,而且 这个喷涂鸦是可以覆盖的,并且覆盖的顺序也影响到最后车身的显示效果,假设 现在喷涂鸦具有 2 种样式: (1) 红色火焰 (2) 紫色霞光如果使用“继承父类” 设计这样的功能,那么类图就像如下的这样:从图中可以看到使用继承来实现这种功能,并且是 2 种涂鸦样式,就需要创 建 4 个子类,如果喷涂鸦有 3 种,4 种呢?这种情况就是典型中学课程学习过的 “排列与组合”,那简直就是“Head First 设计模式”书中讲的“类爆炸”。
JOF设计模式(很实用的)

设计模式之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(参数)。
java 面向对象的常用设计模式

java 面向对象的常用设计模式java 面向对象的常用设计模式有:1、观察者模式观察者模式又称为发布-订阅模式,定义了对象之间一对多依赖关系,当目标对象(被观察者)的状态发生改变时,它的所有依赖者(观察者)都会收到通知。
2、抽象工厂模式抽象工厂模式主要用于创建相关对象的家族。
当一个产品族中需要被设计在一起工作时,通过抽象工厂模式,能够保证客户端始终只使用同一个产品族中的对象;并且通过隔离具体类的生成,使得客户端不需要明确指定具体生成类;所有的具体工厂都实现了抽象工厂中定义的公共接口,因此只需要改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
3、单例设计模式单例设计模式可以确保系统中某个类只有一个实例,该类自行实例化并向整个系统提供这个实例的公共访问点,除了该公共访问点,不能通过其他途径访问该实例。
4、策略模式将类中经常改变或者可能改变的部分提取为作为一个抽象策略接口类,然后在类中包含这个对象的实例,这样类实例在运行时就可以随意调用实现了这个接口的类的行为。
比如定义一系列的算法,把每一个算法封装起来,并且使它们可相互替换,使得算法可独立于使用它的客户而变化,这就是策略模式。
5、适配器模式适配器模式主要用于将一个类或者接口转化成客户端希望的格式,使得原本不兼容的类可以在一起工作,将目标类和适配者类解耦;同时也符合“开闭原则”,可以在不修改原代码的基础上增加新的适配器类;将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性,但是缺点在于更换适配器的实现过程比较复杂。
6、命令模式命令模式的本质是将请求封装成对象,将发出命令与执行命令的责任分开,命令的发送者和接收者完全解耦,发送者只需知道如何发送命令,不需要关心命令是如何实现的,甚至是否执行成功都不需要理会。
命令模式的关键在于引入了抽象命令接口,发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。
工厂模式百度百科

编程开发工厂模式定义:实例化对象,用工厂方法代替new操作.为何使用?工厂模式是我们最常用的模式了,著名的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(参数)。
java面试题—设计模式(26题)

2、抽象工工厂厂模式(多个工工厂厂):创建多个工工厂厂类,提高高工工厂厂的扩展性,不不用用像上面面一一样如果增加产品则要去修改唯一一的工工厂厂类;
5、适配器器模式(接口口兼容):将某个类的接口口转换成客户端期望的另一一个接口口表示,目目的是消除由于接口口不不匹配所造成的类的兼容性问题。 1、类的适配器器模式:
2、对象的适配器器模式: 3、接口口的适配器器模式:
4、使用用场景: 1、类的适配器器模式:当希望将一一个类转换成满足足另一一个新接口口的类时,可以使用用类的适配器器模式,创建一一个新类,继承原有的类,
实现新的接口口即可。 2、对象的适配器器模式:当希望将一一个对象转换成满足足另一一个新接口口的对象时,可以创建一一个Wrapper类,持有原类的一一个实例例,在
Wrapper类的方方法中,调用用实例例的方方法就行行行。 3、接口口的适配器器模式:当不不希望实现一一个接口口中所有的方方法时,可以创建一一个抽象类Wrapper,实现所有方方法,我们写别的类的时
10
System.out.print("排序结果:”);//打印
11
}
12 }
13 //排序
14 class ConcreteSort extends AbstractSort {
15
16
@Override
17
protected void sort(int[] array){
18
for(int i=0; i<array.length-1; i++){
spring设计模式——简单工厂、工厂方法、抽象工厂

spring设计模式——简单⼯⼚、⼯⼚⽅法、抽象⼯⼚spring中⽤到很多的设计模式,其中最典型的就是⼯⼚模式。
⼯⼚模式⼜有以下三种:简单⼯⼚、⼯⼚⽅法、抽象⼯⼚。
下⾯将对这三种模式⼀⼀进⾏讲解。
1、简单⼯⼚: 当A对象需要调⽤B对象的⽅法时,我们⼀般会在A中new⼀个B实例(这种⽅式叫做硬编码耦合),这样做的缺点是⼀旦需求发⽣变化,需要使⽤C类来代替B时就要改写A类的⽅法。
假如应⽤中有1000个类以硬编码的⽅式耦合了B,那搞起来可就费劲了。
这时“简单⼯⼚”模式就派上⽤场了。
可以让B类实现⼀个IB接⼝,并创建⼀个⼯⼚类IBFactory,⽤于创建IB实例,⽽A类通过调⽤IBFactory来得到IB实例。
以下是代码⽰例:package com.lincoln.springDesignPattern;/*** Computer需要调⽤Output接⼝*/public class Computer{private Output out;private String name;public Computer(Output out,String name){this.out = out ; = name ;}public void setName(String name){ = name;}public void setOut(Output out) {this.out = out;}public void keyIn(String msg){out.getData(msg);}public void print(){out.out();}public static void main(String args[]){Computer cp = new Computer(PrintFactory.getPrint(),"lincoln's computer ") ;cp.keyIn("spring in action...");cp.keyIn("think in java...");cp.print();}}下⾯是⼀个输出接⼝:package com.lincoln.springDesignPattern;/*** ⼀个输出接⼝*/public interface Output{int MAX_CACHE_LINE = 50;void out();void getData(String msg);}定义了两个实现类:package com.lincoln.springDesignPattern;/*** 第⼀个打印器*/public class Printer implements Output{private String[] printData = new String[MAX_CACHE_LINE];private int dataNum = 0;public void out(){while(dataNum > 0){System.out.println("打印" + printData[0]);System.arraycopy(printData , 1, printData, 0, --dataNum);}}public void getData(String msg){if (dataNum >= MAX_CACHE_LINE){System.out.println("输出队列已满!");}else{printData[dataNum++] = msg;}}}另⼀个实现类:package com.lincoln.springDesignPattern;/*** 实现了Output接⼝*/public class BetterPrinter implements Output{private String[] printData = new String[MAX_CACHE_LINE * 2];private int dataNum = 0;public void out(){while(dataNum >=0 ){System.out.println("printer2," + printData[0]);//System.arraycopy(printData , 1, printData, 0, --dataNum);}}public void getData(String msg){if (dataNum >= MAX_CACHE_LINE * 2){System.out.println("getData");}else{printData[dataNum++] = msg;}}}定义⼀个⼯⼚,由这个⼯⼚来觉得究竟使⽤哪个printer。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是
指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,
使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据LSP原则,
任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型
与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽
象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。
当每个抽象产品都有多于一个的具体子类的时候,工厂角色怎么知道实例化哪一个子类呢?
比如每个抽象产品角色都有两个具体产品。抽象工厂模式提供两个具体工厂角色,分别对应
于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体
工厂类只负责创建抽象产品的某一个具体子类的实例。
每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;
而抽象工厂模式针对的是多个产品等级结果。
下面是一个java抽象工厂的实现实例.
我们以交通工具(Vihicle),食品(Foot),武器(Weapon)为抽象产品类为例:
交通工具(Vihicle)
public abstract class Vihicle {
public abstract void run();
}
食品(Foot)
public abstract class Foot {
public abstract void printName();
}
武器(Weapon)
public abstract class Weapon {
public abstract void shoot();
}
这三种抽象产品类都有两种子类的实现:
交通工具(Vihicle)有实现类Car,Broom
public class Car extends Vihicle{
public void run(){
System.out.println("冒着烟奔跑中的Car...");
}
}
public class Broom extends Vihicle{
public void run(){
System.out.println("一路沙尘暴飞奔而来..");
}
}
食品(Foot)有实现类Mushroom,Apple
public class Mushroom extends Foot{
@Override
public void printName() {
System.out.println("Mushroom");
}
}
public class Apple extends Foot{
public void printName(){
System.out.println("Apple");
}
}
武器(Weapon)有实现类AK47,MagicStick
public class AK47 extends Weapon{
public void shoot(){
System.out.println("dadada.....");
}
}
public class MagicStick extends Weapon{
@Override
public void shoot() {
System.out.println("MagicStick fare fur...");
}
}
现在建立一个抽象工厂类的父类AbstractFactory,定义好生产产品的抽象方法,让它的子类去
实现,生成具体的需要的产品.
public abstract class AbstractFactory {
public abstract Vihicle createVihile();
public abstract Weapon createWeapon();
public abstract Foot createFoot();
}
所有工厂类都要继承这个父类.
建立第一个工厂类DefaultFactory它生成的具体的产品类为Apple,Car,AK47.
public class DefaultFactory extends AbstractFactory{
@Override
public Foot createFoot() {
return new Apple();
}
@Override
public Vihicle createVihile() {
return new Car();
}
@Override
public Weapon createWeapon() {
return new AK47();
}
}
建立第二个工厂类MagicFactory它生成的具体的产品类为MagicStick,Broom,Mushroom
public class MagicFactory extends AbstractFactory{
@Override
public Foot createFoot() {
return new Mushroom();
}
@Override
public Vihicle createVihile() {
return new Broom();
}
@Override
public Weapon createWeapon() {
return new MagicStick();
}
}
这个工厂序列就建立好了,也就是说这有两个工厂能生产两种系列的产品,两种组合.当如果
还有其它定单需要另外的组合时,我们又可以建立一个工厂类实现AbstractFactory. 当抽象
产品有第三种实现产品时,我们就可以建立这个类,继承相应的抽象产品类.建立符合需求的
工厂类来组合.下面是测试的类:
public class Test {
public static void main(String[] args) {
MagicFactory f=new MagicFactory();
Vihicle c=f.createVihile();
c.run();
Weapon w=f.createWeapon();
w.shoot();
Foot a=f.createFoot();
a.printName();
}
}
我们只需要用其它工厂类替换上面代码中红色部分的工厂类即可.