【创建型】原型模式

现在我们有这样一个需求。在后台输入一批学生的信息以后,封装成一个列表(List ),传送给前台打印出来。

这是第一版。

/**
  * 这是最开始的Student 类
  */

public class Student1 {

   private String name;
   private int age;
   private String teacher;
   private String major;  

   // 各种setter 和getter

} 
 

 

/**
 * 第一个场景类:按照一开始的想法做的一个场景 ,现在我们是要把一批学生给记录到一个list里面,然后在页面打印出来
 */

public class Client1 {
	
	public static void main(String[] args) {
		List<Student1> list = new ArrayList<Student1>();// 建立存储学生信息的列表
		Student1 student = new Student1();// 定义一个学生,接下来写好一样的信息
		student.setAge(21);
		student.setMajor("计算机");
		student.setTeacher("黄大牛");
		for (int i = 0; i < 10; i++) {
			student.setName(RandomGenerator.getRandomLetters());
			list.add(student);// 添加到列表中
		}
		System.out.println("将在页面上" + list.size() + "条记录,内容如下");
		// 将列表返回给界面显示
		for (Student1 _student : list) {
			System.out.println("名字为 " + _student.getName() + " 的 "
					+ _student.getMajor() + " 学院学生已经打印到界面");
		}
	}
	
}
 

结果如下:

 

将在页面上10条记录,内容如下
名字为 YdIkJf 的 计算机 学院学生已经打印到界面
名字为 YdIkJf 的 计算机 学院学生已经打印到界面
名字为 YdIkJf 的 计算机 学院学生已经打印到界面
名字为 YdIkJf 的 计算机 学院学生已经打印到界面
名字为 YdIkJf 的 计算机 学院学生已经打印到界面
名字为 YdIkJf 的 计算机 学院学生已经打印到界面
名字为 YdIkJf 的 计算机 学院学生已经打印到界面
名字为 YdIkJf 的 计算机 学院学生已经打印到界面
名字为 YdIkJf 的 计算机 学院学生已经打印到界面
名字为 YdIkJf 的 计算机 学院学生已经打印到界面
 

很明显,在list 里面用add() 方法是记下引用,而这个实际上的对象一直在变,所以所有的引用实际上都是指向同一个对象,结果当然是这样子。

得说题目要求就是返回一个列表,所以想在第一个循环里面打印的想法取消掉。那么只能这么改了。

		for (int i = 0; i < 10; i++) {
			Student1 student = new Student1();// 定义一个学生,接下来写好一样的信息
			student.setAge(21);
			student.setMajor("计算机");
			student.setTeacher("黄大牛");
			student.setName(RandomGenerator.getRandomLetters());
			list.add(student);// 添加到列表中
		}
 

的确能达到要求了,但是实际上造成了很多重复性动作,如果循环次数多,对象就成爆炸式增长。在这个情形下有了原型模式。事实上在开发中会经常有这样的情况,一个类需要做多次的数据库存储,但是每条记录又只是差那么一丁点,这时候就可以用原型模式了。

clone() 方法是基类Object 的一个方法,利用这个方法实现对象的复制。

修改后的代码如下:

/**
 * 这是修改以后的Student类
 */
public class Student2 implements Cloneable {
	
	private String name;
	private int age;
	private String teacher;
	private String major;
	
	public Student2 clone() {
		Student2 student = null;
		try {
			student = (Student2) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return student;
	}

	//各种setter()和getter()
}
 
