当前位置:网站首页>Prototype mode -- clone monster Army

Prototype mode -- clone monster Army

2022-06-24 20:34:00 zhanyd

Introduction

Xiaoshuai works for a game company , Participate in the development of one RPG game , He is responsible for designing monsters in the game . Some big scenes need hundreds of monsters , If you use new To create each monster , There are many parameters that need to be initialized , It's going to take a lot of time , And it's troublesome .

Xiaoshuai decides to quickly clone monsters in prototype mode , Let the monster army quickly gather .

Archetypal model

Archetypal model : Using prototype instances to specify the kind of objects to create , And create new objects by copying these stereotypes .

 Insert picture description here

Prototype is a creative design pattern , Enables you to copy objects , Even complex objects , And you don't have to make your code depend on the class they belong to .

Corresponding to our code , The class diagram is as follows :
 Insert picture description here

Monsters :

/** *  Monsters  */
public class Monster implements Cloneable{
    

    /** *  name  */
    String name;

    /** *  aggressivity  */
    int attackPower;

    /** *  Health value  */
    int hp;

    public Monster(String name, int attackPower, int hp) {
    
        this.name = name;
        this.attackPower = attackPower;
        this.hp = hp;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
    
        return super.clone();
    }

    @Override
    public String toString() {
    
        return " Monster name :" + name + ", aggressivity :" + attackPower + ", Health value :" + hp;
    }

    public String getName() {
    
        return name;
    }

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

    public int getAttackPower() {
    
        return attackPower;
    }

    public void setAttackPower(int attackPower) {
    
        this.attackPower = attackPower;
    }

    public int getHp() {
    
        return hp;
    }

    public void setHp(int hp) {
    
        this.hp = hp;
    }

}

Client class :

public class Client {
    

    public static void main(String[] args) throws CloneNotSupportedException {
    
        List<Monster> monsterList = new ArrayList<Monster>();
        Monster monster = new Monster(" Flying dragon ", 200, 100);

        for(int i = 0; i < 10; i++) {
    
            monsterList.add((Monster)monster.clone());
        }

        monsterList.stream().forEach(f -> System.out.println(f));
    }
}

Output :

 Monster name : Flying dragon , aggressivity :200, Health value :100
 Monster name : Flying dragon , aggressivity :200, Health value :100
 Monster name : Flying dragon , aggressivity :200, Health value :100
 Monster name : Flying dragon , aggressivity :200, Health value :100
 Monster name : Flying dragon , aggressivity :200, Health value :100
 Monster name : Flying dragon , aggressivity :200, Health value :100
 Monster name : Flying dragon , aggressivity :200, Health value :100
 Monster name : Flying dragon , aggressivity :200, Health value :100
 Monster name : Flying dragon , aggressivity :200, Health value :100
 Monster name : Flying dragon , aggressivity :200, Health value :100

Notice the Monster Is to achieve Cloneable Interface to use clone() Method , If you put Cloneable If the interface is removed, an error will be reported :

Exception in thread "main" java.lang.CloneNotSupportedException: prototype.monster.normal.Monster
	at java.lang.Object.clone(Native Method)
	at prototype.monster.normal.Monster.clone(Monster.java:31)
	at prototype.monster.normal.Client.main(Client.java:13)

Object Class clone() The method has been described :
 Insert picture description here

Shallow copy and deep copy

If every monster has its own pet , Pets have their own names and skills , Let's take a look at the following example .

Shallow copy

Monsters :

/** *  Monsters  */
public class Monster implements Cloneable{
    

    /** *  name  */
    String name;

    /** *  aggressivity  */
    int attackPower;

    /** *  Health value  */
    int hp;

    /** *  Pets  */
    Pet pet;

    public Monster(String name, int attackPower, int hp, Pet pet) {
    
        this.name = name;
        this.attackPower = attackPower;
        this.hp = hp;
        this.pet = pet;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
    
        return super.clone();
    }

    @Override
    public String toString() {
    
        return " Monster name :" + name + ", aggressivity :" + attackPower + ", Health value :" + hp + ",  Pet name :" + pet.name + ", Skill :" + pet.skill;
    }

    public String getName() {
    
        return name;
    }

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

    public int getAttackPower() {
    
        return attackPower;
    }

    public void setAttackPower(int attackPower) {
    
        this.attackPower = attackPower;
    }

