Façade Pattern

Welcome to part 1 of the Design Patterns series!
This episode will be about the Façade Pattern!

Façade Pattern

Façade - Wikipedia

Façade Pattern is a very basic pattern we often unknowingly use. It’s a very useful pattern which is used in lots of applications.

Just as many patterns, the name says a lot about what the pattern does. As Façade means: “the principal front of a building, that faces on to a street or open space”.

In coding terms you can see this as a central access point. It’s the façade of a feature or your game which has access to multiple classes to call actions.

Examples

You can also compare it to a hub. You can setup an AI hub in your home controlling your media players, kitchen and cleaning devices. Your smart home device will be the façade of all these actions. You’ll ask the smart home device (façade) to start the music and start cleaning.

Another example you can think of is an ATM! When you want to get money out of an ATM a lot of things will happen in the background. It’ll check your pin-code registered to your bank account. It will check if the amount of money you want to subtract is possible and in the end it will provide you the money if all conditions are correct or show an error why it couldn’t happen.

The user doesn’t know about the actions an ATM is doing. All it asks is money, and asks the ATM to deliver it when the user has the right conditions.

Intentions of using Façade pattern

  • Improving readability by having a central point of handling actions in order or sequences.
  • Easy access/launching point.

Demo

Demo introduction

For this demo I decided to make a simple guess game. The goal is to keep the sorcerer alive by giving it the right type of food. When you give it the wrong type of food, it will be so disappointed resulting in killing himself. That’s not what we want! 😜

As I explained in examples section, a façade is the central point of delegating action. Such as an ATM. In this demo there’s one façade to control the game.
When you press any button, the game will trigger the sorcerer to eat. If the sorcerer dies, the façade will enable a restart button and allow you to try again. If the sorcerer survives, the sorcerer will recall a type of food. Every time the sorcerer is eating the façade will disable all food buttons so the user is forced to wait.

In steps:

  • Facade got access to the sorcerer, all food buttons and a reset button.
  • When the sorcerer calls out to eat food, all food buttons will enable.
  • When the user presses any of the food buttons, all buttons will be disabled, the sorcerer will eat it and decide to die or not.
  • When sorcerer dies.
    • All food buttons remain inactive.
    • Reset button will be enabled, if pressed the whole procedure will restart
  • When sorcerer survives
    • Sorcerer will call out for food again, all food buttons will enable.

Setup

For this demo I am using Unity 2019.4.10f, but you can follow this series with any version you like!

For some visual effects I installed DoTween to code some small tween animations you will see later in code examples. Also do I use DoTween to make delayed calls.

The hierarchy:

Hierarchy is based of a few simple objects.

  • background, first layer for scenery
  • sorcerer, character who eats food
  • front background to add some depth. Makes the sorcerer stand behind the bushes
  • food buttons container
    • All food type buttons
    • Made a master button so it was easy to change/modify original design without having to change each individual button
    • button reset to reset our game
  • façade

Sorcerer character contains an animator with three animations:

All animations

idle -> eat is linked to Eat trigger.
eat -> idle has an end time to transition back to idle.
idle -> die is linked to Die trigger.
die -> idle is linked to idle in case we want to reset.

Code

Actions

Sorcerer.cs

Sorcerer will be our character who eats food and visualise the message to the user.
Therefor it has two public accessible method for eating and setting it’s target.

namespace Facade.Code {
    // to make sure we have an animator on this instance we add a require component attribute.
    [RequireComponent(typeof(Animator))]
    public class Sorcerer : MonoBehaviour {
        // to visualise which type of food we want to eat
        [SerializeField] private Text _targetLabel;

        // to trigger animations
        private Animator _anim;

        private int _currentTarget;

        // Two event actions we will listen to in Facade
        public event Action OnDied;
        public event Action OnSurvived;

        private void Start() {
            // get animator
            _anim = GetComponent<Animator>();

            // set target label alpha to 0
            _targetLabel.DOFade(0, 0);
        }

        // Set food type target
        public void SetTarget(int target, string foodString, Action onSetLabel) {
            _currentTarget = target;
            _targetLabel.text = $"Give me: {foodString}";

            // Fade in the text label asking the food type
            _targetLabel.DOFade(1, 0.2f).SetDelay(2).OnComplete(() => {
                // Fade out the text label so the user can't peak anymore what the sorcerer wants to eat.
                _targetLabel.DOFade(0, 0.1f).SetDelay(0.5f);

                // Call action to tell facade the question is visible! 
                onSetLabel?.Invoke();
            });
        }

        // Start eating progress and check whether we died or not
        public void Eat(int target) {
            _anim.SetTrigger("Eat");

            if (_currentTarget != target) {
                // Die after 3 seconds to make it exciting if the user choose right or wrong.
                DOVirtual.DelayedCall(3f, Die);
            }
            else {
                // Call survive event after 1.5 seconds to start whole process over.
                DOVirtual.DelayedCall(1.5f, () => OnSurvived?.Invoke());
            }
        }

