Skip to content

目的

指定要使用原型实例创建的对象类型,并通过克隆这个原型来创建新对象。

解释

首先,应该注意,原型模式并不是用来获得性能优势的。只是用于从原型实例创建新对象。

真实世界例子

还记得多莉吗?克隆羊!我们先不谈细节,但关键是 这一切都与克隆有关。

简单地说

通过克隆的方式基于现有对象来创建一个对象。

维基百科说

原型模式是软件开发中的一种创造性设计模式。 当要创建的对象的类型由被克隆以生成新对象的原型实例所决定时,原型模式就会被使用

简而言之,它允许您创建现有对象的副本,并根据需要进行修改,而不是从头创建对象并进行设置

从零开始创建一个对象并进行设置。

编程示例

在Java中,建议按如下方式实现原型模式。 首先,创建一个具有克隆对象的方法的接口。在本例中,Prototype接口通过其copy方法实现这一点。

java
public interface Prototype {
  Object copy();
}

我们的示例包含不同生物的层次结构。例如,让我们看看'Beast'类和'Orcbast'类。

java
@EqualsAndHashCode
@NoArgsConstructor
public abstract class Beast implements Prototype {

  public Beast(Beast source) {
  }

  @Override
  public abstract Beast copy();
}

@EqualsAndHashCode(callSuper = false)
@RequiredArgsConstructor
public class OrcBeast extends Beast {

  private final String weapon;

  public OrcBeast(OrcBeast orcBeast) {
    super(orcBeast);
    this.weapon = orcBeast.weapon;
  }

  @Override
  public OrcBeast copy() {
    return new OrcBeast(this);
  }

  @Override
  public String toString() {
    return "Orcish wolf attacks with " + weapon;
  }
}

我们不想讨论太多细节,但完整的示例还包含基类“Mage”和“warrord”,除orcs外,还有专门针对elves的实现。

为了充分利用原型模式,我们创建了“HeroFactory”类和“HeroFactoryImpl”类,从原型中生成不同种类的生物。

java
public interface HeroFactory {
  
  Mage createMage();
  Warlord createWarlord();
  Beast createBeast();
}

@RequiredArgsConstructor
public class HeroFactoryImpl implements HeroFactory {

  private final Mage mage;
  private final Warlord warlord;
  private final Beast beast;

  public Mage createMage() {
    return mage.copy();
  }

  public Warlord createWarlord() {
    return warlord.copy();
  }

  public Beast createBeast() {
    return beast.copy();
  }
}

现在,我们能够展示完整的原型模式,通过克隆产生新的生物

现有实例

java
    var factory = new HeroFactoryImpl(
        new ElfMage("cooking"),
        new ElfWarlord("cleaning"),
        new ElfBeast("protecting")
    );
    var mage = factory.createMage();
    var warlord = factory.createWarlord();
    var beast = factory.createBeast();
    LOGGER.info(mage.toString());
    LOGGER.info(warlord.toString());
    LOGGER.info(beast.toString());

    factory = new HeroFactoryImpl(
        new OrcMage("axe"),
        new OrcWarlord("sword"),
        new OrcBeast("laser")
    );
    mage = factory.createMage();
    warlord = factory.createWarlord();
    beast = factory.createBeast();
    LOGGER.info(mage.toString());
    LOGGER.info(warlord.toString());
    LOGGER.info(beast.toString());

下面是运行该示例的控制台输出。

Elven mage helps in cooking
Elven warlord helps in cleaning
Elven eagle helps in protecting
Orcish mage attacks with axe
Orcish warlord attacks with sword
Orcish wolf attacks with laser

类图

alt text

适用性

当系统要独立于其产品的创建、组合、表示和维护方式时,应使用原型模式

*当在运行的过程中指定要实例化的类时,例如,通过动态加载。

  • 避免构建与产品类层次结构平行的工厂类层次结构。
  • 当一个类的实例只能有几个不同的状态组合中的一个时。安装相应数量的原型并克隆它们可能更方便,而不是每次都以适当的状态手动实例化类。
  • 当对象的创建比克隆更昂贵时。

已知用途

更多