jeudi 12 janvier 2017

Can this code be thought of as an example of bridge pattern?

Code without bridge pattern:

abstract class DataEncryptor
{
    protected abstract string GetSalt ();

    protected byte [] GetFile (string filePath)
    {
        return System.IO.File.ReadAllBytes (filePath);
    }

    public abstract void EncryptFile (string filePath);
}

abstract class DataEncryptorFastAndWeak : DataEncryptor
{
    public override void EncryptFile (string filePath)
    {
        var file = GetFile (filePath);
        var salt = GetSalt ();

        //weak, but fast algorithm of file encrypting
    }
}

abstract class DataEncryptorLongAndStrong : DataEncryptor
{
    protected abstract int GetEncryptIterationCount ();

    string GenerateRandomSalt ()
    {
        //TODO: automatic salt generation
        return string.Empty;
    }

    string CombineSalts (string salt1, string salt2)
    {
        //TODO: tricky way of salts combining
        return $"{salt1}{salt2}";
    }

    public override void EncryptFile (string filePath)
    {
        var file = GetFile (filePath);

        var salt = GetSalt ();
        var salt2 = GenerateRandomSalt ();
        var doubleExtendedSalt = CombineSalts (salt, salt2);

        var iterations = GetEncryptIterationCount ();

        //time long, but strong algorithm of file encrypting
    }
}

#region Console

class ConsoleDataEncryptorFastAndWeak : DataEncryptorFastAndWeak
{
    protected override string GetSalt ()
    {
        Console.WriteLine ("Type salt:");
        return Console.ReadLine ();
    }
}

class ConsoleDataEncryptorLongAndStrong : DataEncryptorLongAndStrong
{
    protected override string GetSalt ()
    {
        Console.WriteLine ("Type salt:");
        return Console.ReadLine ();
    }

    protected override int GetEncryptIterationCount ()
    {
        Console.WriteLine ("Type iterations:");
        return int.Parse (Console.ReadLine ());
    }
}

#endregion

#region Windows Forms

class WindowsFormsEncryptorFastAndWeak : DataEncryptorFastAndWeak
{
    protected override string GetSalt ()
    {
        //create window with editable text view
        //subscribe to events
        //show window
        //wait for user input
        return string.Empty; //return window.editText.Text;
    }
}

class WindowsFormsEncryptorLongAndStrong : DataEncryptorLongAndStrong
{
    protected override string GetSalt ()
    {
        //create window with editable text view
        //subscribe to events
        //show window
        //wait for user input
        return string.Empty; //return window.editText.Text;
    }

    protected override int GetEncryptIterationCount ()
    {
        //create window with integer "toggle" btn
        //subscribe to events
        //show window
        //wait for user input
        return 0; //return window.integerCounter.Value;
    }
}

#endregion

Code WITH bridge pattern:

interface IValueProvider
{
    string GetSalt ();
    int GetEncryptIterationCount ();
}

abstract class DataEncryptor
{
    public IValueProvider valuesProvider;

    public void SetValueProvider (IValueProvider valuesProvider)
    {
        this.valuesProvider = valuesProvider;
    }

    protected byte [] GetFile (string filePath)
    {
        return System.IO.File.ReadAllBytes (filePath);
    }

    public abstract void EncryptFile (string filePath);
}

class DataEncryptorFastAndWeak : DataEncryptor
{
    public override void EncryptFile (string filePath)
    {
        var file = GetFile (filePath);
        var salt = valuesProvider.GetSalt ();

        //weak, but fast algorithm of file encrypting
    }
}

class DataEncryptorLongAndStrong : DataEncryptor
{
    string GenerateRandomSalt ()
    {
        //TODO: automatic salt generation
        return string.Empty;
    }

    string CombineSalts (string salt1, string salt2)
    {
        //TODO: tricky way of salts combining
        return $"{salt1}{salt2}";
    }

    public override void EncryptFile (string filePath)
    {
        var file = GetFile (filePath);

        var salt1 = valuesProvider.GetSalt ();
        var salt2 = GenerateRandomSalt ();
        var extendedSalt = CombineSalts (salt1, salt2);

        var iterations = valuesProvider.GetEncryptIterationCount ();

        //time long, but strong algorithm of file encrypting
    }
}

class ConsoleValueProvider : IValueProvider
{
    int IValueProvider.GetEncryptIterationCount ()
    {
        Console.WriteLine ("Type iterations:");
        return int.Parse (Console.ReadLine ());
    }

    string IValueProvider.GetSalt ()
    {
        Console.WriteLine ("Type salt:");
        return Console.ReadLine ();
    }
}

class WindowValueProvider : IValueProvider
{
    int IValueProvider.GetEncryptIterationCount ()
    {
        //create window with integer "toggle" btn
        //subscribe to events
        //show window
        //wait for user input
        return 0; //return window.integerCounter.Value;
    }

    string IValueProvider.GetSalt ()
    {
        //create window with editable text view
        //subscribe to events
        //show window
        //wait for user input
        return string.Empty; //return window.editText.Text;
    }
}

So, when we, for example, have a need to create a DataEncryptor without user interaction for getting salt etc (NoUserDataEncryptor), which, for example, is getting salt based on current system time and uses predefined encryption iteration count, in case of NO_Bridge we should provide two classes: NoUserDataEncryptorFastAndWeak and NoUserDataEncryptorLongAndStrong, and in case of With_Bridge only one: NoUserValueProvider. Is my understanding of pattern correct?

Aucun commentaire:

Enregistrer un commentaire