原型模式

1.使用场景:
1.1.对象类型只有在运行期才能够确定。
1.2.克隆一直对象的副本。
1.3.大同小异的一些对象。
2.UML表示
在原型模式中通常用以下的几类对象:
Client角色:使用原型对象的客户程序
Prototype角色:规定了具体原型对象必须实现的接口(如果要提供深拷贝,则必须具有实现clone的规定)
ConcretePrototype:从抽象原型派生而来,是客户程序使用的对象,即被复制的对象。此角色需要实现抽象原型角色所要求的接口。

具体的UML示意图如下:

3.代码实现
下面举一个忍者使用影分身术的例子:

定义普通忍者类:

 

public class Ninjia_A implements Cloneable{
    private String name;//名字
    private int rp;//血槽
    private Ninjutsu ninjutsu;//忍术
    public Ninjia_A(String name, int rp,Ninjutsu ninjutsu) {
        this.name = name;
        this.rp = rp;
        this.ninjutsu=ninjutsu;
    }

    public Ninjutsu getNinjutsu() {
        return ninjutsu;
    }

    public void setNinjutsu(Ninjutsu ninjutsu) {
        this.ninjutsu = ninjutsu;
    }

    protected Object clone() throws CloneNotSupportedException {
         Ninjia_A nn;
         nn= (Ninjia_A) super.clone();
        return nn;
    }

    public String getName() {
        return name;
    }

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

    public int getRp() {
        return rp;
    }

    public void setRp(int rp) {
        this.rp = rp;
    }
}

S级忍者:

 

 

public class Ninjia_S implements Serializable {

    private static final long serialVersionUID = 2169380777227967513L;
    private String name;//名字
    private int rp;//血槽
    private Ninjutsu ninjutsu;//忍术
    public Ninjia_S(String name, int rp,Ninjutsu ninjutsu) {
        this.name = name;
        this.rp = rp;
        this.ninjutsu=ninjutsu;
    }

    public Ninjutsu getNinjutsu() {
        return ninjutsu;
    }

    public void setNinjutsu(Ninjutsu ninjutsu) {
        this.ninjutsu = ninjutsu;
    }

    public String getName() {
        return name;
    }

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

    public int getRp() {
        return rp;
    }

    public void setRp(int rp) {
        this.rp = rp;
    }

    protected Object dclone() throws CloneNotSupportedException, IOException, ClassNotFoundException {
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(bos);
        oos.writeObject(this);
        ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois=new ObjectInputStream(bis);
        return ois.readObject();
    }

}

忍术类:

 

 

public class Ninjutsu implements Serializable {
    private int damage;//破坏力
    private String name;

    public Ninjutsu(int damage, String name) {
        this.damage = damage;
        this.name = name;
    }

    public int getDamage() {
        return damage;
    }

    public void setDamage(int damage) {
        this.damage = damage;
    }

    public String getName() {
        return name;
    }

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

测试类::

 

 

public class Client {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Ninjia_A kakaxi=new Ninjia_A("旗木.卡卡西",50,new Ninjutsu(500,"影分身"));

        Ninjia_A kk;
        try {
             kk= (Ninjia_A) kakaxi.clone();

             System.out.println(kakaxi.getNinjutsu()==kk.getNinjutsu());
            // System.out.println(kk.getNinjutsu().getName()+"  "+kk.getNinjutsu().getDamage());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        Ninjia_S naturo=new Ninjia_S("漩涡.那乳托",500,new Ninjutsu(1000,"影分身"));
        Ninjia_S nn;
        try {
            nn= (Ninjia_S) naturo.dclone();
            System.out.println(naturo.getNinjutsu()==nn.getNinjutsu());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

    }
}

结论:原型模式更像一种编程的技巧,很少单独使用,注意的是在Java中,除了基本数据类型外,其他的都是引用类型,这个必须注意。
最后,附上文章的代码下载连接:
https://github.com/MemoryExplosion/design_pattern_review/tree/master/src/java/prototype

 



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值