Search Unity

Factory Design Pattern: Am I Doing This Right?

Discussion in 'Scripting' started by tburns517, Feb 14, 2016.

  1. tburns517

    tburns517

    Joined:
    Jan 12, 2016
    Posts:
    48
    Hello,

    I am learning about the Factory Design Pattern and would like to create a simple factory to create shapes. I would simply just like to call the shape from the factory, instantiate it, and then destroy it after 30 seconds. Am I doing this correctly?

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public interface ShapeFactory {
    5.  
    6.     void CreateShape();
    7.  
    8. }
    9.  
    10. class Cube : ShapeFactory {
    11.  
    12.     public void CreateShape()
    13.     {
    14.         GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
    15.         cube.transform.position = new Vector3(0, 0, 0);
    16.         Object.Instantiate(cube);
    17.         Object.Destroy(cube, 30.0f);
    18.     }
    19.  
    20. }
    21.  
    22.  
    23. class Sphere : ShapeFactory
    24. {
    25.  
    26.     public void CreateShape()
    27.     {
    28.         GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    29.         sphere.transform.position = new Vector3(0, 0, 0);
    30.         Object.Instantiate(sphere);
    31.         Object.Destroy(sphere, 30.0f);
    32.     }
    33.  
    34. }
    35.  
    36.  
    37. class Cylinder : ShapeFactory
    38. {
    39.  
    40.     public void CreateShape()
    41.     {
    42.         GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
    43.         cylinder.transform.position = new Vector3(0, 0, 0);
    44.         Object.Instantiate(cylinder);
    45.         Object.Destroy(cylinder, 30.0f);
    46.     }
    47.  
    48. }



    I'm not quite sure how to call the shape. Any help, tips, suggestions, feedback, etc. would be greatly appreciated. Thanks in advance.
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    Well, in your factories, you're creating 2 objects, not one.

    You create a GameObject as a primitive, then you clone that primitive, then you delete the original primitive, but allow the clone to continue on living.

    Remove the 'Object.Instantiate(...)' lines, you've already created it, why clone it?
     
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    Also, your factories seem to be playing more roles than intended. A factory in a factory pattern is all about creating objects... not about destroying them. What if you wanted to change the duration of time between creation and deletion? You'd have to modify the interface of your factory to allow that... but if the factory didn't deal with destruction you could deal with it on your own independently.

    Note I also changed the naming to reflect more common standards you'd find with other programmers.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public interface IShapeFactory {
    6.  
    7.     GameObject CreateShape();
    8.  
    9. }
    10.  
    11. class CubeFactory : IShapeFactory {
    12.  
    13.     public GameObject CreateShape()
    14.     {
    15.         GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
    16.         cube.transform.position = new Vector3(0, 0, 0);
    17.         return cube;
    18.     }
    19.  
    20. }
    21.  
    22.  
    23. class SphereFactory : IShapeFactory
    24. {
    25.  
    26.     public GameObject CreateShape()
    27.     {
    28.         GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    29.         sphere.transform.position = new Vector3(0, 0, 0);
    30.         return sphere;
    31.     }
    32.  
    33. }
    34.  
    35.  
    36. class CylinderFactory : IShapeFactory
    37. {
    38.  
    39.     public GameObject CreateShape()
    40.     {
    41.         GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
    42.         cylinder.transform.position = new Vector3(0, 0, 0);
    43.         return cylinder
    44.     }
    45.  
    46. }
    47.  
    48.  
    49.  
    50. //USAGE:
    51. public class ExampleUsage : MonoBehaviour
    52. {
    53.  
    54.     void Start()
    55.     {
    56.         var factory = new SphereFactory();
    57.         var obj = factory.CreateShape();
    58.         Object.Destroy(obj, 30.0f);
    59.     }
    60.  
    61. }
    62.  
     
    Last edited: Feb 14, 2016
  4. tburns517

    tburns517

    Joined:
    Jan 12, 2016
    Posts:
    48
    Thanks for the quick reply. I guess in my mind I thought the GameObject would be created but it would not show up on the screen, so I would need to Instantiate it. I have some UI buttons that the user can click on to create the shape they want.

    EDIT:

    Just saw your second post, and wow, that definitely makes a lot more sense to me now. Thank you.
     
  5. tburns517

    tburns517

    Joined:
    Jan 12, 2016
    Posts:
    48
    After viewing your code closely, I guess I am a little bit confused by it. By setting CreateShape() as a GameObject in the interface, you would have to pass in a GameObject obj or something along those lines, right? Otherwise, it would have to be void. Then in each class there would be a method, for example, public GameObject CreateShape(GameObject cube), which you could then return the cube at the end. How would the usage then change, since you have to pass in a GameObject?
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    Why would you have to pass in a GameObject?

    It's returning the GameObject that was created.

    It's a factory, it creates things, so it returns what it created.


    [edit]
    Oh, and sorry, I forgot to edit all the code and make sure all the factory classes had the correct return type. That's what happens when you write code in a browser...