前言
目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
本节给大家讲一下设计模式中的原型模式,并结合实际业务场景给大家讲解如何使用~
本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~
原型模式
原型模式是一种创建型设计模式,它通过复制(克隆)已有对象的实例来创建新的对象实例,而无需调用构造函数。这种方式可以提高对象创建的效率,同时也可以避免对象构造函数中的复杂逻辑。
原型模式的核心是一个原型接口,通常包含一个 clone() 方法,用于克隆对象。具体原型对象实现该接口并实现clone()方法,可以将自身复制一份并返回给调用者。客户端通过克隆一个原型对象来创建新的对象实例。
原型模式有两种实现方式:深克隆和浅克隆。深克隆会克隆对象及其内部引用的所有对象,而浅克隆只会克隆对象本身,不会克隆内部引用的对象。
接下来,我们一起看下:
public interface Prototype {
Prototype clone();
}
class ConcretePrototype implements Prototype {
private String name;
public ConcretePrototype(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public Prototype clone() {
return new ConcretePrototype(name);
}
}
class Client {
public static void main(String[] args) {
ConcretePrototype prototype = new ConcretePrototype("prototype");
ConcretePrototype clone = (ConcretePrototype) prototype.clone();
System.out.println("Prototype: " + prototype.getName());
System.out.println("Clone: " + clone.getName());
}
}
在上面的示例代码中,我们定义了一个原型接口 Prototype 和一个具体原型类 ConcretePrototype。ConcretePrototype 实现了 Prototype 接口,并重写了 clone() 方法。在 Client 类中,我们创建了一个 ConcretePrototype 对象,并克隆了它。我们可以看到,克隆出来的对象与原始对象具有相同的属性值。
原型模式在实际应用中可以帮助我们避免重复创建相似对象,提高程序的效率。同时,它也可以避免直接使用构造函数来创建对象时可能会遇到的一些问题,例如构造函数中的复杂逻辑。
最佳实践
我们依然以一个电商平台的例子给大家讲解下如何使用。
假设我们正在开发一个电商网站,需要提供商品推荐功能。在这个功能中,我们需要根据用户的历史浏览记录和购买记录,推荐出一些相关的商品。
为了实现这个功能,我们可以使用原型模式来创建商品推荐的原型对象。该原型对象包含了一些基本的推荐规则和算法,可以根据用户的历史记录生成推荐的商品列表。
下面是一个简单的实现示例:
首先定义一个商品推荐的原型接口 ProductRecommendation:
public interface ProductRecommendation {
List<Product> getRecommendations(List<Product> userHistory);
ProductRecommendation clone();
}
接着实现该接口的具体原型类 ConcreteProductRecommendation:
public class ConcreteProductRecommendation implements ProductRecommendation {
private int maxRecommendations;
public ConcreteProductRecommendation(int maxRecommendations) {
this.maxRecommendations = maxRecommendations;
}
public void setMaxRecommendations(int maxRecommendations) {
this.maxRecommendations = maxRecommendations;
}
public ConcreteProductRecommendation(ConcreteProductRecommendation source) {
this.maxRecommendations = source.maxRecommendations;
}
@Override
public List<Product> getRecommendations(List<Product> userHistory) {
// 根据用户历史记录生成推荐商品列表的具体实现
// ...
return userHistory;
}
@Override
public ProductRecommendation clone() {
return new ConcreteProductRecommendation(this);
}
}
在 ConcreteProductRecommendation 类中,我们定义了一个 maxRecommendations 属性,表示最大推荐商品数量。在 getRecommendations 方法中,我们根据用户的历史记录生成推荐商品列表。在 clone 方法中使用 new 操作符创建新的对象,并将属性值复制到新对象中:
最后,我们可以在客户端代码中使用原型模式来创建商品推荐的原型对象,并根据用户历史记录生成推荐的商品列表:
public class Client {
public static void main(String[] args) {
// 创建商品推荐原型对象
ConcreteProductRecommendation prototype = new ConcreteProductRecommendation(5);
// 根据用户历史记录生成推荐商品列表
List<Product> userHistory = new ArrayList<>();
userHistory.add(new Product("product1"));
userHistory.add(new Product("product2"));
userHistory.add(new Product("product3"));
List<Product> recommendations = prototype.getRecommendations(userHistory);
// 克隆原型对象并修改属性值
ConcreteProductRecommendation clone = (ConcreteProductRecommendation) prototype.clone();
clone.setMaxRecommendations(10);
// 根据用户历史记录生成推荐商品列表
List<Product> userHistory2 = new ArrayList<>();
userHistory2.add(new Product("product4"));
userHistory2.add(new Product("product5"));
userHistory2.add(new Product("product6"));
List<Product> recommendations2 = clone.getRecommendations(userHistory2);
// 输出推荐商品列表
System.out.println("Recommendations 1:");
for (Product recommendation : recommendations) {
System.out.println(recommendation.getName());
}
System.out.println("Recommendations 2:");
for (Product recommendation : recommendations2) {
System.out.println(recommendation.getName());
}
}
}
总之,原型模式可以帮助我们快速创建相似的对象,提高程序的效率和灵活性。大家可以思考一下,结合之前讲的设计模式原则~
结束语
设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲适配器模式~
本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~
相关文章
项目源码(源码已更新 欢迎star⭐️)
Kafka 专题学习
- 一起来学kafka之Kafka集群搭建
- 一起来学kafka之整合SpringBoot基本使用
- 一起来学kafka之整合SpringBoot深入使用(一)
- 一起来学kafka之整合SpringBoot深入使用(二)
- 一起来学kafka之整合SpringBoot深入使用(三)
项目源码(源码已更新 欢迎star⭐️)
ElasticSearch 专题学习
项目源码(源码已更新 欢迎star⭐️)
往期并发编程内容推荐
- Java多线程专题之线程与进程概述
- Java多线程专题之线程类和接口入门
- Java多线程专题之进阶学习Thread(含源码分析)
- Java多线程专题之Callable、Future与FutureTask(含源码分析)
- 面试官: 有了解过线程组和线程优先级吗
- 面试官: 说一下线程的生命周期过程
- 面试官: 说一下线程间的通信
- 面试官: 说一下Java的共享内存模型
- 面试官: 有了解过指令重排吗,什么是happens-before
- 面试官: 有了解过volatile关键字吗 说说看
- 面试官: 有了解过Synchronized吗 说说看
- Java多线程专题之Lock锁的使用
- 面试官: 有了解过ReentrantLock的底层实现吗?说说看
- 面试官: 有了解过CAS和原子操作吗?说说看
- Java多线程专题之线程池的基本使用
- 面试官: 有了解过线程池的工作原理吗?说说看
- 面试官: 线程池是如何做到线程复用的?有了解过吗,说说看
- 面试官: 阻塞队列有了解过吗?说说看
- 面试官: 阻塞队列的底层实现有了解过吗? 说说看
- 面试官: 同步容器和并发容器有用过吗? 说说看
- 面试官: CopyOnWrite容器有了解过吗? 说说看
- 面试官: Semaphore在项目中有使用过吗?说说看(源码剖析)
- 面试官: Exchanger在项目中有使用过吗?说说看(源码剖析)
- 面试官: CountDownLatch有了解过吗?说说看(源码剖析)
- 面试官: CyclicBarrier有了解过吗?说说看(源码剖析)
- 面试官: Phaser有了解过吗?说说看
- 面试官: Fork/Join 有了解过吗?说说看(含源码分析)
- 面试官: Stream并行流有了解过吗?说说看
推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)
博客(阅读体验较佳)
本文正在参加「金石计划」