Encrypting String using the Decorator Pattern

I’m trying to apply the decorator pattern to making an object that encrypts a word into a certain encryption, like the L337 method, which replaces letters like 9 with g, or 4 with r. I was going to do this with three other encryption decorators. Basically, I want to type a word into an inputfield and show the encrypted word in a text object. But I can’t get the L337 decorator to inherit from the main decorator class. It won’t accept the keyword ‘super’, so I tried the base word, but then when I implement Encrypt, it won’t take the object newEncryption. Could someone help me figure out how to put this pattern together please?

public class Encryption : MonoBehaviour
{

public static InputField inputBox;
public static Text outputText;



public interface IEncryption { void Encrypt(); }


public class TextEncryption : IEncryption
{
   public void Encrypt()
   {
       string currentText = inputBox.text;
       outputText.text = currentText;
   }
}


public abstract class encryptionDecorator : IEncryption
{
   protected IEncryption tempEncryption;
   public encryptionDecorator(IEncryption newEncryption)
   {
       tempEncryption = newEncryption;
   }

   public void Encrypt()
   {
       tempEncryption.Encrypt();
   }
}

public class L337EncryptionDecorator : encryptionDecorator
{
   public L337EncryptionDecorator(IEncryption newEncryption) : base(newEncryption)
   {
       print("Encrypting L337 Code");
   }

   public void Encrypt()
   {

   }

}
}

I like your idea, sounds fun :slight_smile:

Your setup looks a little over-complicated. Decorators just wrap around an existing instance, and implement the same interface.

Here’s a working example. It just prints to the console. I also modified the encryption classes to return a string, rather than couple them to any unity components.

using UnityEngine;

public class Encryption : MonoBehaviour
{
    public void Start()
    {
        string original = "encrypt me!";

        var textEncrpytion = new TextEncryption(original);
        var l337Encrpytion = new L337Encryption(textEncrpytion);

        string result = l337Encrpytion.Encrypt();

        print("unencrypted: " + original);
        print("encrypted:" + result);
    }
}


public interface IEncryption
{
    string Encrypt();
}


public class TextEncryption : IEncryption
{
    private string _original;

    public TextEncryption(string original)
    {
        _original = original;
    }

    public string Encrypt()
    {
        Debug.Log("Performing Text Encryption");

        return _original;
    }
}


public class L337Encryption : IEncryption
{
    private IEncryption _encryption;

    public L337Encryption(IEncryption encryption)
    {
        _encryption = encryption;
    }

    public string Encrypt()
    {
        Debug.Log("Performing L337 Encryption");

        string result = _encryption.Encrypt();
        result = result.Replace('e', '3').Replace('t', '7');

        return result;
    }
}

It works nice thanks. But I can’t figure out how to translate it into unity. I want to couple the components. I thought I could make an encryption manager and attach the inputfield and outputtext, but I keep getting the error “object referecne not set to an instance of an object”

Personally due to how the Unity workflow is, I would implement the Decorator pattern slightly differently.

Instead of having each decorator wrap around each other and then having objects try and communicate through the wrapped shell… simply store the decorators as a list on the class and when something tries to access a class’s property the class interally run generations of the data through the decorators before sending the final result back. This way the fact that the class is using decorators remains transparent to the requesting classes, yet now you can pre-configure which decorators the class is using in the inspector. And you can still add/remove decorators at runtime.

Write each decorator as a Scriptable Object and then have your Encryption class hold a list of encryptionDecorator (which now derives from ScriptableObject). throw away the constructor (in this sense your decorators no longer need to keep references of the things its decorating). Now when something wants the text output they can call Encryption.Encrypt(inputString) which interally feeds the string into each decorator in a loop and finally returns the result back.

I think the issue is whether the Decorator Pattern is the important thing here. JoshM’s plan is better (just give the object a list of string-to-string encoders and hand-run them in a order) but it’s not the Decorator Pattern(*) I’m guessing the OP doesn’t care - probably just saw somewhere “oh, you should use decorator.” But it might be for a job interview or something, where you need to show the actual patterns(**).

(*) Adding a variable function as a member seems more like Strategy, not that it matters.

(**) Just wear a tie, have a firm grip and act confident. The interviewer won’t understand Design Patterns any better than you do. They just want to know you can fake it in case the boss checks.

No worries, just use the ‘inputBox’ text as input, and assign the result to the ‘outputText’ text. This example will encrypt when you press enter in the input field:

public class Encryption : MonoBehaviour
{
    public InputField inputBox;
    public Text outputText;

    private void Awake()
    {
        if (inputBox == null) Debug.LogError("Assign an inputBox in the inspector");
        if (outputText == null) Debug.LogError("Assign an outputText in the inspector");

        inputBox.onEndEdit.AddListener(PerformEncryption);
    }

    private void PerformEncryption(string inputText)
    {
        var textEncrpytion = new TextEncryption(inputText);
        var l337Encrpytion = new L337Encryption(textEncrpytion);

        outputText.text = l337Encrpytion.Encrypt();
    }
}