Object Oriented Programming Patterns for Geeks

The Facade Pattern

 

namespace ooppatterns
{
    using System;
    using System.Collections.Generic;

    internal class Program
    {
        private static void Main( string[] args )
        {
            // the facade object - used to make the
            // order process it wraps easier to use
            OrderProcessor SC = new OrderProcessor();

            if ( !SC.PlaceOrder( "Matt", "Haujobb", 2 ) )
                Console.WriteLine( "Order could not be sent!" );

            Console.WriteLine( new string( '-', 50 ) );

            if ( !SC.PlaceOrder( "Bob", "Fight Club", 3 ) )
                Console.WriteLine( "Order could not be sent!" );

            Console.WriteLine( new string( '-', 50 ) );

            if ( !SC.PlaceOrder( "Mick", "Aladin", 1 ) )
                Console.WriteLine( "Order could not be sent!" );

            Console.WriteLine( new string( '-', 50 ) );

            if ( !SC.PlaceOrder( "Andy", "Haujobb", 2 ) )
                Console.WriteLine( "Order could not be sent!" );

            Console.ReadLine();
        }
    }

    // The facade (or wrapper)
    class OrderProcessor
    {
        // The objects the facade is wrapping
        private StockRoom _SR = new StockRoom();
        private Accounts _AC = new Accounts();
        private Delivery _DE = new Delivery();

        // A simplified method...
        public bool PlaceOrder( string customer, string product, int units )
        {
            // the more complicated process...
            if ( this._SR.CanFullfillOrder( product, units ) )
            {
                item order = this._SR.RequestItem( product, units );

                order.costInPence += this._DE.DeliveryCost( order );

                this._AC.ChargeCustomer( customer, order );

                this._DE.Dispatch( customer, product, order );

                return true;
            }
            else
            {
                Console.WriteLine( "Stock room had insufficient stock" );

                return false;
            }
        }
    }

    // The following objects represent the subsystem(s)...
    class item
    {
        public int unitsInStock;
        public int costInPence;

        public item( int unitsInStock, int costInPence )
        {
            this.unitsInStock = unitsInStock;
            this.costInPence = costInPence;
        }
    }

    class StockRoom
    {
        private Dictionary<string, item> _stock = new Dictionary<string, item>();

        // pretend this data is sourced from a DB...
        public StockRoom()
        {
            this._stock.Add( "Haujobb", new item( 3, 1000 ) );
            this._stock.Add( "Fight Club", new item( 2, 1200 ) );
            this._stock.Add( "Aladin", new item( 4, 800 ) );
        }

        public bool CanFullfillOrder( string product, int units )
        {
            Console.WriteLine( "Checking stock of {0}.", product );

            if ( !this._stock.ContainsKey( product ) )
                return false;

            return this._stock[product].unitsInStock >= units;
        }

        public item RequestItem( string product, int units )
        {
            if ( !this._stock.ContainsKey( product ) )
                return null;

            if ( this._stock[product].unitsInStock >= units )
            {
                item prod = this._stock[product];

                item retVal = new item( units, prod.costInPence * units );

                prod.unitsInStock -= units;

                Console.WriteLine( "Stock room has picked order of {0} x {1}. " +
@"There are {2} units left in stock."
, units, product, prod.unitsInStock ); return retVal; } else return null; } } class Accounts { public void ChargeCustomer( string customer, item order ) { Console.WriteLine( "Customer '{0}' has been charged {1} pence.",
customer
, order.costInPence ); } } class Delivery { public int DeliveryCost( item order ) { int postage = order.unitsInStock * 45; Console.WriteLine( "Postage for {0} units is {1}.", order.unitsInStock,
postage
); return postage; } public void Dispatch( string customer, string product, item order ) { Console.WriteLine( "{0} x {1} units at {2} has been dispatched to {3}.",
product
, order.unitsInStock, order.costInPence, customer ); } } }