        private void Die() {
            _anim.SetTrigger("Die");

            // call die event
            OnDied?.Invoke();
        }
    }
}
FoodMenu.cs

To control all buttons enabling/disabling, we add a food menu class which accesses all buttons.

namespace Facade.Code {
    public class FoodMenu : MonoBehaviour {
        // all buttons set in inspector
        [SerializeField] private Button[] _buttons;

        // set all buttons intractability to false
        public void DisableButtons() {
            for (int i = 0; i < _buttons.Length; i++) {
                _buttons[i].interactable = false;
            }
        }
        
        // set all buttons intractability to true
        public void EnableButtons() {
            for (int i = 0; i < _buttons.Length; i++) {
                _buttons[i].interactable = true;
            }
        }
    }
}
FoodType.cs

Food type is a short data struct so we can set the food type’s name and icon.

namespace Facade.Code {
	// making this struct serializable so it's visible in the editor inspector
    [System.Serializable]
    public struct FoodType {
        public string Name;
        public Sprite Icon;
    }
}

Facade

GameFacade.cs

Now we have all actions set up as puzzle pieces, we can setup our facade!

namespace Facade.Code {
    public class GameFacade : MonoBehaviour {
        // access points
        [SerializeField] private FoodType[] Targets;
        [SerializeField] private Sorcerer sorcerer;
        [SerializeField] private FoodMenu _foodMenu;
        [SerializeField] private Button _reset;
        [SerializeField] private Image _foodIcon;

        // current target
        private int _target = -1;

        private void Start() {
            // initializing objects
            _reset.onClick.AddListener(Reset);
            _reset.gameObject.SetActive(false);

            // listening to sorcerer events
            sorcerer.OnSurvived += RandomTarget;
            sorcerer.OnDied += OnEnemyDied;

            // disabling all buttons on start
            _foodMenu.DisableButtons();

            // set a random target
            RandomTarget();
        }

        private void RandomTarget() {
            // get a random target number
            _target = Random.Range(0, Targets.Length);

            // set sorcerer target to start label animation
            // enable all buttons once target is set.
            sorcerer.SetTarget(_target, Targets[_target].Name, _foodMenu.EnableButtons);
        }

        // Called by button onclick events in editor.
        public void Eat(int target) {
            // disable all buttons
            _foodMenu.DisableButtons();

            // set food icon sprite, which will be animated by sorcerer .Eat method
            _foodIcon.sprite = Targets[target].Icon;

            // start eat animation
            sorcerer.Eat(target);
        }

        private void OnEnemyDied() {
            // enable reset button when enemy died
            _reset.gameObject.SetActive(true);
        }

        private void Reset() {
            sorcerer.OnSurvived -= RandomTarget;
            sorcerer.OnDied -= OnEnemyDied;

            // reset current scene
            SceneManager.LoadScene(SceneManager.GetActiveScene().name);
        }
    }
}

Inspector:

As you can see in this example, we can access, change and modify everything through our game façade. We can add new targets, link access points and so change these too.

The user can only interact through the food buttons. So the food buttons call the game façade .Eat method passing their target number.

Git

Find the repository here with full source code:
https://github.com/jscotty/DesignPatterns

Or download the unity package here:

Break down

I made this simplified UML diagram to break down what happens.
As you can see, the user only talks with the Façade by pressing the buttons. This makes the user not having to care what the rest does. All it wants to do is to provide the target index he/she thinks the sorcerer wants to survive. The façade delegates this through the actions.
This makes this example comparable to an ATM I explained in the beginning. All the user does is pressing buttons and the façade will delegate it further to receive returns.

Most important to do when developing Façades in your project, is to think in access points. When “I” as a “user” want to get … , who/what do I contact/interact with to receive my return. The user does not know what happens in background, but the contact/interaction access point knows what sequence has to happen. 😉

Resources

Derek Banas

A great simple explanation of façade pattern bank demo.

Simply Explained

Perfect simple example of a home theatre façade explained in TypeScript.

Wikipedia

This Wikipedia page is a great in-depth explanation of possibilities with Facade Pattern.
https://en.wikipedia.org/wiki/Facade_pattern

Assets

For the demo below I used three free art packages!

Evil Wizard
Free Pixel Art Hill
Free Pixel Foods

Hope you enjoyed this episode!
Did you already know about Façade pattern? Or did you just realize you’ve been using it unknowingly all the time! (I did so once I learned about it 😜 )

If any questions, feel free to message me on Instagram @justinbieshaar or in comments below!

Happy coding everyone! 👨‍💻

Greetings,
Justin Scott

Follow Justin Scott:

I love to learn and share. - 01001010 01010011 01000010

Latest posts from

Leave a Reply

Your email address will not be published. Required fields are marked *