软件设计模式与体系结构-设计模式-生成模式&单例模式

二、生成器模式

1. 生成者模式

概念

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

生成器模式是一步一步创建一个复杂的对象

在这里插入图片描述

Director director = new Director();
director.setBuilder(cb);
director.construct();
if ( cb == 1 ) Product1 = director.getObject();
else Product 2 = director.getObject();

1.确定Director,成员为xxxBuilder(表示要用到的生成器的父类),方法有设置生成器,获取产品(getXXX),创建整个产品的方法(这个方法用来调用生成器的各个方法,最后生成一个完整的产品)指挥者类针对抽象生成器类编程
2.确定XXXBuilder,成员为产品,方法就是构建这个产品所有部件所需的方法,以及getXXX获取产品,以及初始化产品的方法(肯定要先new申明一个空的产品,赋值给成员变量里的产品)
3.确定具体的生成器类,继承自XXXBuilder
4.确定具体产品,成员和方法就是该产品所需的各种方法属性等

实例一:房屋选购系统
题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

时序图

在这里插入图片描述
只需要选择一个HouseBuilder,再调用构建的方法constructWholeHouse,再一个个调用生成部件的方法,调用设置参数方法,就能返回产品

类图

在这里插入图片描述

Director director = new Director();
director.setHouseBuilder( hb );
director.constructWholeHouseObj();
House hsObj = director.getHouse();
优缺点

优点

  1. 在生成器模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象
  2. 每一个具体生成器都相对独立,而与其他的具体生成器无关,因此可以很方便地替换具体生成器或增加新的具体生成器,用户使用不同的具体生成器即可得到不同的产品对象
  3. 可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
  4. 增加新的具体生成器无须修改原有类库的代码,指挥者类针对抽象生成器类编程,系统扩展方便,符合“开闭原则”

缺点

  1. 生成器模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用生成器模式,因此其使用范围受到一定的限制
  2. 如果产品的内部变化复杂,可能会导致需要定义很多具体生成器类来实现这种变化,导致系统变得很庞大
适用场景
  1. 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
  2. 需要生成的产品对象的属性相互依赖,需要指定其生成顺序
  3. 对象的创建过程独立于创建该对象的类。在生成器模式中引入了指挥者类,将创建过程封装在指挥者类中,而不在生成器类中
  4. 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。

2. 生成器模式与抽象工厂模式

  1. 与抽象工厂模式相比,生成器模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族
  2. 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在生成器模式中,客户端可以不直接调用生成器的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象。
  3. 如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么生成器模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车

3. 课程作业***

在这里插入图片描述
在这里插入图片描述

三、单例模式

1. 单例模式

单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供一个全局访问点

要点:

某个类只能有一个实例
它必须自行创建这个实例
它必须自行向整个系统提供这个实例

基本思路

在这里插入图片描述

instance是静态变量,类型为Singleton,用于存储已经被创建的实例。getInstance()为实例创建方法,它创建实例的方式很特别,如果一个实例此前已经被创建了(因而被存储在变量instance中),则该方法返回instance;如果此前Single实例没有被创建,则该方法新创建并且返回Singleton类的一个实例,从而保证了实例的唯一性。

Public class Singleton {
	private static Singleton instance;
	private String name;
	private Singleton (String name) {
		this.name = name;
	}
	public static Singleton getInstance (String name) {
		if (instance == null && ! name.equals(null))
			instance = new Singleton (name);
		return instance;
	}
}
实例一:互联网连接问题

在这里插入图片描述
在这里插入图片描述

2. 多线程情况

多线程中的单例模式,在getInstance()方法应声明为synchronized,防止当唯一实例尚未创建时有两个线程同时调用创建方法,那么将导致两个现成各自创建了一个实例,从而违反了单例模式的实例唯一性的初衷

在这里插入图片描述

3. 优缺点

优点

  1. 提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它,并为设计及开发团队提供了共享的概念
  2. 由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。
  3. 允许可变数目的实例。我们可以基于单例模式进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例

缺点

  1. 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难
  2. 单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起
  3. 滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;现在很多面向对象语言(如Java、C#)的运行环境都提供了自动垃圾回收的技术,因此,如果实例化的对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致对象状态的丢失

4. 适用场景

  1. 系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器,或者需要考虑资源消耗太大而只允许创建一个对象。
  2. 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。
  3. 在一个系统中要求一个类只有一个实例时才应当使用单例模式。反过来,如果一个类可以有几个实例共存,就需要对单例模式进行改进,使之成为多例模式

5. 课程作业

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VengaZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值