	public static void main(String[] args) {
		List<Student2> list = new ArrayList<Student2>();// 建立存储学生信息的列表
		Student2 student = new Student2();// 定义一个学生,接下来写好一样的信息
		student.setAge(21);
		student.setMajor("计算机");
		student.setTeacher("黄大牛");
		for (int i = 0; i < 10; i++) {// 以下是各个学生不同的地方
			Student2 _student = student.clone();
			_student.setName(RandomGenerator.getRandomLetters());
			list.add(_student);// 添加到列表中
		}
		System.out.println("将在页面上" + list.size() + "条记录,内容如下");
		// 将列表返回给界面显示
		for (Student2 _student : list) {
			System.out.println("名字为 " + _student.getName() + " 的 "
					+ _student.getMajor() + " 学院学生已经打印到界面");
		}
	}
 

 

这就是原型模式(Prototype Pattern )了。事实上这非常容易理解,也没什么难度,那么它有什么好处呢。貌似这也是对象的大量生成? 有什么好处?

1.     原型模式是在内存中做对象的复制,性能上比实例化一个对象要好很多;

2.     不希望初始化的时候要写构造方法的时候。

什么场景需要用到呢?

需要在频繁new 一个对象的时候,可以用到;一个对象需要提供给很多对象访问而且各个调用者都可能需要修改它的值的时候;……

浅拷贝和深拷贝的区别?

Java 在执行clone() 方法的时候,只是在内存中分配跟主对象一模一样的内存块,那有什么是包含在这个内存块里面的呢。有基本数据类型(String 很特殊的被包括了)和引用,还有不可变对象(final )。但是引用的对象是不在的!这就出现了一个问题,对于被引用的东西,拷贝出来以后实际上被几个对象(包括原来的对象和拷贝出来的对象)共享着,这就不算真正意义上的拷贝了!因为实际生产中很多类不只是基本数据类型。这就是浅拷贝

那么我们应该怎么实现深拷贝 呢?其实很简单,在clone() 方法里面重新生成一个就是了。下面给出一段代码 :

浅拷贝 :跟我们之前的做法一样。

public class Student3 implements Cloneable {
	
	private School school;
	
	@Override
	public Student3 clone() {
		Student3 student = null;
		try {
			student = (Student3) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return student;
	}
	
}

  

深拷贝 :在clone() 方法中也要重新克隆一个。

	@Override
	public Student3 clone() {
		Student3 student = null;
		try {
			student = (Student3) super.clone();
			student.school = (School) school.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return student;
	}
 

事实上这个引用对象也必须实现clone() 方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
GeoPandas是一个开源的Python库,旨在简化地理空间数据的处理和分析。它结合了Pandas和Shapely的能力,为Python用户提供了一个强大而灵活的工具来处理地理空间数据。以下是关于GeoPandas的详细介绍: 一、GeoPandas的基本概念 1. 定义 GeoPandas是建立在Pandas和Shapely之上的一个Python库,用于处理和分析地理空间数据。 它扩展了Pandas的DataFrame和Series数据结构,允许在其中存储和操作地理空间几何图形。 2. 核心数据结构 GeoDataFrame:GeoPandas的核心数据结构,是Pandas DataFrame的扩展。它包含一个或多个列,其中至少一列是几何列(geometry column),用于存储地理空间几何图形(如点、线、多边形等)。 GeoSeries:GeoPandas中的另一个重要数据结构,类似于Pandas的Series,但用于存储几何图形序列。 二、GeoPandas的功能特性 1. 读取和写入多种地理空间数据格式 GeoPandas支持读取和写入多种常见的地理空间数据格式,包括Shapefile、GeoJSON、PostGIS、KML等。这使得用户可以轻松地从各种数据源中加载地理空间数据,并将处理后的数据保存为所需的格式。 2. 地理空间几何图形的创建、编辑和分析 GeoPandas允许用户创建、编辑和分析地理空间几何图形,包括点、线、多边形等。它提供了丰富的空间操作函数,如缓冲区分析、交集、并集、差集等,使得用户可以方便地进行地理空间数据分析。 3. 数据可视化 GeoPandas内置了数据可视化功能,可以绘制地理空间数据的地图。用户可以使用matplotlib等库来进一步定制地图的样式和布局。 4. 空间连接和空间索引 GeoPandas支持空间连接操作,可以将两个GeoDataFrame按照空间关系(如相交、包含等)进行连接。此外,它还支持空间索引,可以提高地理空间数据查询的效率。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值