ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • OOP Design Pattern - Creational Pattern
    프로그래밍 언어 2024. 1. 12. 17:49

    Abstract Factory

    Abstract Factory Pattern

    • An interface for creating families of related or dependent objects without specifying their concrete classes
    • Provides way to create families of related objects without imposing their concrete classes
    • Encapsulating a group of individual factories that have a common theme without specifying their concrete classes
    • The client does not know which concrete objects it receives from each of factories, because of using only the generic interfaces of their product

     

    Overview

    • Solves problem like:
      1. How can an application be independent of how its objects are created?
      2. How can a class be independent of how the objects that it requires are created?
      3. How can faimilies of related or dependent objects be created?
    • Describes how to solve such problems:
      1. Encapsulate object creation in a separate (factory) object by defining and implementing an interface for creating objects
      2. Delegate object creation to a factory object instead of creating objects directly

    Class UML of abstract factory pattern

     

    Caution to use pattern

    • May result in unnecessary complexity and extra work in the initial writing of code
    • Higher levels of seperation and abstraction can result in systems that  are more difficult to debug and maintain

     

    Implements

    1. Create a concrete implementation of the abstract factory
    2. Uses the generic interface of the factory to create the concrete objects that are part of the family

     

    Example

    Example class hierarchy

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public abstract class AbsBossFactory
    {
        public Boss CreateBoss()
        {
            Boss t_boss = new Boss(){ monster = CreateMonster(), weapon = CreateWeapon() };
            return t_boss;
        }
    		
        public abstract Monster CreateMonster();
        public abstract Weapon CreateWeapon();
    }
    
    public class BossFactory1 : AbsBossFactory
    {
        public override Monster CreateMonster()
        {
            Monster t_mosnter = new Goblin();
            return t_monster;
        }
    
        public override Weapon CreateWeapon()
        {
            Weapon t_weapon = new Sword();
            return t_weapon;
        }
    }
    
    public class BossSpawner : Monobehaviour
    {
        private void Start()
        {
            AbsBossFactory t_bossFactory = new BossFactory1();
            Boss t_boss = t_bossFactory.CreateBoss();
        }
    }

     

    Builder

    Builder Pattern

    • Provide a flexible solution to various object creation problems in OOP
    • Separate the contruction of a complex object from its representation
    • The same construction process can create different representations

     

    Overview

    • Solves problem like:
      1. How can a class (the same construction process) create different representations of a complex object?
      2. How can a class that includes creating a complex object be simplified?
    • Describes how to solve such problems:
      1. Encapsulate creating and assembling the parts of a complex object in a separate Builder object
      2. A class delegates object creation to a Builder object instead of creating the objects directly

    Class UML of builder pattern

     

    Caution to use pattern

    • Benefits
      1. Allow to vary a product's internal representation
      2. Encapsulate code for construction and representation
      3. Provide control over steps of contruction process
    • Drawbacks
      1. A distinct concrete builder must be created for each type of product
      2. Builder classes must be mutable
      3. May hamper / complicate dependency injection

     

    Example

    public class Bicycle // Represents a product created by the builder
    {
        public string make;
        public string model;
        public int height;
        public string colour;
    		
        public Bicycle(string p_make, string p_model, int p_height, string p_colour)
        {
            make = p_make;
            model = p_model;
            height = p_height;
            colour = p_colour;
        }
    }
    
    public interface IBicycleBuilder // The builder abstraction
    {
        int height;
        string colour;
    		
        Bicycle GetResult();
    }
    
    public class GTBuilder : IBicycleBuilder // Concrete builder implementation
    {
        public int height;
        public string colour;
    
        public Bicycle GetResult()
        {
            return height == 29 ? new Bicycle("GT", "Avalanche", height, colour) : null;
        }
    }
    
    public class MountainBikeBuildDirector // director
    {
        private IBicycleBuilder builder;
        
        public MountainBikeBuildDirector(IBicycleBuilder p_builder) 
        {
            builder = p_builder; 
        }
        
        public void Construct()
        {
            builder.height = 29;
            builder.colour = "Red";
        }
    	
        public Bicycle GetResult() { return this.builder.GetResult(); }
    }
    
    public class Client
    {
        public void DoSomethingWithBicycles()
        {
            var t_director = new MountainBikeBuildDirector(new GTBuilder());
            Bicycle t_bike = t_director.Construct().GetResult();
        }
    }

     

    Factory Method

    Factory Method Pattern

    • Define an interface for creating an object, but let subclasses decide which class to instantiate
    • Uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object will be created
    • Calls a factory method:
      1. Specified in an interface
      2. Implemented by child classes
      3. Implemented in a base class and optionally overriden by derived classes

     

    Overview

    • Solves problem like:
      1. How can an object be created so that subclasses can redefine which class to instantiate?
      2. How can a class defer instantiation to subclasses?
    • Describes how to solve such problems:
      1. Define a separate operation (factory method) for creating an object
      2. Create an object by calling a factory method, not using a constructor

    Class UML of factory method pattern

     

    Caution to use pattern

    • May result in unnecessary complexity and extra work in the initial writing of code
    • Higher levels of seperation and abstraction can result in systems that are more difficult to debug and maintain

     

    Example

    Example class hierarchy

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public abstract class AbsMonsterFactory
    {
        public abstract Monster CreateMonster(int p_type);
    }
    
    public enum EGoblin { NONE = -1, RED, GREEN }
    
    public class GoblinFactory : AbsMonsterFactory
    {
        public RedGoblin redGoblin;
        public GreenGoblin greenGoblin;
    
        public override Monster CreateMonster(int p_type)
        {
            Monster t_monster = null;
    
            if(p_type.Equals((int)EGoblin.RED)) t_monster = Instantiate(redGoblin);
            else if(p_type.Equals((int)EGoblin.GREEN)) t_monster = Instantiate(greenGoblin);
    
            return t_monster;
        }
    }
    
    public class MonsterSpawner : Monobehaviour
    {
        private void Start()
        {
            AbsMonsterFactory t_goblinFactory = new GoblinFactory();
            Monster t_monster = t_goblinFactory.CreateMonster((int)EGoblin.GREEN);
        }
    }

     

    Prototype

    Prototype Pattern

    • Used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects
    • Used to avoid subclasses of an object creator in the client application
    • Uses to avoid the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword) when it is prohibitively expensive for a given application

     

    Overview

    • One of design patterns that describe how to make objects that are easier to implement, change, test, and reuse
    • Solves problem like:
      1. How can objects be created so that which objects to create can be specified at run-time?
      2. How can dynamically loaded classes be instantiated?
    • Describes how to solve such problems:
      1. Define a Prototype object that returns a copy of itsself
      2. Create new objects by copying a Prototype object
    • Not require subclassing, but require an "initialize" operation

    Class UML of prototyp pattern

     

    Implementations

    • Declares an abstract base class that specifies a pure virtual clone() method
    • Any class that needs a "polymorphic constructor" capability derives itself from the abstract base class, and implements the clone() operation
    • Instead of writing code that invokes the "new" operation,
      1. Calls the clone() method on the prototype
      2. Calls the factory method with a parameter designating the particular concrete derived class desired
      3. Invoke the clone() method through some mechanism provided by another design pattern

     

    Example

    public abstract class Foo // Normal implementation
    {
        public abstract Foo Clone();
    }
    
    public class ConcreteFoo1 : Foo
    {
        public override Foo Clone()
        {
            return (Foo)this.MemberwiseClone(); // Clones the concrete class
        }
    }
    
    public class ConcreteFoo2 : Foo
    {
        public override Foo Clone()
        {
            return (Foo)this.MemberwiseClone(); // Clones the concrete class
        }
    }

     

    Singleton

    Singleton Pattern

    • Restricts the instantiation of a class to a singular instance
    • Useful when exactly one object is needed to coordinate actions across a system
    • Allows object to:
      1. Ensure objects only have one instance
      2. Provide easy access to that instance
      3. Control their instantiation (e.g., hiding the constructors of a class)

     

    Overview

    • Preferred to global variables, not pollute the global namespace (or their containing namespace)
    • Permit lazy allocation and initialization
    • Used as basis for other design pattern because only one facade object is required

     

    Implementations

    • Ensure that only one instance of the singleton class ever exists declaring all constructors of the class to be private, which prevents it from being instantiated by other objects
    • Typically provide global access to singleton instance providing a static method that returns a reference to the instance
    • Lazy Initialization

     

    Caution to use the pattern

    • A potential dependency on the singleton by other objects occuring increased coupling, introducing difficulties with unit testing
    • Violate the single-responsibility principle, responsible for enforcing their own uniqueness along with performing their normal functions

     

    Example

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SingletonMonobehaviour<T> : MonoBehaviour where T : Component
    {
        private static T instance;
    
        public static T Instance
        {
            get 
            {
                if (instance == null)
                {
                    instance = FindObjectOfType(typeof(T)) as T;
    
                    if (instance == null)
                        instance = new GameObject(typeof(T).Name, typeof(T)).GetComponent<T>();
                }
    
                return instance;
            }
        }
    
        protected virtual void Awake()
        {
            var t_objs = FindObjectsOfType<T>();
    
            if (t_objs.Length > 1)
            {
                Destroy(gameObject);
                return;
            }
    
            if (transform.parent != null) DontDestroyOnLoad(transform.root.gameObject);
            else DontDestroyOnLoad(gameObject);
        }
    }

     

    '프로그래밍 언어' 카테고리의 다른 글

    [C#] Public Field vs Auto-Implemented Property  (0) 2024.04.06
    OOP Design Pattern - Structural Pattern  (0) 2024.01.18
    [C++] 이동 의미론 Move Semantics  (0) 2023.11.20
    입실론 테스트  (0) 2023.11.20
    객체 지향 설계 SOLID  (0) 2023.11.16
Designed by Tistory.