`

24、设计模式之创建模式

    博客分类:
  • java
 
阅读更多

设计模式的分类

总体来说设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

还有两类:并发型模式和线程池模式。

 

这里说的模式可以理解为如何创建实例,这种创建实例的设计方式有什么好处和用地;

1.1、FactoryMethod (工厂方法模式)

@判断创建实例:

接口; 实现接口类; 工厂(public  Interface   createObject(String which){return new A();//创建一个匿名实例});

调用:Interface  a = new  Factory().createObject("a"); a.function();

@选择创建实例:

Interface   ImplementsClass(A,B,C,D....)  Factory{createA(){return new A() }   createB(){return new B() } }

调用:Interface     b =new Factory().createB();   b.function();

@选择型,静态创建实例(2的升级版,常用这种模式):

Interface   ImplementsClass(A,B,C,D....)  Factory{static  createA(){return new A() }   static  createB(){return new B() } }

调用:Interface     b =Factory.createB();   b.function();

&:A的匿名实例通过向上转型成为接口的实例a,然后a执行A中复写接口的实现方法;

工厂方法模式的好处:将多个类的构造方法进行封装,在创建对象时,可以减少代码;如多个实例调用同样的构造方法,这样可大大减少代码的写入;将构造方法封装与其他方法隔离也体现了解耦的思想,增强程序健壮性;若是继承抽象类,调用同一方法时,还可以节省大量的方法代码;在需要创建多个实例时可以考虑使用工厂方法模式。工厂方法模式只创建了一个工厂类。

 

1.2、Abstract Factory(抽象工厂模式)

将工厂方法进一步细分,比如有类A,实现了接口IR1;Factory1实现一个接口Ifactory,复写方法createObject(){renturn new A();};

比如要得到A的实例:

Ifactory f = new Factory1();
IR1 a = f.createObject();

如果A类提供的方法不能满足新的需求,而又不能修改A提供的方法,或者A提供过多的方法而不会被使用,创建了A的实例必然会造成内存浪费;这样就产生了接口编程的思想,在接口中可以定义许多抽象方法,由它的子类去实现;子类有选择性的实现那些接口方法或覆写成各自需要的方法以实现不同功能;假如现在有一个新需求,A提供的方法不能满足,可以创建一个B实现同一个接口IR1,覆写方法function(),满足了新需求;但原来定义的工厂方法模式不能实例这类,因为没有定义,这时只需要创建一个新工厂Factory2实现工厂接口,并提供一个生产B的方法,就能实现功能扩展:

Ifactory f = new Factory2();
IR1 b = f.createObject();

 

从上面的解释就知道使用抽象工厂的好处:扩展功能!

 

1.3、单例模式

单列模式是编程语言常用的设计模式;比如多台电脑对一台打印机的调用,不可能同时打印,只能打印完了一个任务才能进行下一个打印任务,又如售票系统,当多个窗口同时出票,每个窗口都会对库存票进行查询,如果库存同时接收了相同的指令而没有进行排序操作的话,就有可能出现几个窗口对同一张票进行了操作,这肯定是行不通的;这里就涉及到一个多线程/进程 同步/死锁概念;    单例模式的作用就是当一个线程/进程 在操作某个资源(这个资源称为临界资源)的时候,操作开始前对资源加锁防止其他线程/进程操作这个资源,操作结束后进行解锁,后面的线程/进程就可以操作这个资源了,同时进行加锁/解锁;

 

但对于大数据、大对象、操作频繁的线程,显然这种纯 单例模式是不能满足要求的,数据隔离这个概念便产生了,数据隔离将在以后的章节讲解;

在java中A a = new A();这会调用两个线程执行:一个是类A的声明方法,一个是A的匿名实例创建方法;记住这一点,所以A a与new A()谁先谁后执行是无法确定的,这里涉及到线程安全问题;

返回一个单例对象的常用代码

public static synchronized Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  

synchronized 表名同步,即加锁

static  表名全局、类属性

两个关键字加在一起:当调用了这个类(不管是创建实例还是直接引用类名)都会率先开辟static的属性/方法的静态内存(虽然方法要调用后才执行);

在synchronized前加上了static声明,即在这个静态内存中,所有调用这个方法的对象都要被加锁;若没有加static关键字,每次new出一个新对象,就会产生一个新的堆内存空间,而synchronized的作用范围就在这个堆内存中,每次实例对象都会被对象的线程执行一次,synchronized 只对实例的线程进行了加锁,而其他对象也对这个方法进行了操作;这就是为什么使用static把这个方法放在全局内存中的原因;

 

使用单例模式的好处:对临界资源的顺序占有;

 还有一些线程安全的获取单例的方法比如使用内部类创建、静态属性创建,这里不再说明,可以在网上找到;

 

1.4、Builder(建造者模式)

工厂模式是通过工厂得到单个接口实例,接口实例调用被覆写的方法;建造者可以想象为一个车间,车间里有多条生产线(多个create方法),一条生产线只生产同一类型的多个对象;

List<A>   a = new ArrayList<A>();
public  void  createManyA(int x){
     for(int i=0;i<x;i++){
          a.add(new A());
      }
}
public  void  createManyB(int x){ .....

 

1.5、Prototype(原型模式)

学习过javascript可能会有印象,一个js库提供者通常将属性、方法封装在原型属性中,用户在调用这个对象时可以添加自定义的属性和方法,提供者而不是直接写在对象本身中,那样会造成浏览器无法甄别该使用哪个属性或方法;可以把对象的原型想像成隐藏属性. 当访问对象的一个属性时, 首先查找对象本身, 找到则返回; 若找不到, 则查找原型属性;

原型模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。在Java中,复制对象是通过clone()实现的;先看下Cloneable接口: 

public interface Cloneable {   //没有任何方法
}

创建一个原型类要实现Cloneable接口,Cloneable接口是个空接口,此处的重点是super.clone()这句话,super.clone()调用的是Object的clone()方法,而在Object类中,clone()是native的,具体怎么实现,参看23、jvm之JNI;先明白一个知识:基本数据类型值就是地址

class A{
	public int x=32; //基本数据类型栈内存中保存
	public String  str0="why!"; 
	//在堆内存中指定一块空间保存"why!","why!"本身是一个String的实例,只开辟一次堆内存空间,str0和info0都指向这个引用地址;
	//这里str0是声明的一个实例,实例信息保存在栈内存中,"why!"将引用地址赋值给str0
	public String  str=new String("why!"); 
	//在堆内存中给予一块区域来保存"why!"使用了new关键字:1.创建了匿名实例,2.开辟了新堆内存空间	
}
class B{
	public int y=32;
	public String  info0="why!";
	//这里info0是一个新实例,"why!"将引用地址赋值给info0,不会再开辟一个堆内存空间来保存"why!",
	public String  info=new String("why!");
}
public class Demo5 {
 public static void main(String...strings ){
	 System.out.println(new A().x==new B().y);  //true 栈内存中值就是地址,所以地址相同
	 System.out.println(new A().str0==new B().info0); //true说明两者指向同一堆内存地址,
	 System.out.println(new A().str==new B().info); //false说明两者指向不同的堆内存地址
 }
}

 现在来创建一个原型:

 class Prototype  implements Cloneable{
	 public int x=2;  //x为基本数据类型
	 public  String s=new String("ok");  //s为引用数据类中
	public void sayHi(){
		System.out.println("Hello!!!");
	}
	public Prototype copy() throws CloneNotSupportedException {  //Prototype可以用Object替代,这里为了看上去容易理解返回Prototype型
		Prototype  proto = (Prototype ) super.clone();  
        //在自身方法中创建了一个实例,联想单例模式,A.getA();返回一个A的匿名实例,这里是一个有声明名字的实例
        return proto;  
        //调用 new Prototype().copy()将会返回一个Obejct对象,要调用proto的方法还是要用Prototype接收
    }  
}
public class Demo4{
	public static void main(String... s) throws CloneNotSupportedException{
		Prototype obj= new Prototype();  
		Prototype obj2 =obj.copy();
		//用Prototype接收,这里与Prototype obj2=new Prototype()是不一样的,obj2复制obj也会生成一个堆内存空间来存放
		System.out.println(obj.x==obj2.x);     //判断基本数据类型是否相同,基本数据类型值就是地址  true
		System.out.println(obj.s==obj2.s);     //判断引用数据类型是否指向同一地址 true,说明new String("ok")只执行了一次		
	}
}

上面的例子中,通过克隆对象得到的引用地址一样的,匿名开辟堆内存空间方法只执行了一次,这就是java中所说的浅复制;

 

浅复制:将一个对象复制后,引用类型指向原对象的引用地址。

深复制:将一个对象复制后,引用类型重新创建,要实现深复制,需要采用流的形式读入被复制的对象,再写出二进制数据给对应的对象。[#]

 

分享到:
评论

相关推荐

    设计模式之创建型模式实验.docx

    【设计模式之创建型模式实验】 创建型设计模式主要关注对象的创建,它们提供了一种在不指定具体类的情况下创建对象的方式,增强了系统的灵活性和可扩展性。在本实验中,我们将探讨五种常见的创建型设计模式:简单...

    24种设计模式以及混合设计模式

    在本文中,我们将深入探讨24种设计模式,并结合混合设计模式的概念,以及它们在实际项目中的应用案例。 首先,设计模式分为三大类:创建型、结构型和行为型。创建型设计模式关注对象的创建过程,如单例模式...

    设计模式之蝉

    还有“工厂模式”(Factory pattern),它是创建型设计模式之一,用于创建对象而不暴露创建逻辑给客户端,并且通过使用一个共同的接口来指向新创建的对象。这种模式在创建对象时提供了更高的灵活性和可扩展性。在...

    设计模式之创建型模式

    创建型模式作为设计模式的五种主要类别之一,它主要关注的是对象的创建过程,通过抽象和封装创建过程中的变化点,使得系统能够更加灵活地应对未来的变化。 创建型模式包括多种不同的模式,例如工厂模式、单态模式、...

    JAVA设计模式(创建模式 结构模式 行为模式)

    Java设计模式是软件开发中的重要概念,它是一种在特定情境下解决问题的经验总结,可以提高代码的可重用性、可维护性和灵活性。本资源主要涵盖了创建模式、结构模式和行为模式三大类,每种模式都是面向对象设计的核心...

    设计模式之美——教你写出高质量代码

    "设计模式之美——教你写出高质量代码"这个主题旨在帮助开发者更好地理解和应用设计模式,从而提升代码的质量和可维护性。设计模式不仅对面试有所帮助,也是职场发展中的必备技能,无论你使用哪种开发语言。 设计...

    设计模式之美—学习笔记

    在这个“设计模式之美”的学习笔记中,我们将探讨一些主要的设计模式,以及它们在实际开发中的应用。 首先,我们从创建型模式开始。这类模式主要用于对象的创建,如单例模式(Singleton)、工厂模式(Factory ...

    Java设计模式之禅

    《Java设计模式之禅》是一本深入浅出讲解设计模式的书籍,书中不仅包含23种经典设计模式的案例,还详细介绍了设计模式背后的思想和原则,适合初学者以及对设计模式有一定了解的程序员阅读。本书旨在帮助读者理解如何...

    人人都懂设计模式 人人都懂设计模式

    设计模式可以分为三大类:创建型模式、结构型模式和行为型模式。 在本书中,作者罗伟富通过 Python 实现了 23 种经典设计模式,包括 Singleton 模式、Factory 模式、Observer 模式等。这些模式可以帮助开发者更好地...

    JAVA设计模式chm文档

    设计模式之Factory 设计模式之Prototype(原型) 设计模式之Builder 设计模式之Singleton(单态) 结构模式: 设计模式之Facade(外观) 设计模式之Proxy(代理) 设计模式之Adapter(适配器) 设计模式之Composite(组合) 设计...

    5种创建型设计模式

    GOF的23中设计模式中,五种创建型模式的介绍。

    3.java设计模式-创建者模式-抽象工厂模式.pdf

    抽象工厂模式是创建型设计模式中的一种,用于创建一系列相关或相互依赖的对象,而无需指定其具体类。抽象工厂模式强调产品的系列,对于有多个产品等级结构的系统非常有用。在抽象工厂模式中,一个工厂负责创建多个...

    GOF设计模式中英文+设计模式精解中英文

    GOF(Gang of Four)设计模式,由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位专家在他们的著作《设计模式:可复用面向对象软件的基础》中提出,被誉为设计模式的经典之作。本资源包含了GOF设计...

    Java 设计模式之创建模式

    Java设计模式中的创建模式是软件开发中的一种重要设计思想,它们主要是为了抽象并封装对象的创建过程,使得系统在创建对象时更具灵活性和扩展性。本文将深入探讨三种工厂模式和单例、多例模式。 首先,理解创建模式...

    Java设计模式之创建型模式的几个小DEMO

    创建型模式是设计模式的一种分类,主要关注对象的创建过程,旨在抽象和隔离实例化过程,提高代码的灵活性和可复用性。本篇文章将详细探讨Java中的几种创建型设计模式,并通过具体的DEMO来阐述它们的应用。 1. 单例...

    23种设计模式详解PDF

    设计模式 的分类 总体来说设计模式分为三大类: 创建型模式(5): 工厂方法模式 、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式(7): 适配器模式、装饰器模式、代理模式、外观模式、桥接模式、...

    java设计模式之工厂模式

    java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式...

    JAVA 24种设计模式介绍与6大设计原则.pdf

    JAVA 24种设计模式主要分为三类:创建型模式、结构型模式和行为型模式。创建型模式关注对象创建机制,为对象实例化提供指导,包括单例模式、抽象工厂模式、建造者模式、工厂方法模式、原型模式和生成器模式等。结构...

    Java设计模式之创建型模式源码以及文档

    在"Java设计模式之创建型模式源码以及文档"中,你将找到这些模式的具体实现,包括源码和相关文档。通过阅读源码,你可以深入理解每种模式的内部工作机制,而文档则会提供理论背景和应用场景的解释,帮助你更好地运用...

    设计模式之创建型模式.pdf

    创建型模式是软件工程中23种设计模式中的一类,主要目的是使得对象的创建与使用相分离,从而使系统更加灵活。创建型模式包括单例模式、工厂方法模式、抽象工厂模式、建造者模式和原型模式等。这些模式各有其特定的...

Global site tag (gtag.js) - Google Analytics