聊一聊:设计模式——原型模式

114 阅读3分钟

你好,我是风一样的树懒,一个工作十多年的后端专家,曾就职京东、阿里等多家互联网头部企业。公众号“吴计可师”,已经更新了近百篇高质量的面试相关文章,喜欢的朋友欢迎关注点赞

原型模式详解

一、定义与核心思想 原型模式(Prototype Pattern)是一种创建型设计模式,通过复制现有对象来生成新对象,而非通过类实例化。其核心在于实现一个原型接口,声明克隆方法,使得对象能够自我复制,从而避免重复初始化带来的开销。

二、结构组成

  1. 原型接口(Prototype):声明克隆方法,通常为clone()
  2. 具体原型类(Concrete Prototype):实现克隆方法,复制自身。
  3. 客户端(Client):通过复制原型对象创建新实例。

三、实现方式

  1. 浅拷贝:复制对象及基本类型字段,引用字段共享原对象地址。

    public class ShallowPrototype implements Cloneable {
        private List<String> items = new ArrayList<>();
        
        public void addItem(String item) {
            items.add(item);
        }
        
        @Override
        public ShallowPrototype clone() throws CloneNotSupportedException {
            return (ShallowPrototype) super.clone(); // 浅拷贝,items引用共享
        }
    }
    
  2. 深拷贝:递归复制所有引用对象,确保数据独立性。

    public class DeepPrototype implements Cloneable {
        private List<String> items = new ArrayList<>();
        
        @Override
        public DeepPrototype clone() throws CloneNotSupportedException {
            DeepPrototype copy = (DeepPrototype) super.clone();
            copy.items = new ArrayList<>(this.items); // 手动复制列表元素
            return copy;
        }
    }
    

四、应用场景

  • 资源消耗大对象:如数据库连接配置,避免重复初始化。
  • 动态状态保存:游戏存档、文档历史版本。
  • 复杂对象生成:GUI控件、多层级配置对象。

五、优缺点分析

  • 优点
    • 性能优化,绕过构造器直接复制二进制流。
    • 动态添加产品类,客户端仅依赖接口。
    • 简化对象创建逻辑,尤其适用于复杂对象。
  • 缺点
    • 深拷贝实现复杂,尤其循环引用需特殊处理。
    • 需为每个类实现克隆方法,增加维护成本。

六、经典案例 场景:游戏角色装备系统

  • 需求:玩家创建新角色时,复用基础属性模板,但独立装备库。
  • 实现
    // 原型接口
    interface CharacterPrototype extends Cloneable {
        CharacterPrototype clone() throws CloneNotSupportedException;
    }
    
    // 具体原型类
    class GameCharacter implements CharacterPrototype {
        private String name;
        private List<String> equipment = new ArrayList<>();
    
        public GameCharacter(String name) {
            this.name = name;
            loadDefaultEquipment(); // 耗时操作:从文件加载默认装备
        }
    
        private void loadDefaultEquipment() {
            equipment.add("青铜剑");
            equipment.add("布甲");
        }
    
        @Override
        public GameCharacter clone() throws CloneNotSupportedException {
            GameCharacter copy = (GameCharacter) super.clone();
            copy.equipment = new ArrayList<>(this.equipment); // 深拷贝装备列表
            return copy;
        }
    
        public void addEquipment(String item) {
            equipment.add(item);
        }
    }
    
    // 客户端使用
    public class Client {
        public static void main(String[] args) throws Exception {
            GameCharacter prototype = new GameCharacter("战士模板");
            GameCharacter player1 = prototype.clone();
            player1.addEquipment("火焰戒指");
            
            GameCharacter player2 = prototype.clone();
            System.out.println(player2.getEquipment()); // 输出:[青铜剑, 布甲]
        }
    }
    

七、进阶应用:原型管理器 管理多个原型,便于按需获取。

public class PrototypeManager {
    private Map<String, CharacterPrototype> prototypes = new HashMap<>();
    
    public void register(String key, CharacterPrototype proto) {
        prototypes.put(key, proto);
    }
    
    public CharacterPrototype create(String key) throws CloneNotSupportedException {
        return prototypes.get(key).clone();
    }
}

// 注册不同职业原型
PrototypeManager manager = new PrototypeManager();
manager.register("warrior", new GameCharacter("战士"));
manager.register("mage", new GameCharacter("法师"));

// 快速生成角色
GameCharacter newWarrior = (GameCharacter) manager.create("warrior");

八、注意事项

  1. 深拷贝实现:使用序列化/反序列化(如Java的ObjectOutputStream)或手动逐层复制。
  2. Cloneable接口:Java中需实现Cloneable标记接口,否则clone()抛出异常。
  3. 性能权衡:深拷贝可能带来额外开销,需根据场景选择浅拷贝或深拷贝。

九、与其他模式对比

  • 工厂模式:关注类实例化过程;原型模式关注对象复制。
  • 单例模式:限制实例数量;原型模式旨在快速生成副本。

总结 原型模式通过对象自我复制,高效解决复杂对象创建问题,尤其适用于初始化成本高或需动态配置的场景。合理选择深/浅拷贝,结合原型管理器,可显著提升系统灵活性与性能。

今天文章就分享到这儿,喜欢的朋友可以关注我的公众号,回复“进群”,可进免费技术交流群。博主不定时回复大家的问题。 公众号:吴计可师

qrcode_for_gh_79f35896a87f_258.jpg