解释
原型模式是一种创建型设计模式,它的核心思想是通过复制
一个已有
的对象来创建新的对象
,而不是通过构造函数或者工厂方法。这样可以避免重复的初始化操作,提高创建效率。
适用场景
原型模式适用于以下场景:
- 当创建对象的成本较高时,可以利用原型模式来缓存已有的对象,然后通过
克隆
来获取新的对象。 - 当需要创建大量相似或者相同的对象时,可以利用原型模式来减少重复代码,提高
可维护性
。 - 当需要动态地生成对象时,可以利用原型模式来根据不同的需求和条件来选择合适的原型进行
复制
。
优点
原型模式有以下优点:
- 可以提高创建效率,避免
重复的初始化操作
。 - 可以减少重复代码,提高
可维护性
。 - 可以增加系统的
灵活性
和扩展性
,可以动态地
生成对象。
缺点
原型模式也有以下缺点:
- 需要实现克隆方法,并且注意
深拷贝
和浅拷贝
的区别。 - 需要维护一个原型注册表,并且注意
线程安全
问题。 - 可能会违反
开闭原则
,如果修改了原型类,则需要修改所有依赖于该类的代码。
代码实现
PHP
// 声明一个网站原型类
class WebsitePrototype
{
protected $name;
protected $category;
// 设置网站名称和分类
public function setName($name)
{
$this->name = $name;
}
public function setCategory($category)
{
$this->category = $category;
}
// 克隆方法,用于创建新的网站对象
public function clone()
{
return clone $this;
}
}
// 实例化一个网站原型对象
$prototype = new WebsitePrototype();
// 克隆多个网站对象并设置不同的名称和分类
$site1 = $prototype->clone();
$site1->setName("Site 1");
$site1->setCategory("Blog");
$site2 = $prototype->clone();
$site2->setName("Site 2");
$site2->setCategory("E-commerce");
$site3 = $prototype->clone();
$site3->setName("Site 3");
$site3->setCategory("Social Network");
// 打印各个网站对象的名称和分类
echo "Site 1: " . $site1->getName() . " (" . $site1->getCategory() . ")\n";
echo "Site 2: " . $site2->getName() . " (" . $site2->getCategory() . ")\n";
echo "Site 3: " . $site3->getName() . " (" . $site3->getCategory() . ")\n";
Go
package main
import "fmt"
// 网站原型结构体
type WebsitePrototype struct {
name string
category string
}
// 设置网站名称和分类
func (wp *WebsitePrototype) setName(name string) {
wp.name = name
}
func (wp *WebsitePrototype) setCategory(category string) {
wp.category = category
}
// 克隆方法,用于创建新的网站对象
func (wp *WebsitePrototype) clone() *WebsitePrototype {
return &WebsitePrototype{
name: wp.name,
category: wp.category,
}
}
func main() {
// 实例化一个网站原型对象
prototype := &WebsitePrototype{}
// 克隆多个网站对象并设置不同的名称和分类
site1 := prototype.clone()
site1.setName("Site 1")
site1.setCategory("Blog")
site2 := prototype.clone()
site2.setName("Site 2")
site2.setCategory("E-commerce")
site3 := prototype.clone()
site3.setName("Site 3")
site3.setCategory("Social Network")
// 打印各个网站对象的名称和分类
fmt.Printf("Site 1: %s (%s)\n", site1.name, site1.category)
fmt.Printf("Site 2: %s (%s)\n", site2.name, site2.category)
fmt.Printf("Site 3: %s (%s)\n", site3.name, site3.category)
}
Java
import java.util.HashMap;
import java.util.Map;
// 网站原型类
abstract class WebsitePrototype {
protected String name;
protected String category;
public abstract WebsitePrototype clone();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
// 具体网站类
class Blog extends WebsitePrototype {
public Blog(String name, String category) {
this.name = name;
this.category = category;
}
public Blog(Blog blog) {
this.name = blog.name;
this.category = blog.category;
}
@Override
public WebsitePrototype clone() {
return new Blog(this);
}
}
class ECommerce extends WebsitePrototype {
public ECommerce(String name, String category) {
this.name = name;
this.category = category;
}
public ECommerce(ECommerce ecommerce) {
this.name = ecommerce.name;
this.category = ecommerce.category;
}
@Override
public WebsitePrototype clone() {
return new ECommerce(this);
}
}
class SocialNetwork extends WebsitePrototype {
public SocialNetwork(String name, String category) {
this.name = name;
this.category = category;
}
public SocialNetwork(SocialNetwork socialNetwork) {
this.name = socialNetwork.name;
this.category = socialNetwork.category;
}
@Override
public WebsitePrototype clone() {
return new SocialNetwork(this);
}
}
// 网站原型管理器类
class WebsitePrototypeManager {
private static Map<String, WebsitePrototype> websitePrototypes = new HashMap<>();
public static void addWebsitePrototype(String key, WebsitePrototype prototype) {
websitePrototypes.put(key, prototype);
}
public static WebsitePrototype getWebsitePrototype(String key) {
return websitePrototypes.get(key).clone();
}
}
public class PrototypePatternExample {
public static void main(String[] args) {
// 实例化三种类型的网站原型
Blog blogPrototype = new Blog("", "");
ECommerce ecommercePrototype = new ECommerce("", "");
SocialNetwork socialNetworkPrototype = new SocialNetwork("", "");
// 将三种类型的网站原型加入网站原型管理器
WebsitePrototypeManager.addWebsitePrototype("blog", blogPrototype);
WebsitePrototypeManager.addWebsitePrototype("ecommerce", ecommercePrototype);
WebsitePrototypeManager.addWebsitePrototype("socialnetwork", socialNetworkPrototype);
// 通过网站原型管理器获取相应类型的网站对象并设置名称和分类
Blog blog1 = (Blog) WebsitePrototypeManager.getWebsitePrototype("blog");
blog1.setName("Blog 1");
blog1.setCategory("Blog");
ECommerce ecommerce1 = (ECommerce) WebsitePrototypeManager.getWebsitePrototype("ecommerce");
ecommerce1.setName("E-commerce 1");
ecommerce1.setCategory("E-commerce");
SocialNetwork socialNetwork1 = (SocialNetwork) WebsitePrototypeManager.getWebsitePrototype("socialnetwork");
socialNetwork1.setName("Social Network 1");
socialNetwork1.setCategory("Social Network");
// 打印各个网站对象的名称和分类
System.out.println("Blog 1: " + blog1.getName() + " (" + blog1.getCategory() + ")");
System.out.println("E-commerce 1: " + ecommerce1.getName() + " (" + ecommerce1.getCategory() + ")");
System.out.println("Social Network 1: " + socialNetwork1.getName() + " (" + socialNetwork1.getCategory() + ")");
}
}