java总结设计模式详解.docx
- 文档编号:30650530
- 上传时间:2023-08-18
- 格式:DOCX
- 页数:103
- 大小:46.89KB
java总结设计模式详解.docx
《java总结设计模式详解.docx》由会员分享,可在线阅读,更多相关《java总结设计模式详解.docx(103页珍藏版)》请在冰豆网上搜索。
java总结设计模式详解
【java总结】设计模式详解
Java设计模式,是一套由前人总结的,被反复使用的代码设计经验。
它为我们解决一些实际问题提供了一些很好的设计模板,了解设计模式,有利于提高我们的代码设计能力,架构能力,更有可能自己能够设计出适合业务的一套设计模式。
接下来就让我们了解一下这些神秘的设计模式。
总的来说,设计模式可以分为以下几大类。
创建型模式:
属于创建型模式的设计模式有单例模式,简单工厂模式,工厂方法模式,抽象工厂模式,原型模式,建造者模式。
这些模式都是用来创建对象的,提供了方便的接口给客户端使用。
创建型模式将对象的创建和使用分离,在使用对象时无需关心对象的创建细节,从而降低系统的耦合度,让设计方案更易于修改和扩展。
结构型模式:
属于结构型模式的设计模式有适配器模式,桥接模式,组合模式,装饰模式,外观模式,享元模式,代理模式。
他们大多是用来组织某种结构,提供某种复杂的功能,不同的结构型模式关注如何将现有类或对象组织在一起形成更加强大的结构。
比如适配器提供了将两个毫不相关的类或接口提供了桥梁,组合模式为树形结构提供了模板,外观模式为客户提供了方便简洁的接口,并且隐藏了内部细节。
行为型模式:
属于行为型模式的设计模式有职责链模式,命令模式,解释器模式,迭代器模式,中介者模式,备忘录模式,观察者模式,状态模式,策略模式,模板方法模式,访问者模式。
这些模式为客户端提供了许多功能需求,注重对象之间的交互,关注他们之间的相互作用和职责划分。
比如策略模式为用户提供了不同的策略选择,观察者模式,使得某个事件发生过后可以自动触发其他事件。
又比如备忘录模式,使得用户可以恢复之前的某个状态,实现还原的功能。
接下来我们一个一个来看这些设计模式。
创造型模式
单例模式
需求:
系统需要有一个恒定不变的对象,每次获取都是同一个对象。
比如一个朝代只能有一个皇帝,一个公司只能有一个老板。
那我们的系统就不能new出两个老板对象出来。
windows系统的任务管理器便是实现了单例模式。
特点:
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
而单例模式又分为两类,懒汉式和饿汉式。
饿汉式单例即一开始就new出一个实例,始终占据着内存,不管他以后是不是被用到。
优点是不用考虑多线程的问题。
代码如下
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
publicclassEagerSingleton{
privatestaticfinalEagerSingletoninstance=newEagerSingleton();
privateEagerSingleton(){}
publicstaticEagerSingletongetInstance(){
returninstance;
}
}
懒汉式单例即等到该对象第一次被使用时才new出一个实例,避免了一开始就占用资源。
缺点是考虑多线程情况下同时new出多个实例的问题,需要使用锁,在多线程并发访问环境下会导致性能下降。
代码如下
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
publicclassLazySingleton{
privatestaticLazySingletoninstance=null;
privateLazySingleton(){}
synchronizedpublicstaticLazySingletongetInsatance(){
if(instance==null)instance=newLazySingleton();
returninstance;
}
}
IoDH(InitializationonDemandHolder):
即有延迟加载,又保证线程安全,不影响系统性能。
缺点是与编程语言本身特性相关,java中可以实现,但很多面向对象语言不支持。
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
publicclassIoDH{
privateIoDH(){}
privatestaticclassHolderClass{
privatefinalstaticIoDHinstance=newIoDH();
}
publicstaticIoDHgetInsatance(){
returnHolderClass.instance;
}
}
简单工厂模式
需求:
客户端想简单地传入不同参数就得到不同类的实例,不想很麻烦地一个一个去new。
特点:
简单工厂针对抽象编程,使用static方法,根据传入的参数,new出对应的具体子类,用户可以通过Factory.Create(“对应参数”)得到对应实例,免除创建的职责。
缺点是工厂类集中了大量创建代码,一旦不能正常工作整个系统都要受到影响。
并且扩展十分困难,需要修改工厂逻辑。
示例代码如下:
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
abstractclassProduct{
publicvoidmethodSame(){
//公共方法
}
//抽象业务方法
publicabstractvoidmethodDiff();
}
publicclassConcreteProduct1extendsProduct{
@Override
publicvoidmethodDiff(){
//TODOAuto-generatedmethodstub
System.out.println("我是第一号产品");
}
}
publicclassConcreteProduct2extendsProduct{
@Override
publicvoidmethodDiff(){
//TODOAuto-generatedmethodstub
System.out.println("我是第二号产品");
}
}
publicclassFactory{
publicstaticProductgetProduct(Stringarg){
Productproduct=null;
if(arg.equalsIgnoreCase("1")){
product=newConcreteProduct1();
}elseif(arg.equalsIgnoreCase("2")){
product=newConcreteProduct2();
}
returnproduct;
}
}
publicclassClient{
publicstaticvoidmain(String[]args){
Productproduct1,product2;
product1=Factory.getProduct("1");
product2=Factory.getProduct("2");
product1.methodDiff();
product2.methodDiff();
}
}
工厂方法模式:
需求:
同简单工厂模式。
特点:
定义一个用于创建对象的接口,让子类决定将哪一个类实例化。
在简单工厂模式中,有加入新产品需要修改工厂逻辑的缺点,在工厂方法模式中,我们不再使用同一个工厂,而是不同的产品提供不同的工厂,每当我们加入新产品时,只需要实现新的工厂类,不用改变原来的任何一处代码。
它缺点是新增一个产品类还要提供与之对应的工厂类,个数将成对增加。
代码结构:
抽象产品类(或接口)作为抽象工厂类(或接口)的创建方法的参数传入,再通过具体的工厂实现类来得到对应的具体产品类。
抽象工厂模式:
需求:
在日常生活中,每个产品都有不同的牌子,而同一个牌子旗下可能有不同的产品,怎么去模拟这样一个模式?
特点:
在简单工厂模式的基础上新增两个概念,分别是产品族和产品等级结构。
产品等级结构即产品的继承结构,即抽象产品类/接口与它的实现类。
产品族可以理解为一个品牌,相同品牌旗下的不同产品构成一个产品族。
在抽象工厂模式中,一个产品族是由同一个工厂生产的。
增加新的产品族只需要增加一个新的工厂,无需修改已有系统,符合开闭原则。
但是,增加新的产品等级结构却需要较大的修改,这是它的缺点。
示例代码如下:
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
publicinterfaceComboBox{
publicvoiddisplay();
}
publicinterfaceTextField{
publicvoiddisplay();
}
publicinterfaceButton{
publicvoiddisplay();
}
publicclassSpringButtonimplementsButton{
@Override
publicvoiddisplay(){
//TODOAuto-generatedmethodstub
System.out.println("显示浅绿色按钮");
}
}
publicclassSpringComboBoximplementsComboBox{
@Override
publicvoiddisplay(){
//TODOAuto-generatedmethodstub
System.out.println("显示绿色边框组合框");
}
}
publicclassSpringTextFieldimplementsTextField{
@Override
publicvoiddisplay(){
//TODOAuto-generatedmethodstub
System.out.println("显示绿色边框文本框。
");
}
}
publicclassSummerButtonimplementsButton{
@Override
publicvoiddisplay(){
//TODOAuto-generatedmethodstub
System.out.println("显示浅蓝色按钮");
}
}
publicclassSummerComboBoximplementsComboBox{
@Override
publicvoiddisplay(){
//TODOAuto-generatedmethodstub
System.out.println("显示蓝色边框组合框");
}
}
publicclassSummerTextFieldimplementsTextField{
@Override
publicvoiddisplay(){
//TODOAuto-generatedmethodstub
System.out.println("显示蓝色边框文本框");
}
}
publicinterfaceSkinFactory{
publicButtoncreateButton();
publicTextFieldcreateTextField();
publicComboBoxcreateComboBox();
}
publicclassSpringSkinFactoryimplementsSkinFactory{
@Override
publicButtoncreateButton(){
//TODOAuto-generatedmethodstub
returnnewSpringButton();
}
@Override
publicTextFieldcreateTextField(){
//TODOAuto-generatedmethodstub
returnnewSpringTextField();
}
@Override
publicComboBoxcreateComboBox(){
//TODOAuto-generatedmethodstub
returnnewSpringComboBox();
}
}
publicclassSummerSkinFactoryimplementsSkinFactory{
@Override
publicButtoncreateButton(){
//TODOAuto-generatedmethodstub
returnnewSummerButton();
}
@Override
publicTextFieldcreateTextField(){
//TODOAuto-generatedmethodstub
returnnewSummerTextField();
}
@Override
publicComboBoxcreateComboBox(){
//TODOAuto-generatedmethodstub
returnnewSummerComboBox();
}
}
原型模式
需求:
创建一个复杂对象比较麻烦或者成本较高,需要一个方法来简化对象创建的过程。
或者是需要保存对象的状态。
特点:
让对象实现Cloneable接口,重写Clone方法。
适用clone方法需要注意的是,克隆分为浅克隆和深克隆。
当一个对象中所含的数据都是基本类型数据时,调用clone方法不会有任何问题,这是所谓的浅克隆。
当你数据中包含引用类型时,简单地调用clone方法只是会对象的引用复制过去,而不是真正的复制一个对象。
以电视(对象)和遥控器(引用)为例,我们只是复制了一个遥控器,而没有复制电视。
这样我们在对其修改的时候,克隆后的对象会改变被克隆对象的状态。
而深克隆就是需要我们将电视也克隆一份,需要在类的clone方法中对引用的类也调用clone方法,或者直接用serializable将整个类序列化写入对象流中再读取出来。
浅克隆示例代码:
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
publicclassWeeklyLogimplementsCloneable{
privateStringname;
privateStringdate;
privateStringcontent;
publicvoidsetName(Stringname){
this.name=name;
}
publicvoidsetDate(Stringdate){
this.date=date;
}
publicvoidsetContent(Stringcontent){
this.content=content;
}
publicStringgetName(){
returnthis.name;
}
publicStringgetDate(){
returnthis.date;
}
publicStringgetContent(){
returnthis.content;
}
publicWeeklyLogclone(){
Objectobj=null;
try{
obj=super.clone();
return(WeeklyLog)obj;
}
catch(Exceptione){
//TODO:
handleexception
System.out.println("不支持复制!
");
returnnull;
}
}
publicstaticvoidmain(String[]args){
WeeklyLoglog=newWeeklyLog();
log.setName("小明");
log.setDate("第1周");
log.setContent("每天加班");
System.out.println("****周报****");
System.out.println("周次:
"+log.getDate());
System.out.println("姓名:
"+log.getName());
System.out.println("内容:
"+log.getContent());
System.out.println("************");
WeeklyLoglog2=log.clone();
log2.setDate("第2周");
System.out.println("****周报****");
System.out.println("周次:
"+log2.getDate());
System.out.println("姓名:
"+log2.getName());
System.out.println("内容:
"+log2.getContent());
System.out.println("************");
}
}
深克隆示例代码:
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
publicclassAttachmentimplementsSerializable{
privateStringname;
publicvoidsetName(Stringname){
this.name=name;
}
publicStringgetName(){
returnname;
}
publicvoiddownload(){
System.out.println("下载附件:
文件名为"+name);
}
}
publicclassWeeklyLogimplementsCloneable,Serializable{
privateStringname;
privateStringdate;
privateStringcontent;
privateAttachmentattachment;
publicvoidsetAttachment(Attachmentattachment){
this.attachment=attachment;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicvoidsetDate(Stringdate){
this.date=date;
}
publicvoidsetContent(Stringcontent){
this.content=content;
}
publicStringgetName(){
returnthis.name;
}
publicStringgetDate(){
returnthis.date;
}
publicStringgetContent(){
returnthis.content;
}
publicAttachmentgetAttachment(){
returnthis.attachment;
}
publicWeeklyLogclone(){
Objectobj=null;
try{
obj=super.clone();
return(WeeklyLog)obj;
}
catch(Exceptione){
//TODO:
handleexception
System.out.println("不支持复制!
");
returnnull;
}
}
publicWeeklyLogdeepClone()throwsIOException,ClassNotFoundException{
ByteArrayOutputStreambao=newByteArrayOutputStream();
ObjectOutputStreamoos=newObjectOutputStream(bao);
oos.writeObject(this);
ByteArrayInputStreambis=newByteArrayInputStream(bao.toByteArray());
ObjectInputStreamois=newObjectInputStream(bis);
return(WeeklyLog)ois.readObject();
}
publicstaticvoidmain(String[]args)throwsClassNotFoundException,IOException{
WeeklyLoglog=newWeeklyLog();
Attachmentattachment=newAttachment();
log.setAttachment(attachment);
log.setName("小明");
log.setDate("第1周");
log.setContent("每天加班");
System.out.println("****周报****");
System.out.println("周次:
"+log.getDate());
System.out.println("姓名:
"+log.getName());
System.out.println("内容:
"+log.getContent());
System.out.println("************");
WeeklyLoglog2;
log2=log.deepClone();
log2.setDate("第2周");
System.out.println("****周报****");
System.out.println("周次:
"+log2.getDate());
System.out.println("姓名:
"+log2.getName());
System.out.println("内容:
"+log2.getContent());
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 总结 设计 模式 详解