简体   繁体   中英

Forcing the execution of a method

I'm writing a grocery cart simulation app

Here is my situation, I want to force a type to execute a method it has defined for itself...

Basically I have an interface

interface IGroceryCart
{
   // Other methods snipped for clarity
   void Checkout(IEnumerable<IGroceryItem> itemsToBuy);
}

Now the IGroceryItem interface looks like this

interface IGroceryItem
{
   // Other methods snipped for clarity
   CheckoutIssues EnsureFreshness();
}    

IGroceryCart and IGroceryItem have concrete implementations obviously, but what I am trying to do is this:

When I call Checkout on a grocery cart, I want all the items that are being checked out to internally call their EnsureFreshness() method and then react accordingly if one or more items had CheckoutIssues

CheckoutIssues is just something like

class CheckoutIssues
{
   string Description {get;set;}
   //etc
}

What would be the best way to implement a way that EnsureFreshness has been called on each grocery item? Or an alternate approach that is better to get these kind of errors? Should I go the custom validator route? Each grocery item may have its own way of checking freshness, milk would be different from Eggs for example, so I have to rely on each individual implementation, but I'd like to force that call on checkout, hope that makes sense.

You could just put it in your Checkout method, and add the returned object to some collection to deal with:

List<CheckoutIssues> issues = new List<CheckoutIssues>();
foreach (IGroceryItem item in itemsToBuy) {
    issues.Add(item.EnsureFreshness());
}

Well lets say you go to Walmart and add items to the Cart , is it the duty of the Cart to checkout or is it the duty of the employer at counter to checkout?

I feel it is wired to have method Checkout on Shopping Cart . If I were you I would probably take this route.

 interface IGroceryCart
{

   /**void Checkout(IEnumerable<IGroceryItem> itemsToBuy);**/
   void AddItem(IEnumerable<IGroceryItem> itemsToBuy)//I like to add items to Grocery Cart.
}

I should be able to add Item to the GroceryCart.

The second issue is when you add Apples to the cart in Walmart, the apple does not know if it fresh or expired or rotten.

    interface IGroceryItem
    { 
       CheckoutIssues EnsureFreshness(); //I am skeptic about having this method on GroceryItem
    }   

    class GroceryCart:IGroceryCart
    {
       public void AddItem(IEnumerable<IGroceryItem> itemsToBuy)
       {

       }
    }

    class Billing
   {


    public decimal BillItems(GroceryCart cart)
    {
         foreach item in cart
           if(itemIsfresh)
             Bill it.
    } 



     private bool IsItemFresh(GroceryItem item)
     {

     }

  }

What is wrong with what you have? Why not just iterate through your itemsToBuy and call EnsureFreshness on each? If any errors come back, Checkout could throw an Exception, or it could be changed to return the list of errors, or just the first error.

Does that help?

What not having something like that:

public abstract GroceryCart : IGroceryCart
{
    public void Checkout(IEnumerable<IGroceryItem> itemsToBuy)
    {
        foreach (var item in itemsToBuy)
        {
            item.EnsureFreshness();
        }

        this.InternalCheckout(itemsToBuy);
    }

    protected abstract void InternalCheckout(IEnumerable<IGroceryItem> itemsToBuy);
}

Now just inherit from your abstract class rather than implementing the interface. And in your third party classes have a reference to GroceryCart rather than IGroceryCart when you need to enfore that freshness is checked. Where it's not mandatory, continue to use IGroceryCart .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM