Один шаблон проектирования в день (4) — прототип

Java задняя часть Архитектура Шаблоны проектирования

предисловие

режим прототипапринадлежность к объектуСоздать схему. давпрототип объектадля указания всех созданных объектовтип, а затем используйте этопрототип объектакоторый предоставилМетод копированиясоздать большетого же типаОбъект.

Структура шаблона прототипа

режим прототипатребует, чтобы объект реализовалклонировать себяинтерфейс (тип). Таким образом, черезЭкземпляр прототипаСоздайте новый объект, вам не нужно заботиться об этомсам экземпляртип, нужно только реализоватьклонировать себяметод без прохожденияnewсоздавать.

Представление типов прототипов

  1. простая форма
  2. форма регистрации

текст

простая форма

Связанная роль

  1. Роль клиента:класс клиентаСделать запрос на создание объекта;
  2. Роль абстрактного прототипа (Prototype): это абстрактная роль, обычно состоящая изJavaинтерфейсилиJavaабстрактный классвыполнить. Эта роль определяет необходимые методы реализации конкретного класса-прототипа.
  3. Бетонная роль прототипа: Эта роль должна быть реализованароль абстрактного архетипаобязательныйСвязанные с клонированиемизинтерфейс.

образец кода

Prototype.java

/**
 * 抽象原型角色
 */
public abstract class Prototype {
    private String id;

    public Prototype(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    /**
     * 克隆自身的方法
     * @return 一个从自身克隆出来的对象。
     */
    public abstract Prototype clone();
}

ConcretePrototype1.java

public class ConcretePrototype1 extends Prototype {
    public ConcretePrototype1(String id) {
        super(id);
    }

    public Prototype clone() {
        Prototype prototype = new ConcretePrototype1(this.getId());
        return prototype;
    }
}

ConcretePrototype2.java

public class ConcretePrototype2 extends Prototype {
    public ConcretePrototype2(String id) {
        super(id);
    }

    public Prototype clone() {
        Prototype prototype = new ConcretePrototype2(this.getId());
        return prototype;
    }
}

результат операции

форма регистрации

Связанная роль

  1. Роль клиента:класс клиентаСделать запрос на создание объекта;
  2. Роль абстрактного прототипа (Prototype): это абстрактная роль, обычно состоящая изJavaинтерфейсилиJavaабстрактный классвыполнить. Эта роль определяет необходимые методы реализации конкретного класса-прототипа.
  3. Бетонная роль прототипа: Эта роль должна быть реализованароль абстрактного архетипаобязательныйСвязанные с клонированиемизинтерфейс.
  4. Роль менеджера прототипов: предоставлять различныепрототип объектаизСоздайтеиуправлять.

образец кода

КромеМенеджер прототиповPrototype Managerза пределами,Режим регистрациииПростой режимДругих отличий нет.

Prototype.java W

public interface Prototype {
    public Prototype clone();
    public String getName();
    public void setName(String name);
}

ConcretePrototype1.java

public class ConcretePrototype1 implements Prototype {
    private String name;

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public Prototype clone() {
        Prototype prototype = new ConcretePrototype1();
        prototype.setName(this.name);
        return prototype;
    }

    @Override
    public String toString() {
        return "ConcretePrototype1 [name=" + name + "]";
    }

}

ConcretePrototype2.java

public class ConcretePrototype2 implements Prototype {
    private String name;

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public Prototype clone() {
        Prototype prototype = new ConcretePrototype2();
        prototype.setName(this.name);
        return prototype;
    }

    @Override
    public String toString() {
        return "ConcretePrototype2 [name=" + name + "]";
    }
}

PrototypeManager.java

public class PrototypeManager {
    /**
     * 用来记录原型的编号同原型实例的对象关系
     */
    private static Map<String, Prototype> map = new HashMap<>();

    /**
     * 私有化构造方法,避免从外部创建实例
     */
    private PrototypeManager() {
    }

    /**
     * 向原型管理器里面添加或者修改原型实例
     *
     * @param prototypeId 原型编号
     * @param prototype   原型实例
     */
    public static void setProtoType(String prototypeId, Prototype prototype) {
        map.put(prototypeId, prototype);
    }

