Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > ASP.NET and ASP > Other ASP.NET > BOOK: Professional ASP.NET Design Patterns
Password Reminder
Register
Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
BOOK: Professional ASP.NET Design Patterns
This is the forum to discuss the Wrox book Professional ASP.NET Design Patterns by Scott Millett; ISBN: 978-0-470-29278-5
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Professional ASP.NET Design Patterns section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developersí questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old February 15th, 2011, 06:58 AM
Authorized User
Points: 448, Level: 7
Points: 448, Level: 7 Points: 448, Level: 7 Points: 448, Level: 7
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jan 2011
Posts: 86
Thanks: 1
Thanked 12 Times in 12 Posts
Default State pattern versus Strategy Pattern

Hi,

let me say first of all that I find this book magnificent. Having a bit of a bore-out at work, this book gives me more fun with coding than I have had in a long time. I'm only just starting with it (chapter 5 now), but can see its applicability already.

But to start with my actual question... is it me, or is the difference between State pattern and Strategy pattern really thin?

I'm trying to use this for a simple purchase approval processing webform and lean towards the strategy pattern to use.. (Depending on whether the request is already in process with a supplier (hence its state) concretestrategy A or B must be used ...)

Although it is the state of the request that governs the actual method, it feels more natural to use the strategy pattern. Looking at the UML they are almost alike... so I tend to believe there is no harm to use this. Or am I missing some big difference in the two patterns here?
Reply With Quote
  #2 (permalink)  
Old February 18th, 2011, 10:11 AM
elbandit's Avatar
Wrox Author
Points: 599, Level: 8
Points: 599, Level: 8 Points: 599, Level: 8 Points: 599, Level: 8
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: May 2007
Location: Southsea, Portsmouth, Hampshire, United Kingdom.
Posts: 107
Thanks: 11
Thanked 17 Times in 15 Posts
Default

Hi disel2010,

Thanks for reading the book!

Yes the two patterns do look very similar this is because they are both employing polymorphism at their core. Let's take a look at their definitions:

The state pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class.

The strategy pattern defines a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

So you can see that they are concerned with two very different things.

Ok lets take a look at your problem..

Quote:
I'm trying to use this for a simple purchase approval processing webform and lean towards the strategy pattern to use.. (Depending on whether the request is already in process with a supplier (hence its state) concretestrategy A or B must be used ...)
I am not sure of the intricacies of your problems but lets assume that the purchase order can be in the following states:

- Open
- Submitted
- Approved
- Rejected

Lets also assume that we need to alert people when the purchase order state changes. Some people want to be alerted by text messages, others by email. In order to notify interested parties we need to apply the correct notification strategy. Hopefully you can see from the sentance above where the patterns fit. Here is some code to see it all in action...

Code:
 
    public class PurchaseOrder
    {
        private IPurchaseOrderState _internal_state;
        
        public PurchaseOrder() : this(new PurchaseOrderOpenState())
        { }
        public PurchaseOrder(IPurchaseOrderState initial_state)
        {
            _internal_state = initial_state;
        }
        public bool can_add_item()
        {
            return _internal_state.can_add_item();
        }
        public void add(Item item_to_purchase)
        {
            if (can_add_item())
            {
                // update internal storage...
            }
            else            
                throw new ApplicationException("You can't do this...");            
        }
        public void submit()
        {
            _internal_state.submit();
        }
        public void approve()
        {
            _internal_state.approve();
        }
        
        public void change_state_to(IPurchaseOrderState new_state)
        {
            _internal_state = new_state;
        }
        public bool is_valid_for_submission()
        {
            // check all is ok....
            return true;
        }
        public Person approver { get; set;  }
        public Person originator { get; set; }
        public void notify_approver_with(string message)
        {           
             approver.send(message);          
        }
        public void notify_originator_with(string message)
        {
            originator.send(message);
        }
    }
    public class Person
    {
        // This is the strategy
        public INotificationChanncel notification_channel { get; set; }
        public void send(string message)
        {
            notification_channel.send(message);
        }
    }
    public interface INotificationChanncel
    {
        void send(string message);
    }
    public class EmailNotificationChanncel : INotificationChanncel
    {
        private readonly EmailAddress _emailAddress;
        public EmailNotificationChanncel(EmailAddress email_address)
        {
            _emailAddress = email_address;
        }
        public void send(string message)
        {
            // email...
        }
    }
    public class PurchaseOrderOpenState : IPurchaseOrderState
    {        
        public bool can_add_item()
        {
            return true;
        }
        
        public void submit(PurchaseOrder purchase_order)
        {
            if (purchase_order.is_valid_for_submission())
            {
                purchase_order.notify_approver_with("PO is now submitted");
                purchase_order.change_state_to(new PurchaseOrderSubmittedState());
            }
        }
        public void approve(PurchaseOrder purchase_order)
        {
            // need to submit first
            throw new ApplicationException("You need to a submit an application before approval.");
        }        
    }
    public class PurchaseOrderSubmittedState : IPurchaseOrderState
    {
        public bool can_add_item()
        {
            return false;
        }
        public void submit(PurchaseOrder purchase_order)
        {
            // need to submit first
            throw new ApplicationException("This PO has already been submitted.");
        }
        public void approve(PurchaseOrder purchase_order)
        {
            purchase_order.notify_originator_with("PO is now approved"));
            purchase_order.change_state_to(new PurchaseOrderSubmittedState());
        }
    }
    public interface IPurchaseOrderState
    {
        bool can_add_item();
        void submit(PurchaseOrder purchase_order);
        void approve(PurchaseOrder purchase_order);        
    }
Hopefully you can see the difference. If I haven't answered your question please reply.

Cheers
Scott
Reply With Quote
The Following 2 Users Say Thank You to elbandit For This Useful Post:
disel2010 (February 19th, 2011), ksouthworth (March 22nd, 2011)
  #3 (permalink)  
Old March 15th, 2011, 09:20 AM
Registered User
Points: 11, Level: 1
Points: 11, Level: 1 Points: 11, Level: 1 Points: 11, Level: 1
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Mar 2011
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Scott,
This is a great book! Wish I had bought it sooner! I have a quick question regarding the following scenario:
a patient's visit to an outpatient clinic can be in any of the following states:
pending, kept, cancelled.
if the visit is kept, a therapist treats the patient and enters charge codes for the services rendered to the patient; so, there is a new state (charge entry state) than can be partially entered or complete.
when charges are complete, the visit and the charges are billed so you could say that a visit can be billed or not or put on hold.
The current system I am maintaining is using one property where all the above statuses are mixed in. Should I create 3 properties, one for the visit status, one for charge entry status and one for billing status?
Please advise.
Thanks,
Huambo
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Strategy Pattern g2eenday BOOK: Professional PHP Design Patterns 1 July 3rd, 2010 05:10 PM
Differences between Delegate AND Strategy Pattern Luka77 BOOK: Professional PHP Design Patterns 2 April 28th, 2010 06:40 PM
Pattern extension? tdewey BOOK: ASP.NET 3.5 Enterprise Application Development with Visual Studio 2008: Problem Design Solutio 1 May 13th, 2009 11:20 PM
DirectoryInfo.GetFiles(pattern): search pattern fo arif_1947 VS.NET 2002/2003 1 October 20th, 2004 12:59 AM



All times are GMT -4. The time now is 04:18 AM.


Powered by vBulletin®
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.