I'm trying to create a food ordering application. It will recieve menu data from a webservice (format not yet decided), and turn it into an order form.
I'm having trouble working out how to approach pizzas - they are more complicated than anything else as you can choose the size, base, toppings etc.
I want to have a class of Product, which I can create for each item in the menu. Then, this product will be given objects of class Size and Option. This allows a pizza to be created, its size set (e.g. regular/large/xl) and a set of toppings (Option) to be set.
I need, somehow, for the Option objects to know what the Size of the Product is. I need to do this, as a topping may cost £5 for a regular pizza, but the same topping cost £7 for a large one. Ideally, Option wouldn't be an element of Size, as the options available stay the same for each size - only the price changes.
My (probably wrong) model looks like this: http://yuml.me/diagram/scruffy/class/%5BPizza%5D-%3E%5BToppings%5D,%20%5BPizza%5D-%3E%5BSize%5D
Any ideas on how I could achieve this?
Having actually written software to deal with this, I found having sub-items to represent options worked best. In essence, allow items to have sets of sub-items, and then those sub-items can have sets of more sub-items, etc. Each option is really an just another item (it's got a name and a price), only it's related to another item. So in your example, it might look like this:
Pizza (Item)
|--> Size (ItemSet)
| |--> Large ($15) (Item)
| | |--> Toppings (ItemSet)
| | |--> Pepperoni ($7) (Item)
| | |--> Anchovies ($7) (Item)
| |--> Regular ($10) (Item)
| |--> Toppings (ItemSet)
| |--> Pepperoni ($4) (Item)
| |--> Anchovies ($4) (Item)
|--> Crust (ItemSet)
|--> Thin (Item)
|--> Deep-Dish (Item)
The Pizza item has a Size itemset, which contains 2 items (large or regular), each of which has their own Toppings itemset, which contains the list of toppings for each, each with their own pricing. You can have multiple itemsets per item (and most likely would need them). I showed this with the crust itemset. Sub-items don't have to have pricing of their own. Generally pricing is additive, so the top-level item (pizza) usually has the base price, and then sub-items selected have their price added onto the base price as the user selects them.
I would suggest the Decorator pattern as a starting point.
A base Pizza class will have properties and methods for adding sauces, toppings, etc. Decorators can modify the size of the base Pizza. For example, an ExtraLargePizza decorator will change the size. Each decorator should expose the functionality for calculating the cost of the pizza. This is because the decorator knows its own size.
Related
I am trying to program an iPhone App that will create a card set of 10 cards.
The total deck includes about 100 cards with different properties:
Each card has a name, a suit and a cost.
For an example:
card.name = "Test"
card.cost = 2
card.suit = "BasicSet"
Let's suppose there are 4 "Sets"* with 20 cards each.
I want the user to be able to select the suit themselves, because most of the suits come from extension sets.
To make it more balanced, I will also decide a maximum and minimum amount of cards with a specific cost (the cost ranging from 2 - 6).
In the end, there will be 2 functions. One function that selects all valid cards (from the available card suits) and another that picks 10 cards at random (taking into account the cost).
What is the easiest way to implement the cards? Defining the class card and implementing the 100 cards? Or creating 3 arrays with name, cost and origin where one card has the same index in all 3 arrays?
Help would be appreciated?
EDIT:
Each Suit contains unique cards. So if my suits are diamond, spade and so on, there will only be a diamond king, but no spade king.
Just an example how it could look like:
Suit Basic {
name=Village, cost=2
name=City, cost=3
name=NewYork, cost=6
}
Suit Advanced {
name=Tree, cost=4
name=Forest, cost=5
}
Suit Special {
name=Cocktail, cost=2
name=OrangeJuice, cost=4
}
One class Card could store all necessary information and functions for basic operations. When Card class is ready, you could create objects of that class with your data parsed from plist or any other format. It's not really necessary to hardcode your data inside the app.
This is a very special problem I met in Prestashop.
I have a product, let's say a two color wooden stick, which is a normal 10" long stick. Half of it (5") can be blue and the other half red for example.
My product is this: Two color wooden stick. I have the following features: color 1 and and color 2 .
In the admin at the product's features I check red for the color 1 and blue for color 2.
Now the problem: when user filters using layered navigation, maybe they select blue for color 1 and red for color 2. This will result displaying 0 products as our wooden stick is inverse, but in the reality it's the same product.
How could I make that possible without duplicating the wooden stick product?
I see there is mismatching, your product 10" is not blue OR red, but blue-red in same time, so set two different colors is bad idea, instead I can propose you to do next, I hope when you said that you use color features it is named in Presta backoffice attributes, there is the difference between two this things in Presta, so:
in Catalog -> Product Attributes create new P.Attribute with name Color and for last option choose Color or textures in dropdown
add new Value for this new Color p.atrribute named e.g. "blue-red" and upload texture (img) that contains both colors. Repeat this procedure as much as needed.
in Layered navigation use this new p.attribute instead old
OR
another idea, create using same way 2 different color attributes Color1 and Color2, no textures, just use real separate colors there like "red", "blue". Then in product create combinations of this two colors and assign it to product.
In this case in layered navigation you will can set 2 filters - Color1, Color2 and customers will can to choose it. But, imho, first solution is better for UX.
I want to suggest recipes to my users, so I'm fetching recipes from a JSON source (including their ingredients).
At the moment, ingredients can be fetched from three ways:
3 tomatoes (no particular unit)
125ml of milk (volume unit, either metric or imperial)
500g of pasta (mass unit, either metric or imperial)
Requirements
I want to use a DDD approach, so a layered architecture.
I need to be able to display the ingredient as-is, like suggested in my bullet list above. The user can choose between a metric or imperial view.
3 tomatoes
125ml of milk or 1/2 cup of milk
55g of pasta or 2 ounces of pasta
My challenge
I'm not sure how to design the class in order to respect encapsulation and to ensure an easy-to-maintain design.
My first idea was to represent units with a Unit class, so my Ingredient class would hold a quantity and a unit. But in some cases, the ingredient is unitless. With this idea in mind, my IngredientPresenter would look like this:
public String present(Ingredient ingredient) {
if ( ingredient.isUnitless() )
return ingredient.getQuantity() + " " + ingredient.getName();
else
return ingredient.getUnit() + " " + ingredient.getName();
}
I'm not convinced with this approach since I could have many different types of units, and so my IngredientPresenter would grow rapidly (and violating OCP).
Then, I thought I could go with polymorphism. While it seems a good approach, I don't know what to expose in my interface since my implementations would be completely different. I would need to expose my methods in implementations, so loosing all the benefits of polymorphism. My IngredientPresenter would look like below:
public String present(Ingredient ingredient) {
if ( ingredient instanceof UnitlessIngredient ) {
UnitlessIngredient actualIngredient = (UnitlessIngredient) ingredient;
return actualIngredient.getQuantity() + " " + actualIngredient.getName();
} else {
WithUnitIngredient actualIngredient = (WithUnitIngredient) ingredient;
return actualIngredient.getUnit() + " " + actualIngredient.getName();
}
}
Actually, I think my problem is that I don't know how to represent units properly, so I'm looking your help.
Thank you for your time!
Edit
I will not only present my ingredient. In my domain layer, I need to calculate the ingredient's nutriment facts. So, depending on its quantity (or volume, or mass), the calculation is done differently. One simply multiply the nutriment facts by the quantity while the other must perform a pro-rata. That's a perfect case of polymorphism.
Definitely go with polymorphism.
The way this is normally done is that present() stops being a standalone function in a vacuum, and it becomes a method of the Ingredient instead.
So, you essentially call the Ingredient to render itself into a string. Possibly with some parameter indicating metric vs. imperial, which the ingredient may have some use for, or it may ignore if unitless. Simple, elegant, tried, it works.
I know the title probably isn't too clear because I probably don't have the right terminology, but an example should make it clear. Suppose I have an app with posts and comments, what would be the best practice as far as grouping those into namespaces/packages of the various ways. If there's no better way, what are the advantages and disadvantages of both. Here are a couple different ways I envisioned, note this is in no way exhaustive, it's just to get the point across:
1)
MyAp
|--Entities
| |--AbstractEntity.class
| |--Comment.class
| |--Post.class
|--DataMappers
| |--AbstractDataMapper.class
| |--CommentDataMapper.class
| |--PostDataMapper.class
|--DataMappers
| |--AbstractService.class
| |--CommentService.class
| |--PostService.class
2)
MyAp
|--Abstract
| |--AbstractDataMapper.class
| |--AbstractEntity.class
| |--AbstractService.class
|--Impl
| |--Comment
| | |--Comment.class
| | |--CommentDataMapper.class
| | |--CommentService.class
| |--Post
| | |--Post.class
| | |--PostDataMapper.class
| | |--PostService.class
With a big project, you could break either one of the methods above into broader groups. For example, for #1 you could have Db, Util, System, etc. beneath your Entities, DataMappers, and Services namespaces and would place class implementations in there while keep the AbstractEntity class under the Entities namespace. For #2, you could do the same putting those additional namespaces under Abstract and Impl.
I'm leaning towards #1 being better, seems like I would have to add additional Db, Util, System, etc. namespaces to 2 different places. But #2 has the appeal of keeping all classes related to one model class together. Can't make up my mind!
I'd say there's something wrong in both approaches.
Most of developers tend to break classes by their main specialization. Mapper should go to mappers, model should go to models, helpers should go to helpers, interfaces to interfaces, we think first. That can be easy decision an the beginning of the project, but it causes some pain as time passes. It looks rather stupid some times. Especially when you need to extract a certain functionality into a separate component.
From my experience I can say that you should group classes by their high-level function, or 'sub-system', or, as now DDD specifies 'bounded context'. In the same time there shouldn't be very may grouping levels.
So - I can see all of your entities belong to Posting context. It can look strange enough, but I'd suggest that you put all of your classes to Posting fodler and do not create extra subfolders unless you have a very specific functionality area within the context.
MyAp
|--Core
|--AbstractEntity.class
|--AbstractDataMapper.class
|--AbstractService.class
|--Posting
|--Comment.class
|--Post.class
|--CommentDataMapper.class
|--PostDataMapper.class
|--CommentService.class
|--PostService.class
In general your second approach looks similar. In that case you can easy add more and more context-specific folders. Something like - 'Voting', 'Notifications', 'Authentication', etc. Also I'd suggest to choose the simplest way, and wait until you have some 'critical mass' of classes so you'd have enough information about how to group classes correctly.
With the first approach you domain's contexts would be spread over all folders.
In my experience I've seen the first FAR more than I've seen the latter (I don't think I've ever seen a project divided on the first, actually).
Example: let's say you've got an abstract class that uses the Hollywood pattern. All implementing classes would reasonably be in the same package. It doesn't make any sense to have the "master" template off in an "Abstract" package so far from the actual implementation.
The one other thing I would add is SINGULAR IN ALL CASES EXCEPT COLLECTIONS.
MyAp
|--Entity
| |--AbstractEntity.class
| |--Comment.class
| |--Post.class
|--DataMapper
| |--AbstractDataMapper.class
| |--CommentDataMapper.class
| |--PostDataMapper.class
|--Service
| |--AbstractService.class
| |--CommentService.class
| |--PostService.class
Some frameworks like JaxB put configuration information into a package-info.java. In that case the first approach is mandatory to be able to use package-info.java.
Let's say I have to model the meals of a diner.
A meal can consist of several "components":
(Fries OR rice OR wedges)
AND (One of six different beverages)
AND (One or two out of seven different sauces OR none at all)
Another meal can consist of:
(Salad OR rice)
AND (Garlic OR no garlic)
Further meals can consist of:
Just fries
Just a beverage
Just ...
How can I model this? (UML, entity-relationship, code, ... whatever you can explain best)
Perhaps it helps if you know some tasks I want to perform, so:
Allowing the customer to choose a meal first and display all remaining "add-ons".
Detecting a meal from a list of components. For example if the customer ordered fries, a sauce and a beverage, it should be possible to detect the meal from the first example.
I've thought about dividing all components into articles and then adding some kind of role mapping to mark "fries" as supplement to "cheeseburger", "schnitzel", "..." but then I wondered, how I could model multiple add-ons, optional add-ons, n-out-of-m add-ons...
I hope you can help me out...
If this is homework, it may not matter...
But - if this is going to be used in a real-world app, I would strongly recommend against using concrete classes for each food item ie. Coke class, Salad class, Rice class, etc. as recommended above.
This is a sure way to make your application inflexible.
It would be much better to have a food item class and a drink class with a name property or some such..
Imagine having to rebuild your whole application just because there is now a new special or food item... not cool ;).
I think what is missing from the other answers is the idea of a group.
Each food item could belong to a group along with other items, or by itself.
Say fries, rice, and wedges belong to group A. Drinks belong to group B.
Then you could model a combo as a list of groups - ie. 1 group A item and 1 group B item, or two group A items and1 group B item.
You could also make food items able to belong to multiple groups at the same time... to make the options more flexible.
The db model could get complicated defining all of the relationships, but I think it's necessary.
Perhaps something like this:
group(id, name, desc) - group of like items - entrees, appetizers, drinks... or anything
foodItem(id, name, desc) - represents a single item - fries, rice, etc.
foodItem_group(foodIgem_Id, group_Id) - maps food items to their group - many to many
combo(id, name, desc) - describes a combo
combo_group(combo_Id, group_Id) - maps groups to combos - many to many
I think this would do for representing the basic required model - you may want additional tables to store what the customer actually ordered.. and of course detecting if a customer order matches a combo is left up to your business logic.
It seems like an order can consist of either meals, components, or a mix of both, so I would say, have an Order class that has a list of Components and Meals. Meal should either subclass Component, or they should implement the same interface.
A Meal consists of several "slots," which can be filled by some set of Components. Meals should know how many slots they have and what Components can fill them.
The "detecting a Meal from a list of Components" question is tricky. Off the top of my head, the best way I can think of is giving each Meal a method that takes a list of Components and returns true if that Meal can be made from them (or maybe the subset of Components that would make up that Meal). Order would go through the list of Meals it knows about and see if any of them can be made from the Components in the current Order. There may be a better way to do this, though.
Hope this helps!
Create Component class, and sublcasses (or objects) for all possible types of Components.
Create an abstract Meal class, and subclasses for all possible types of Meals. A Meal can check, whether a certain list of Components matches it (for detecting a meal from a list of components). And a Meal can present to a customer all the choices of components for this meal.
I agree with Amanda that the Meal should be built of the "Slots". Each slot represents one of the Component choices of the Meal, e.g. Fries OR rice OR wedges. A Slot may also model the m-outof-n option.
The Meal class:
class Meal
{
class MealSlot
{
Add(Component);
bool DoesItMatch(vector<Component> ComponentsVector)
{
//Check if this Slot is filled by some element(s)
// of ComponentsVector
}
PrintSlotOptions();
vector<Component> Options;
// for m-of-n option, if multiple items can be chosen in this slot
int HowManyNeededToFillIt;
};
bool DoesItMatch(vector<Component> ComponentsVector)
{
//Check if all Slots are filled by ComponentsVector elements,
//using Slot::DoesItMatch function
}
void PresentChoices()
{
for(i=0; i < Slots.size(); i++)
Slots[i].PrintSlotOptions;
}
vector<Slot> Slots;
};
One of Concrete Meals: (Salad OR rice) AND (Garlic OR no garlic)
class MealType2 : public Meal
{
MealType2()
{
Slots[0].Add(Salad);
Slots[0].Add(Rice);
Slots[1].Add(Garlic);
Slots[1].Add(NOTHING);
}
};
Create an Order class which will contain a Meal name, and a list of Components. If a Meal is ordered, call Meal.PresentChoices() . And if a list of Components is given, go over all the Meals and call Meal.DoesItMatch .
I assume this will eventually get stored in a database. I suggest to create two tables:
Would store the components (fries, salad, garlic, etc)
Would have: id1, id2, relationship. Relationship being:
belongs to
goes with
Based on the "belongs to" relationship, you could find if all components belong to a certain meal. Maybe then go and select all components that belong to that meal and suggest the meal if the components selected make up 50% or more of the meal.
Based on the "goes with" relationship, you could suggest add-ons to the meal, or to the components selected.
seems like you meal can be almost any collection of food items, so start with one abstract base class (or interface) for a Food. make lots of concrete subclasses, one for each food: coke, tea, steak, chicken, potato, rice, pasta, soup, salad, etc.
make your components interfaces: appetizer, dinner, protein, starch, dessert, drink, etc.
refactor your concrete classes into whatever hierarchy they seem to want to go into as you write code and tests.
sprinkle in the component interfaces where they make sense.