Design patterns in C# – part 2 (Proxy pattern)

Role

Supporting object that control the creation of and access to other objects.

Design

Proxy Pattern Image

Implementation

  • ISubject -> IAccount
  • Subject -> Account
  • Proxy ->AccountProxy
  • Client -> TestProxyPattern
namespace ProxyPattern
{
    public interface IAccount
    {
        void LogIn(string login, string password);
        decimal Balance();
        void CashIn(decimal amount);
        void CashOut(decimal amount);
        void LogOut();
    }
}
using System;

namespace ProxyPattern
{
    public class AccountProxy : IAccount
    {
        private Account _account;

        #region IAccount Members

        public void LogIn(string login, string password)
        {
            try
            {
                this._account = Account.GetAccount(login, password);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        public decimal Balance()
        {
            try
            {
                return this._account.Balance();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            return new decimal(-1.0);
        }

        public void CashIn(decimal amount)
        {
            try
            {
                this._account.CashIn(amount);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        public void CashOut(decimal amount)
        {
            try
            {
                this._account.CashOut(amount);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        public void LogOut()
        {
            try
            {
                this._account.LogOut();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        #endregion
    }
}
using System;
using System.Collections.Generic;

namespace ProxyPattern
{
    internal class Account
    {
        private static readonly Dictionary AccountsList;
        private readonly string _password;
        private decimal _balance;
        private bool _loggedIn;

        static Account()
        {
            AccountsList = new Dictionary
                               {
                                   {"jacek", new Account("password")},
                                   {"madzia", new Account("zxcvv")},
                                   {"member", new Account("pass")},
                                   {"jack", new Account("word")},
                                   {"person", new Account("security")}
                               };
        }

        private Account(string password)
        {
            this._password = password;
            this._balance = new decimal(0.0);
            this._loggedIn = false;
        }

        internal static Account GetAccount(string login, string password)
        {
            Account result = AccountsList[login];
            if (result == null)
            {
                throw new Exception("Invalid login !!");
            }

            if (String.Equals(password, result._password))
            {
                result._loggedIn = true;
                return result;
            }

            throw new Exception("Invalid password !!");
        }

        internal decimal Balance()
        {
            if (this._loggedIn)
            {
                return this._balance;
            }

            throw new Exception("You are not log in to the account !!");
        }

        internal void CashIn(decimal amount)
        {
            if (this._loggedIn)
            {
                this._balance += amount;
            }
            else
            {
                throw new Exception("You are not log in to the account !!");
            }
        }

        internal void CashOut(decimal amount)
        {
            if (!this._loggedIn)
            {
                throw new Exception("You are not log in to the account !!");
            }
            if ((this._balance - amount) >= new decimal(0.0))
            {
                this._balance -= amount;
            }
            else
            {
                throw new Exception("You do not have enough money !!");
            }
        }

        internal void LogOut()
        {
            if (this._loggedIn)
            {
                this._loggedIn = false;
            }
            else
            {
                throw new Exception("You are not log in to the account !!");
            }
        }
    }
}
using System;

namespace ProxyPattern
{
    public class TestProxyPattern
    {
        public static void Main()
        {
            IAccount myAccount = new AccountProxy();

            Console.WriteLine("Logging into the account...");
            myAccount.LogIn("jacek", "password");

            Console.WriteLine("Your balance is: {0}", myAccount.Balance());

            Console.WriteLine("Payment 500.00 $ into the account...");
            myAccount.CashIn(new decimal(500.00));

            Console.WriteLine("Your balance is: {0}", myAccount.Balance());

            Console.WriteLine("Payment 250.00 $ from the account...");
            myAccount.CashOut(new decimal(250.00));

            Console.WriteLine("Your balance is: {0}", myAccount.Balance());

            Console.WriteLine("Logging out from the account");
            myAccount.LogOut();

            Console.WriteLine("Your balance is: {0}", myAccount.Balance());

            Console.WriteLine("--------------------\n");
            Console.WriteLine("Logging into the account...");
            myAccount.LogIn("jacek", "wrongPassword");

            Console.WriteLine("Payment 200.11 $ from the account...");
            myAccount.CashOut(new decimal(200.11));

            Console.WriteLine("Logging out from the account");
            myAccount.LogOut();
        }
    }
}

OUTPUT:

Logging into the account…
Your balance is: 0
Payment 500.00 $ into the account…
Your balance is: 500
Payment 250.00 $ from the account…
Your balance is: 250
Logging out from the account
You are not log in to the account !!
Your balance is: -1
——————–
Logging into the account…
Invalid password !!
Payment 200.11 $ from the account…
You are not log in to the account !!
Logging out from the account You are not log in to the account !!

Use when

You have objects that:

  • Are expensive to create.
  • Need access control.
  • Access remote sites.
  • Need to perform some action whenever the are accessed.

You want to:

  • Create objects only when their operations are requested.
  • Perform checks or housekeeping on objects whenever accessed.
  • Have a local object that will refer to a remote object.
  • Implement access rights on objects as their operations are requested.

Bibliography

Advertisements

One thought on “Design patterns in C# – part 2 (Proxy pattern)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s