[技术干货] 原型模式 rust和java的实现
原型模式
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时或者相同的对象需要被重复创建时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。另一个例子,在考试中,每个人做的试卷是相同的,但是试卷却又成千上万份,我们不可能每次都手打一份试卷,因此第一份编排好的试卷就是原型,其他的都是她的复制。
介绍
- 意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
- 主要解决:创建相同却又互相独立的对象,就像试卷每个人的试卷相同,但是每个人的答案却又不同。
- 何时使用: 1、当一个系统应该独立于它的产品创建,构成和表示时。 2、当要实例化的类是在运行时刻指定时,例如,通过动态装载。 3、为了避免创建一个与产品类层次平行的工厂类层次时。 4、当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
- 如何解决:利用已有的一个原型对象,快速地生成和原型对象一样的实例。
- 关键代码: 1、实现克隆操作,在 JAVA 实现 Cloneable 接口,重写 clone(),在 rust中可以使用clone() 方法来实现对象的深拷贝。
- 应用实例: 1、细胞分裂。 2、考试中为每个考生分发相同的试卷。
优点
1、性能提高。
2、逃避构造函数的约束。
缺点
1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。
使用场景
1、资源优化场景。
2、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。 3、性能和安全要求的场景。
4、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。 5、一个对象多个修改者的场景。
6、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
7、在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者。
实现
我们将创建一个抽象类 Shape 和扩展了 Shape 类的实体类。下一步是定义类 ShapeCache,该类把 shape 对象存储在一个 Hashtable 中,并在请求的时候返回它们的克隆。
PrototypePatternDemo 类使用 ShapeCache 类来获取 Shape 对象。
原型模式的 UML 图
rust 实现
rsut中的clone实现起来比较简单,只需要为类添加clone属性编译器就能为我们实现默认的colon方式。
#[derive(Clone)]
struct Shape{
id:String,
mtype:String
}
impl Shape{
fn set_id(&mut self,id:String){
self.id=id;
}
fn get_id(&self)->&str{
&self.id
}
}
#[derive(Clone)]
struct Rectangle{
shape:Shape
}
impl Rectangle {
fn new()->Rectangle {
Rectangle{shape:Shape{
id:String::from("value"),
mtype:String::from("Rectangle")
}}
}
fn draw() {
println!("Inside Rectangle::draw() method.");
}
}
#[derive(Clone)]
struct Square {
shape:Shape
}
impl Square {
fn new()->Square {
Square {shape:Shape{
id:String::from("value"),
mtype:String::from("Square ")
}}
}
fn draw() {
println!("Inside Square ::draw() method.");
}
}
#[derive(Clone)]
struct Circle {
shape:Shape
}
impl Circle {
fn new()->Circle {
Circle {shape:Shape{
id:String::from("value"),
mtype:String::from("Square ")
}}
}
fn draw() {
println!("Inside Circle ::draw() method.");
}
}
fn main(){
let s=Circle::new();
let mut s1=s.clone();
s1.shape.set_id(String::from("dsf"));
println!("{}",s.shape.id);
println!("{}",s1.shape.id);
}
rust代码仓库
https://github.com/onenewcode/design.git
本教程项目在bin文件夹下的prototype.rs文件中
- 点赞
- 收藏
- 关注作者
评论(0)