    /**
     * 根据原型编号从原型管理器里面移除原型实例
     *
     * @param prototypeId 原型编号
     */
    public static void removePrototype(String prototypeId) {
        map.remove(prototypeId);
    }

    /**
     * 根据原型编号获取原型实例
     *
     * @param prototypeId 原型编号
     * @return 原型实例对象
     * @throws Exception 如果根据原型编号无法获取对应实例,则提示异常“您希望获取的原型还没有注册或已被销毁”
     */
    public static Prototype getPrototype(String prototypeId) throws Exception {
        Prototype prototype = map.get(prototypeId);

        if (prototype == null) {
            throw new Exception("您希望获取的原型还没有注册或已被销毁");
        }

        return prototype;
    }

}

Client.java

public class Client {
    public static void main(String[] args) {
        try {
            // 创建第一个实例
            Prototype p1 = new ConcretePrototype1();
            // 注册第一个实例
            PrototypeManager.setProtoType("p1", p1);

            // 克隆第一个实例的原型
            Prototype p3 = PrototypeManager.getPrototype("p1").clone();
            p3.setName("张三");
            System.out.println("第一个实例的副本:" + p3);

            // 创建第二个实例
            Prototype p2 = new ConcretePrototype2();
            // 注册第二个实例
            PrototypeManager.setProtoType("p2", p2);

            // 克隆第二个实例的原型
            Prototype p4 = PrototypeManager.getPrototype("p2").clone();
            p4.setName("李四");
            System.out.println("第二个实例的副本:" + p4);

            // 注销第一个实例
            PrototypeManager.removePrototype("p1");
            // 再次克隆第一个实例的原型
            Prototype p5 = PrototypeManager.getPrototype("p1").clone();
            p5.setName("王五");
            System.out.println("第一个实例的副本:" + p5);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

результат операции

сравнение между двумя

Шаблоны-прототипы в простой форме и зарегистрированной форме имеют свои сильные и слабые стороны.

  1. Если вы хотите создатьпрототип объектаданныеменьшеи сравнитефиксированный, ты можешь использоватьПервоеформа. В этом случае ссылка на объект-прототип может быть заданаклиентСохранить себя.
  2. Если вы хотите создатьпрототип объектаданныене зафиксировано, ты можешь использоватьсекундаформа. В этом случае у клиента нет ссылки на объект-прототип, эта задача передаетсяМенеджер прототиповРоль. Перед клонированием объекта клиент может проверить, есть ли у административного объекта объект-прототип, удовлетворяющий требованиям. Если да, то его можно получитьМенеджер прототиповПолучите ссылку на этот объект из роли; если нет, клиент долженсамокопированиеэтот прототип объекта.

Суммировать

Преимущества шаблонов-прототипов

Режим прототипа позволяет во время выполнениядинамичныйизменить конкретныеТип реализации. Режим прототипа можно найти вво время операции, есть клиент для регистрации типа реализации, соответствующего интерфейсу прототипа, и конкретный тип реализации также может быть динамически изменен.Вроде бы интерфейс не изменился, но на самом деле он уже работает с другой сущностью класса.Поскольку клонирование объекта-прототипа похоже на создание экземпляра класса.

Недостатки паттернов-прототипов

Основным недостатком шаблона-прототипа является то, что каждый класс должен быть оснащенМетод клонирования. Оснащение метода клонирования требует, чтобы функциональность класса былаРассмотрим весь, что не слишком сложно для нового класса, но не так просто для существующего класса.


Добро пожаловать в технический публичный аккаунт: Zero One Technology Stack

零壹技术栈

Эта учетная запись будет продолжать делиться сухими товарами серверных технологий, включая основы виртуальных машин, многопоточное программирование, высокопроизводительные фреймворки, асинхронное ПО, промежуточное ПО для кэширования и обмена сообщениями, распределенные и микросервисы, материалы для обучения архитектуре и расширенные учебные материалы и статьи.