精华内容
下载资源
问答
  • 创建类模式有以下5个:(简单工厂模式的思想引出了设计模式概念,但不属于23个设计模式) 1.抽象工厂模式:创建一系列对象的接口,无需指定具体的类。用于创建一组相关或相互依赖的复杂对象。 优点:   相较于...

    创建类模式的特点是:主要关注对象的创建过程,将对象的创建过程进行封装,使客户端不用去关心如何创建对象。

    创建类模式有以下5个:(简单工厂模式的思想引出了设计模式概念,但不属于23个设计模式)

    1.抽象工厂模式:创建一系列对象的接口,无需指定具体的类。用于创建一组相关或相互依赖的复杂对象。

    优点:
      相较于工厂方法模式,减少了类的个数。当一个产品中多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

    缺点:
      因为多产品构建方法都在集成到每个工厂中,导致一定程度上增加了耦合性,即若要增加一个产品族,则只需添加一个具体工厂,无须修改其他任何代码,符合开闭原则;但若想增加一种新产品,则要添加新接口方法。

    2.建造者模式:将复杂对象的构建与表示分离,使同样构建过程有不同表示。用于创建模块化的复杂的对象。

    优点:

            客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。每一个具体建造者都独立,可以方便地替换具体建造者或增加新的具体建造者, 可以更加精细地控制产品的创建过程 。增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭”。

    缺点:

      当建造者过多时,会产生很多类,难以维护。若产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,系统变得很庞大。

    3.工厂方法模式:定义创建对象的接口,子类决定实例化具体类,用于创建复杂对象。

    优点:
      继承了简单工厂模式的优点,并弥补了其缺点因为抽象工厂层的引入,以及对每种产品生产工厂的分割,在增改产品时,只需要添加或改动对应工厂即可,其他代码不需要做修改,使得系统更加依赖倒转与开闭原则

    缺点:
      每类新产品都需要对应工厂,导致类个数更多增加,增加系统复杂度。

    4.原型模式:原型实例指定创建对象,通过拷贝新建对象,得到一个对象的拷贝。

    优点:

           当需创建对象较为复杂时,或大量重复创建某对象时,可简化创建过程提高效率。

    缺点:

           个人感觉无明显缺点

    5.单例模式:保证一个类只有一个实例,得到内存中的唯一对象。

    优点:

          确保了类实例的唯一性,对访问进行严格控制。

    缺点:

           个人感觉无明显缺点

         在编程中,对象的创建一般是比较复杂的事,为了降低耦合我们通常采用面向抽象编程的方式,对象间的关系等到调用的时候再进行组合,这样降低了对象间的耦合,提高了对象复用的可能。但是将组装类的任务都交给了客户端程序,增加了客户端程序的复杂。创建类模式可以将组装对象的过程封装到一个单独的类中,这样既不会增加对象间的耦合,又可以减小客户端的负担。

     

    展开全文
  • 创建型模式——单例模式

    千次阅读 2020-07-09 10:19:51
    单例模式是最简单的设计模式之一,属于创建型模式,它提供了一种特殊创建对象方式,确保全局中只有单个对象被创建。这个设计模式主要目的是想在整个系统中只能出现类一个实例,即一个类只有一个对象。 单例...

    创建型模式——单例模式

    (一)概述

    单例模式是最简单的设计模式之一,属于创建型模式,它提供了一种特殊的创建对象的方式,确保全局中只有单个对象被创建。这个设计模式主要目的是想在整个系统中只能出现类的一个实例,即一个类只有一个对象。

    在这里插入图片描述
    单例模式可以非常有效地节约资源,主要有以下两点:

    1. 由于频繁使用已经创建完成的对象,可以省略多次创建对象所花费的时间,这对于那些重量级的对象而言,效果非常明显。
    2. 因为不需要频繁创建对象,GC压力也减轻了,而在GC中会有STW(stop the world),从这一方面也节约了GC的时间。

    但是,单例模式很多时候不得不考虑多线程并发的问题。虽然单例模式本身非常简单,但是加上并发问题之后,使得它变为一种非常复杂且容易出错的设计模式。下面我们来看看单例模式的实现方式:

    (二)饿汉模式实现

    public class Singleton {  
    	private static Singleton instance = new Singleton();  
    	private Singleton (){}
    	public static Singleton getInstance() {  
    		return instance;  
    	}  
     }  
    

    饿汉模式是单例模式最简单也是最基础的实现方式之一。这种方式在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快。 这种方式基于类加载机制避免了多线程的同步问题,因此非常通俗易懂。

    (三)非线程安全的懒汉模式实现

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

    这是最基础的懒加载模式的单例模式。我们可以发现与饿汉模式相比,懒汉模式将对象创建时机放到了使用时,当第一次使用这个对象时,才会对对象进行初始化。因此,这种方式能更有效的利用资源。但是,重点来了,这段代码无法在多线程的环境下正常运行(关键在于创建对象时可能出现的指令重排序,这里就不展开了)。

    (四)线程安全的懒汉模式实现

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

    我们可以看到这个懒汉模式和上面的只有一个区别,就是多了一个synchronized关键字,这个关键字使得在同一时间只有一个线程能进入getInstance()的代码块中,避免了多线程情况下的问题。但是,synchronized造成了很多不必要的同步开销,使得这段代码的效率极为低下。因为可能出现问题的时候只是创建对象时,显然我们的对象只会创建一次,而synchronized使得每次使用对象时都要进行同步,造成极大的资源浪费。因此,这种实现方式基本可以弃用。

    我们可以思考一下为什么这段代码效率低,就能找到改进方法。按照道理,我们只需要在第一次创建对象时进行同步,但是这段代码实际将后面每次使用对象的过程也进行了同步。因此,我们可以认为他的封锁粒度过大,因此我们要着手降低封锁的粒度。

    (五)双重检查锁的懒汉模式实现

    public class Singleton {  
        private volatile static Singleton singleton;  
        private Singleton (){}  
        public static Singleton getSingleton() {  
    	    if (singleton == null) {  
    	        synchronized (Singleton.class) {  
    		        if (singleton == null) {  
    		            singleton = new Singleton();  
    		        }  
    	        }  
    	    }  
    	    return singleton;  
        }  
    }  
    

    synchronized同步块里面能够保证只创建一个对象。但是通过在synchronized的外面增加一层判断,就可以在对象一经创建以后,不再进入synchronized同步块,这种方案不仅减小了锁的粒度,保证了线程安全,同时性能方面也得到了大幅提升。同时这里要注意volatile不能少,这个很关键,volatile一般用于多线程的可见性,但是这里是用来防止指令重排序的。

    (六)静态内部类懒汉模式实现

    public class Singleton { 
    	private Singleton(){}
      	public static Singleton getInstance(){  
        	return SingletonHolder.sInstance;  
    	}  
    	private static class SingletonHolder {  
        	private static final Singleton sInstance = new Singleton();  
    	}  
    } 
    

    这是双重检查锁的懒汉模式的替代,一种比较巧妙的实现方式。第一次加载Singleton类时并不会初始化sInstance,只有第一次调用getInstance方法时虚拟机才会加载SingletonHolder并初始化sInstance对象,这样不仅能确保线程安全也能保证唯一性,所以推荐使用静态内部类单例模式。

    (七)基于枚举类的饿汉模式实现

    public enum Singleton{
        INSTANCE;
    }
    

    默认枚举实例的创建是线程安全的,所以不需要担心线程安全的问题。通过枚举类,能自动避免序列化/反序列化攻击,以及反射攻击(枚举类不能通过反射生成)。

    2020年7月9日

    展开全文
  • 单例模式是java中最简单的设计模式之一,这种类型数据模式属于创建型模式,它提供了一种创建对象最佳方法。这种模式涉及到一个单一类,该类负责创建自己对象,同时确保只有单个对象被创建。这个类提供了一种...

    创建者模式——单例设计模式

    单例模式概述:

    单例模式是java中最简单的设计模式之一,这种类型的数据模式属于创建型模式,它提供了一种创建对象的最佳方法。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一对象的方式,可以直接访问,不需要实力化该类的对象。

    单例模式的结构

    单例模式主要有以下角色:

    • 单例类:只能创建一个实例的类。
    • 访问类:用来使用单例类。

    单例模式的实现

    从总体上看,单例模式的实现方式可以分为饿汉式和懒汉式。饿汉式是指在类加载过程中就会导致单例模式对象被创建。懒汉式是指首次使用该类对象时才会创建。
    饿汉式方式1——使用静态变量方式

    /**
     * 饿汉式——静态变量
     */
    public class Singleton1 {
        //将构造方法私有
        private Singleton1(){};
    
        //在成员位置创建该类的对象
        private static Singleton1 instance = new Singleton1();
    
        //对外提供静态方法获取该对象
        public static Singleton1 getInstance(){
            return instance;
        }   
    }
    

    在上述代码中将单例类的构造方法私有化,使得只有在单例类内可以调用构造方法创建单例对象。在单例类的成员变量位置,将单例类实例化。并在单例类中加入static静态方法getInstance,方法返回实例后的单例对象,使得外部类可以访问到单例对象。
    对于上述单例模式的实现过程,也可以在成员变量位置只是声明内部变量,在静态代码块内将其实例化。
    无论使用哪种饿汉式的单例模式实现方法,单例类都会在类加载过程中被实例化,无论在程序中是否应用了单例类中的方法或成员变量,实例后的单例对象都会一直存在于内存中,造成内存的浪费。
    饿汉式方式2——枚举方式

    public enum Singleton4 {
        instance;
    }
    

    枚举类实现单例模式是十分优美的简单的实现方式,因为枚举类是线程安全的,并且只会装载一次,所以可以利用枚举类实现单例模式。
    懒汉式方式1——双重检查锁

    public class Singleton2 {
        //将构造方法私有
        private Singleton2(){};
    
        private static Singleton2 instance;
    
        //对外提供静态方法获取对象
        public static Singleton2 getInstance(){
            //第一次判断,如果instance不为null,不进入抢锁阶段,直接返回实例
            if(instance == null){
                synchronized (Singleton2.class){
                    //抢到锁之后再次判断instance是否为null
                    if (instance == null){
                        instance = new Singleton2();
                    }
                }
            }
            return instance;
        }
    }
    

    使用懒汉式的实现方式,可以避免之前饿汉式中带来的内存浪费的问题。但是使用懒汉式存在新的问题,就是当多个线程同时调用getInstance方法时,有可能会实例出很多对象,如果将getInstance方法用synchronized关键字锁住,优惠造成性能上严重下降。双重检查锁很巧妙的解决了这个问题。
    双重检查锁,在锁外部先进行一次判断,如果已经完成实例化,则不会进行锁争夺。在synchronized内有进行一次判断,防止在阻塞状态的线程得到锁后再次进行实例化操作。
    懒汉式方式2——静态内部类方式

    public class Singleton3 {
        //将构造方法私有化
        private Singleton3(){};
        
        //静态内部类
        private static class SingletonHolder{
            private static final Singleton3 instance = new Singleton3();
        }
        
        //对外提供静态方法获取该对象
        public static Singleton3 getInstance(){
            return SingletonHolder.instance;
        }
    }
    

    由于jvm特性,在加载外部类的过程中,是不会加载静态内部类的,只有内部类的属性或者方法被调用时才会被加载,并初始化静态属性。静态属性由于被static修饰,保证只被实例化一次,并且严格保证实例化顺序。
    第一次加载Singleton3类时不会初始化instance,只有第一次调用getInstance方法,虚拟机加载SingletonHolder,并初始化instance,这样不仅能确保线程安全,也能保证Singleton3类的唯一性。

    单例模式的优化

    在单例模式中,通过“序列化-反序列化”的方式、“反射”的方式都可以破坏单例模式。为了解决反序列化问题,可以在单例类中加入readResolve()方法,在反序列化时被反射调用,如果定义了这个方法,就返回这个方法的值,如果没有定义,则放回新new出来的对象。为了解决反射问题,可以在当调用私有构造方法时,如果单例类已经被实例化,则直接抛出异常。
    解决反序列化与反射,以双重检查锁方式为例进行如下改进:

    import java.io.Serial;
    import java.io.Serializable;
    
    public class Singleton2 implements Serializable {
        //将构造方法私有
        private Singleton2(){
        	//解决反射
            if(instance != null){
                throw new RuntimeException();
            }
        };
    
        private static Singleton2 instance;
    
        //对外提供静态方法获取对象
        public static Singleton2 getInstance(){
            //第一次判断,如果instance不为null,不进入抢锁阶段,直接返回实例
            if(instance == null){
                synchronized (Singleton2.class){
                    //抢到锁之后再次判断instance是否为null
                    if (instance == null){
                        instance = new Singleton2();
                    }
                }
            }
            return instance;
        }
    
    	//解决反序列化
        @Serial
        public Object readResolve(){
            System.out.println("===");
            return instance;
        }
    }
    
    

    文章内容为个人学习总结,如有错误望指正。
    参考链接https://www.bilibili.com/video/BV1Np4y1z7BU

    展开全文
  • 这种类型的设计模式属于结构模式,它是作为现有一个包装。这种模式创建了一个装饰类,用来包装原有类,并在保持类方法签名完整性前提下,提供了额外功能。设计原则要使用装饰者模式,需要满足以下设计...

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

    这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

    设计原则

    要使用装饰者模式,需要满足以下设计原则: 
    1、多用组合,少用继承 
    2、开放-关闭原则:类应该对拓展开放,对修改关闭

    UML类图

    由上自下: 
    1、Component是基类。通常是一个抽象类或者一个接口,定义了属性或者方法,方法的实现可以由子类实现或者自己实现。通常不会直接使用该类,而是通过继承该类来实现特定的功能,它约束了整个继承树的行为。比如说,如果Component代表人,即使通过装饰也不会使人变成别的动物。 
    2、ConcreteComponent是Component的子类,实现了相应的方法,它充当了“被装饰者”的角色。 
    3、Decorator也是Component的子类,它是装饰者共同实现的抽象类(也可以是接口)。比如说,Decorator代表衣服这一类装饰者,那么它的子类应该是T恤、裙子这样的具体的装饰者。 

    4、ConcreteDecorator是Decorator的子类,是具体的装饰者,由于它同时也是Component的子类,因此它能方便地拓展Component的状态(比如添加新的方法)。每个装饰者都应该有一个实例变量用以保存某个Component的引用,这也是利用了组合的特性。在持有Component的引用后,由于其自身也是Component的子类,那么,相当于ConcreteDecorator包裹了Component,不但有Component的特性,同时自身也可以有别的特性,也就是所谓的装饰

    public interface ICar {
        void move();
    }
    
    class Car implements ICar {
        @Override
        public void move() {
            System.out.println("陆地上跑!");
        }
    }
    //Decorator装饰角色
    class SuperCar implements ICar {
        protected ICar car;
        public SuperCar(ICar car) {
            super();
            this.car = car;
        }
    
        @Override
        public void move() {
            car.move();
        }
    }
    //ConcreteDecorator具体装饰角色
    class FlyCar extends SuperCar {
    
        public FlyCar(ICar car) {
            super(car);
        }
    
        public void fly(){
            System.out.println("天上飞!");
        }
    
        @Override
        public void move() {
            super.move();
            fly();
        }
    
    }
    class WaterCar extends SuperCar {
    
        public WaterCar(ICar car) {
            super(car);
        }
        public void swim(){
            System.out.println("水上游!");
        }
        @Override
        public void move() {
            super.move();
            swim();
        }
    }
    //ConcreteDecorator具体装饰角色
    class AICar extends SuperCar {
    
        public AICar(ICar car) {
            super(car);
        }
        public void autoMove(){
            System.out.println("自动跑!");
        }
        @Override
        public void move() {
            super.move();
            autoMove();
        }
    }
    public class Client {
        public static void main(String[] args) {
            Car car  = new Car();
            car.move();
    
            System.out.println("增加新的功能,飞行----------");
            FlyCar flycar = new FlyCar(car);
            flycar.move();
    
            System.out.println("增加新的功能,水里游---------");
            WaterCar  waterCar = new WaterCar(car);
            waterCar.move();
    
            System.out.println("增加两个新的功能,飞行,水里游-------");
            WaterCar waterCar2 = new WaterCar(new FlyCar(car));
            waterCar2.move();
    
        }
    }
    
    陆地上跑!
    增加新的功能,飞行----------
    陆地上跑!
    天上飞!
    增加新的功能,水里游---------
    陆地上跑!
    水上游!
    增加两个新的功能,飞行,水里游-------
    陆地上跑!
    天上飞!
    水上游!
    展开全文
  • 这种类型的设计模式属于创建型模式,它提供了一种创建对象最佳方式。 这种模式涉及到一个单一类,该类负责创建自己对象,同时确保只有单个对象被创建。 这个类提供了一种访问其唯一对象方式,可以直接...
  • 设计模式

    2021-03-25 09:58:56
    设计模式 GoF 在《设计模式》 一种归纳了23种设计模式,而他们又属于三种类型模式,分别是 创建者模式、结构型模式 和 行为型模式。 这23种设计模式主要是基于以下的对象设计原则...创建型设计模式主要解决“对象
  • 这种类型的设计模式属于创建型模式,它提供了一种创建对象最佳方式。这种模式涉及到一个单一类,该类负责创建自己对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一对象方式,可以直接访问,...
  • 这种类型的设计模式属于创建型模式。定义为:保证一个类仅有一个实例,并提供一个访问它全局访问点。 单例模式一般体现在类声明中,单例类负责创建自己对象,同时确保只有单个对象被创建。这个类提供了一种...
  • 单例设计模式

    2021-03-11 18:40:23
    这种类型的设计模式属于创建型模式,它提供了一种创建对象最佳方式。 这种模式涉及到一个单一类,该类负责创建自己对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一对象方式,可以直接访问...
  • 设计模式之装饰模式

    2019-08-14 13:40:14
    这种类型的设计模式属于结构模式(结构模式设计,它关注类和对象组合。继承这一概念被用来组合接口和定义组合对象获得新功能方式。它包括以下几种具体的设计模式:适配器模式、桥接模式、过滤器模式、组合...
  • 设计模式之工厂模式

    2021-01-21 07:25:18
    工厂模式属于创建型模式 创建型模式的关注点是“怎样创建对象”,他将对象的创建与使用分离。这样做可以降低系统的耦合度,使用者需要关系对象创建的细节,对象的创建工作由相关工厂来完成。 由上图可知,创建...
  • 这种类型的设计模式属于创建型模式,它提供了一种创建对象最佳方式。 这种设计模式涉及到一个单一类,该类负责创建自己对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一对象方式。可以直接...
  • 适配器模式是指将一个类接口转换为用户期望另一个接口,使原本接口兼容类可以一起工作,属于结构型设计模式。 适配器模式适用于以下几种业务场景: 1.已经存在方法和需求匹配(方法相同或相似)...
  • 引言:工厂模式是最常见一类创建型设计模式,它包括以下三种具体设计模式: 简单工厂模式 工厂方法模式 抽象工厂模式 我们通常所说工厂模式是指工厂方法模式,它是使用频率最高工厂模式,而简单工厂模式...
  • 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类实例。简单工厂模式是工厂模式家族中最简单...
  • 这种类型的设计模式属于创建型模式,它提供了一种创建对象最佳方式。 这种模式涉及到一个单一类,该类负责创建自己对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一对象方式,可以直接访问...
  • 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类实例。简单工厂模式是工厂模式家族中最简单...
  • 设计模式—单例模式

    热门讨论 2020-10-24 19:59:13
    单例模式是设计模式的一种,属于创建型模式。这种模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。 一.单例的实现主要是通过以下两个步骤: 将该类的构造方法定义为私有方法,这样其他处的代码就...
  • 设计模式在Java中是非常重要.一共有23种设计模式....创建型模式用来处理对象创建过程,主要包含以下5种设计模式:  工厂方法模式(Factory Method Pattern)  抽象工厂模式(Abstract Facto
  • 适配器模式(Adapter Pattern)是指将一个类接口转换成用户期望另一个接口,使原本接口兼容类可以一起工作,属于结构型设计模式。适配器模式适用于以下集中业务场景: 已经存在方法和需求匹配...
  • 定义:从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。  简单工厂模式是由一个工厂对象决定创建...
  • 设计模式之单例

    2019-07-05 13:57:04
    单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一,这种类型的设计模式属于创建型模式。这种模式涉及到一个单一类,该类负责创建自己对象,同时确保只有单个对象被创建。这个类提供了一种访问其...
  • 我们讨论的设计模式将划分以下5类: ①接口行模式 ②职责模式 ③构造型模式 :通过类构造函数来创建对象,使用特定模式来为客户类创建实例对象 ④操作模式 ⑤扩展模式 工厂模式—属于构造型模式分类 在...
  • 简单工厂模式属于创建型模式,又叫做静态工厂方法模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类实例。调用只需要告诉工厂类所需要类型,工厂类就会返回需要产品类工厂子类。可以说是工厂类中...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 169
精华内容 67
关键字:

以下不属于创建型设计模式的是