Questions about the Prototype Pattern

前端 未结 3 1284
灰色年华
灰色年华 2020-12-12 13:40

I am learning about the different design patterns and I have a strong feeling I am missing an essential piece (or pieces) in understanding this particular pattern.

I

3条回答
  •  醉梦人生
    2020-12-12 14:11

    You've got the prototype pattern right by the looks of it.

    How it Reduces Subclassing

    Lets say you're making MineCraft and you're using the prototype pattern for each different kind of block (e.g. dirt, stone, etc). All the prototype objects are actually of the same class Block, but each object has had different properties set on it so that it looks and behaves differently, for example:

    prototypes.dirt = new Block;
    prototypes.dirt.texture = new Image("dirt.jpg");
    prototypes.dirt.hardness = 1;
    
    prototypes.stone = new Block;
    prototypes.stone.texture = new Image("stone.jpg");
    prototypes.stone.hardness = 9;
    

    So instead of subclassing where you would write new DirtBlock or new StoneBlock, you would instead write prototypes.dirt.clone() or prototypes.stone.clone(). No subclassing is required, but you still have the option to subclass if need be.

    Differences With Factory Pattern

    As for when to choose the prototype pattern instead of a factory pattern, there are two situations I can think of where they differ:

    1. You can iterate over a list of prototypes, but you can't iterate over all the methods on an abstract factory^. Continuing from the code above, you could create a random block like so:

      prototypes.allValues().objectAtIndex(rand() % prototypes.size()).clone();

      If you were using the factory method to make blocks, it would be harder to get a random block.

    2. Where creation of an object is expensive, but copying is cheap, the prototype pattern will be more efficient. For example, take this factory method:

      Image loadUserImage() { 
          //loads from disk. will be slow
          return new JPEGImage("path/to/user/image.jpg"); 
      }
      

      If this method is going to be called repeatedly, it would be more efficient to use a prototype like so:

      Image loadUserImage() {
          //copy in memory. will be fast
          return userImagePrototype.clone();
      }
      


    ^ This is a white lie because you actually can iterate over methods depending on what language you're using, but iterating over an array is still probably a better solution because it's less complex than reflection/introspection.

提交回复
热议问题