    public int getHp() {
    
        return hp;
    }

    public void setHp(int hp) {
    
        this.hp = hp;
    }

    public Pet getPet() {
    
        return pet;
    }

    public void setPet(Pet pet) {
    
        this.pet = pet;
    }
}

Pet class :

/** *  Pet class  */
public class Pet {
    

    /** *  name  */
    String name;

    /** *  Skill  */
    String skill;

    public Pet(String name, String skill) {
    
        this.name = name;
        this.skill = skill;
    }

    @Override
    public String toString() {
    
        return " Pet name :" + name + ", Skill :" + skill;
    }

    public String getName() {
    
        return name;
    }

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

    public String getSkill() {
    
        return skill;
    }

    public void setSkill(String skill) {
    
        this.skill = skill;
    }
}

Client class :

public class Client {
    
    public static void main(String[] args) throws CloneNotSupportedException {
    
        //  Pets 
        Pet pet = new Pet(" Little stone man ", " Flying stone ");
        //  Monster 
        Monster monster = new Monster(" Mountain Giant ", 300, 500, pet);
        //  Monster copy 
        Monster monsterClone = (Monster)monster.clone();
        System.out.println("monster :" + monster);
        System.out.println("monsterClone :" + monsterClone);
        System.out.println("----------------------------------------------------------------------------------------------");
        //  Just modify the pet attribute of the monster copy 
        monsterClone.pet.setName(" The camellia ");
        monsterClone.pet.setSkill(" Dive ");
        System.out.println("monster :" + monster);
        System.out.println("monsterClone :" + monsterClone);
    }
}

Output :

monster : Monster name : Mountain Giant , aggressivity :300, Health value :500,  Pet name : Little stone man , Skill : Flying stone 
monsterClone : Monster name : Mountain Giant , aggressivity :300, Health value :500,  Pet name : Little stone man , Skill : Flying stone 
----------------------------------------------------------------------------------------------
monster : Monster name : Mountain Giant , aggressivity :300, Health value :500,  Pet name : The camellia , Skill : Dive 
monsterClone : Monster name : Mountain Giant , aggressivity :300, Health value :500,  Pet name : The camellia , Skill : Dive 

As you can see from the above example , The copied monster object monsterClone Modified your pet pet Properties of , Also changed the pet attribute of the prototype monster .

This is because in the Java In language ,Object Class clone() Method executes the shallow copy of the above . It only copies the data of the basic data type in the object ( such as ,int、long), And reference objects (pet) Memory address of , The reference object itself is not copied recursively .

therefore ,monster and monsterClone Object refers to the same pet object .

Deep copy

Let's take a look at the example of deep copy :

Pet class :
 Insert picture description here
Client class :
 Insert picture description here
Output :
 Insert picture description here
You can see , The copied monster just modified its pet , The pet of the prototype monster has not changed .

Deep copy is to copy all the objects in the object one by one , All data in each object has an independent copy .

The following two figures describe the difference between light copy and deep copy :
 Insert picture description here
 Insert picture description here
Another way to implement deep copy is serialization and deserialization :

public Object deepCopy(Object object) {
     
	ByteArrayOutputStream bo = new ByteArrayOutputStream(); 
	ObjectOutputStream oo = new ObjectOutputStream(bo); 
	oo.writeObject(object); 
	
	ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); 
	ObjectInputStream oi = new ObjectInputStream(bi); 
	
	return oi.readObject();
}

summary

If the creation cost of an object is large , There is little difference between different objects of the same class ( Most of the fields are the same ), under these circumstances , We can take advantage of existing objects ( Prototype ) replicate ( Copy 、 clone ) The way , To create new objects , In order to save creation time .

The prototype pattern is to copy objects at the memory binary level , More than direct new The performance of an object is much better , Especially when a large number of objects are generated in a cycle , Prototype patterns can be more efficient .

This is the prototype pattern , Is it simple ?

Last , Let's look at the advantages and disadvantages of the prototype pattern :

advantage

  • You can clone objects , Without coupling with the specific class to which they belong .
  • Pre generated prototypes can be cloned , Avoid running initialization code repeatedly .
  • It is more convenient to generate complex objects .
  • Different configurations of complex objects can be handled in ways other than inheritance .

shortcoming

  • Cloning complex objects that contain circular references can be cumbersome .

Code link

原网站

版权声明
本文为[zhanyd]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202211327028779.html