I’m creating an app for managing a store. I need to manage the following data relating to each product: the name, the purchase cost and the sales prices (which depend on which retailer is selling the product). In the following image I have represented in the table the data that I need to save and manage.
I know that over time, those who use the app will need to enter new products and new ‘price groups’ (the ‘Selling Price …’ columns of the table).
I’m using an object oriented language (Dart). What could be the best way to organize the code? What classes should I create?
If you need more details, please let me know. Thank you very much!
You probably need just one class Product:
class Product {
final String name;
final double cost; // Or int
final List<int> sellingPrice;
const Product(this.name, this.cost, this.sellingPrice);
}
Then you can get and add selling prices to the list inside the object.
This assumes that the selling price is just a number. If, for example, you want to keep track also of the timestamp of the selling price then you would need another class:
class SellingPrice {
final double price;
final DateTime timestamp;
const SellingPrice(this.price, this.timestamp);
}
class Product {
final String name;
final double cost; // Or int
final List<SellingPrice> sellingPrice;
const Product(this.name, this.cost, this.sellingPrice);
}
A lot depends on how you plan to interact with the object. There could be more efficient structures or different organizations (for example not using a List but a Set).
Related
Lately I was wondering if it is a bad practice to use variables in your code that are related to each other (e.g. a = 2 * b). A concrete example would be euro and dollars. Let's say we have a Person class who has some balance in euros and dollars (coded in java for demonstration):
class Person {
float balanceInEuros;
float balanceInDollars;
public Person(...) { // Problem 1 (see down below)
}
}
Problem 1: What do you need to put in the constructor arguments? Both variables are float so we can't differentiate between to distinct constructors (java can have multiple constructors for a class, as long as they have a different type of arguments). To solve this we can make two separate methods to return a Person, for example:
public static createPersonWithEuros(float euros) {
Person person = new Person();
person.setEuros(euros);
return person;
}
// Similar for dollars...
Problem 2: Now we have no value for the dollars, so a method person.getDollars() would result in an error. Of course this can be fixed again by adding a single line in the createPersonWithEuros() method: person.setDollars(Person.EXCHANGE_RATE_EURO_DOLLAR * euros) or something along those lines.
Arguments for
It feels more natural to use dollars and euros instead of a so called 'balance' which has no concrete meaning.
It makes more sense and thus enhances the readability of the code
Arguments against
By using a universal 'balance' with functions to calculate to euros/dollars etc., it results in cleaner code (less functions/bulk code...)
You need more memory to store essentially the same thing, which could be bad
What is better and why?
EDIT: Another thing I am concerned with is that I programmed this particular example in an OO language. What if this was written in javascript for example?
By creating a separate class Balance which has an amount and a currency, you can use a single constructor with a 'balance' parameter and use euros, dollars, pounds and so on as you like. All conversion goes to the Balance class and Person can use balances regardless of currencies, conversion rates and so on.
I have an OOP design question.
Let's assume that I have a class that contains several numerical scalar properties like maximum, minimum, frequency etc. Since data are flowing in continuously I eventually end up with a list of such class instances. To obtain, say, the global minimum I loop over all classes in the list to find it.
Alternatively, I could instantiate one class (possibly a singleton) that contains lists instead of scalars for each property, and function members that loop over the lists. This approach however seems to generate code that looks more like procedural than object oriented programming.
The question is: What criterions define which approach to choose? If efficiency is important, should I choose one class that contains lists for each properties? If readability is key, should I choose a list of classes?
Thanks for suggestions.
Basically you're askyng if it's more preferable to have an "Array of Structures (AoS)" or "Structure of Arrays (SoA)"
The answer depends on what you need to do with this data. If you want to write a more readable code than go for an Array of Structures, if you want to use SSE or CUDA to optimize your computation-heavy code then go for a Structure of Arrays.
If you search in literature the terms "Array of Structures (AoS)" and "Structure of Arrays (SoA)" you will find many in depth dissertations on this topic, i link just some discussions here:
Structure of arrays and array of structures - performance difference
http://hectorgon.blogspot.it/2006/08/array-of-structures-vs-structure-of.html
http://people.maths.ox.ac.uk/~gilesm/hpc/NVIDIA/NVIDIA_CUDA_Tutorial_No_NDA_Apr08.pdf
http://en.wikipedia.org/wiki/Stream_processing
You were asking for decision criteria. Let me recommend one:
You should think about what constitutes a data point in your application. Let's assume you are measuring values, and one data point consists of several numerical properties. Then you would certainly want a list of classes, where the class represents all of the properties that go together (what I called 'data point' for lack of a better term).
If you must perform some aggregation of these 'data points', such as finding a global minimum over a longer time period, I would suggest designing an extra component for this. So you'd end up with a data gathering component which consists mainly of a 'list of classes', and an aggregation component which may utilize different data structures, but processes parts of your 'list of classes' (say, the part over which the global minimum is to be found).
Basically, OOP is not a solution to every question in programming, sometimes you have to see beyond this,below this. The thing is you have to concentrate on the problem. Efficiency should be more preferable. But if your code is taking too much time to load or you can say its time complexity is too much high then again you'll have trouble. You have to keep to keep both ends in hands. What i'll prefer is the list of classes not the class of list. But different people have different point of views and so we should respect them. Why i am chosing list of classes because,i'll have each object with the respected data, say , i have one object with higher frequency,one with lower,one with a medium,it will be easier to manage all that,plus not much time will be taken. i think in both cases it will be O(n) where n is the number of elements or classes in my case.
In your case, list of data
struct Statistic{
int max;
int min;
std::vector<int> points;
int average;
};
int main(){
std::vector<Statistic> stats;
return 0;
}
You could also store the values and the statistics together in one class and do the calculations on the fly when adding a new value (example in Java):
public class YourClass {
private List<Integer> values = new ArrayList<Integer>();
private long sum = 0;
private int minimum = Integer.MAX_VALUE;
private int maximum = Integer.MIN_VALUE;
// add more stuff you need
public synchronized void add(Integer value) {
values.add(value);
sum += value;
if (value < minimum) {
minimum = value;
}
if (value > maximum) {
maximum = value;
}
}
public List<Integer> getValues() {
return Collections.unmodifiableList(values);
}
public long getSum() {
return sum;
}
public long getAvg() {
return values.isEmpty() ? 0 : sum / values.size();
}
public int getMaximum() {
return maximum;
}
public int getMinimum() {
return minimum;
}
}
Assume we have class Car which MAIN field is called VIN (Vehicle Identification Number). VIN gives us a lot of information such us:
owner
place of registration
country of production
year of production
color
engine type
etc. etc
I can continue and add more information:
last known GPS coordinates
fine list
is theft (boolean)
etc. etc.
It seems reasonable to store some of information (for example year of production and engine type) right inside Car object. However storing all this information right inside Car object will make it too complicated, "overloaded" and hard to manage. Moreover while application evolves I can add more and more information.
So where is the border? What should be stored inside Car object and what should be stored outside in something like Dictionary<Car, GPSCoordinates>
I think that probably I should store "static" data inside Car object so making it immutable. And store "dynamic" data in special storages.
I would use a class called CarModel for the base attributes shared by every possible car in your application (engine size, color, registration #, etc). You can then extend this class with any number of more specific subclasses like Car, RentalCar, or whatever fits your business logic.
This way you have one clear definition of what all cars share and additional definitions for the different states cars can be in (RentalCar with its unique parameters, for example).
Update:
I guess what you're looking for is something like this (although I would recommend against it):
public class Car
{
// mandatory
protected int engineSize;
protected int color;
// optional
protected Map<String, Object> attributes = new HashMap<String, Object>();
public void set(String name, Object value)
{
attributes.put(name, value);
}
public Object get(String name)
{
return attributes.get(name);
}
}
Why this is not a good solution:
Good luck trying to persist this class to a database or design anything that relies on a well known set of attributes for it.
Nightmare to debug potential problems.
Not a very good use of OOP with regard to type definitions. This can be abused to turn the Car class into something it is not.
Just because your Car class provide a property GPSCoordinates does not mean you need to hold those coordinates internally. Essentially, that's what encapsulation is all about.
And yes, you can then add properties such as "IsInGarageNow", "WasEverDrivedByMadonna" or "RecommendedOil".
Here briefly are the business requirements.
I have an entity called PricingSchedule that represents a "subscription" to a system. We use the term "Pricing Schedule", not "subscription" in our team's ubiquitous language, but in theory, a subscription is the same thing.
What determines the Price of the PricingSchedule is the combination of two things:
1. the "duration" of the PricingSchedule (aka, how long is your subscription... 1 year, 2 years, etc...
2. how many Styles (another entity) you want to include in your PricingSchedule. You have two options for how to include Styles; 1. pay per Style, 2. pay for all Styles
Number two is a newly added requirement. Before, it was primarily the PricingSchedule's Duration that determined the Price.
My problem is this... the Price of a PricingSchedule doesn't mean anything when either the Duration, or StylePricingType is applied by itself. I can only get the final Price when they're combined together; aka, 2 years duration with 5 styles.
We have four possible pre-determined durations, ranging from a couple of days, to a 3 or 4 years.
We have two possible ways to bill Style selection; 1. per Style or 2. all Styles. These two things combined then determined the overall Price.
I started thinking the Strategy design pattern could help me here, aka;
public interface IDurationPricingStrategy
public decimal GetDurationPriceFor(PricingSchedule)
public interface IStylePricingStrategy
public decimal GetStylePriceFor(PricingSchedule)
This is a good way to separate things that probably will change going forward, but herein lies the rub; I can't implement one Strategy without knowing the other Strategy's "conditionals."
For example, for the IStylePricingStrategy, I implement the unlimited style pricing option like so:
public class UnlimitedStylePricingStrategy : IStylePricingStrategy
{
public decimal GetStylePriceFor(PricingSchedule)
{
if (PricingSchedule.Duration.Type == DurationType.OneYear)
{
return decimal x;
}
if (PricingSchedule.Duration.Type == DurationType.TwoYears)
{
return decimal x;
}
}
}
if I take this approach, that means if and when I have to add or change a Duration pricing type, then I have to change my StyleStrategy implementation class, which breaks SRP, and basically puts me back to square one.
It's easy if there is only one "thing" that determines the Price for the PricingSchedule, but when I have two things like this, that's where I'm hitting a wall.
Is there another pattern I can use, or somehow use the Strategy pattern differently? I feel that the problem still pulls me towards Strategy, but I'm not sure how to incorporate two Strategies instead of one.
Thanks so much!
Mike
I think one way might be to create an interface for the duration:
public interface IDuration
{
int GetDuration();
decimal CalculatePrice(object whatever); // int something, or whatever.
}
The have your schedule class use it:
public class PricingSchedule
{
public IDuration Duration { get; set; }
}
Then your payment style classes could use the duration like so:
public class UnlimitedStylePricingStyle : PricingStyle
{
public override void GetStylePriceFor(PricingSchedule schedule)
{
int duration = schedule.Duration.GetDuration();
//.....
}
}
The tricky one is days, I'm not sure how you would deal with that, but I would think that using an interface is your best bet here. If you need to add a new duration, you simply implement the interface IDuration.
You could then calculate the price by something like:
public override void GetStylePriceFor(PricingSchedule schedule)
{
int duration = schedule.Duration.GetDuration();
int temp = 34;
decimal result = schedule.Duration.CalculatePrice(temp);
}
Hope this give you a rough idea.
Soliciting feedback/options/comments regarding a "best" pattern to use for reference data in my services.
What do I mean by reference data?
Let's use Northwind as an example. An Order is related to a Customer in the database. When I implement my Orders Service, in some cases I'll want the reference a "full" Customer from an Order and other cases when I just want a reference to the Customer (for example a Key/Value pair).
For example, if I were doing a GetAllOrders(), I wouldn't want to return a fully filled out Order, I'd want to return a lightweight version of an Order with only reference data for each order's Customer. If I did a GetOrder() method, though, I'd probably want to fill in the Customer details because chances are a consumer of this method might need it. There might be other situations where I might want to ask that the Customer details be filled in during certain method calls, but left out for others.
Here is what I've come up with:
[DataContract]
public OrderDTO
{
[DataMember(Required)]
public CustomerDTO;
//etc..
}
[DataContract]
public CustomerDTO
{
[DataMember(Required)]
public ReferenceInfo ReferenceInfo;
[DataMember(Optional)]
public CustomerInfo CustomerInfo;
}
[DataContract]
public ReferenceInfo
{
[DataMember(Required)]
public string Key;
[DataMember(Required)]
public string Value;
}
[DataContract]
public CustomerInfo
{
[DataMember(Required)]
public string CustomerID;
[DataMember(Required)]
public string Name;
//etc....
}
The thinking here is that since ReferenceInfo (which is a generic Key/Value pair) is always required in CustomerDTO, I'll always have ReferenceInfo. It gives me enough information to obtain the Customer details later if needed. The downside to having CustomerDTO require ReferenceInfo is that it might be overkill when I am getting the full CustomerDTO (i.e. with CustomerInfo filled in), but at least I am guaranteed the reference info.
Is there some other pattern or framework piece I can use to make this scenario/implementation "cleaner"?
The reason I ask is that although we could simply say in Northwind to ALWAYS return a full CustomerDTO, that might work fine in the simplistic Northwind situation. In my case, I have an object that has 25-50 fields that are reference/lookup type data. Some are more important to load than others in different situations, but i'd like to have as few definitions of these reference types as possible (so that I don't get into "DTO maintenance hell").
Opinions? Feedback? Comments?
Thanks!
We're at the same decision point on our project. As of right now, we've decided to create three levels of DTOs to handle a Thing: SimpleThing, ComplexThing, and FullThing. We don't know how it'll work out for us, though, so this is not yet an answer grounded in reality.
One thing I'm wondering is if we might learn that our services are designed at the "wrong" level. For example, is there ever an instance where we should bust a FullThing apart and only pass a SimpleThing? If we do, does that imply we've inappropriately put some business logic at too high of a level?
Amazon Product Advertising API Web service is a good example of the same problem that you are experiencing.
They use different DTOs to provide callers with more or less detail depending on their circumstances. For example there is the small response group, the large response group and in the middle medium response group.
Having different DTOs is a good technique if as you say you don't want a chatty interface.
It seems like a complicated solution to me. Why not just have a customer id field in the OrderDTO class and then let the application decide at runtime whether it needs the customer data. Since it has the customer id it can pull the data down when it so decides.
I've decided against the approach I was going to take. I think much of my initial concerns were a result of a lack of requirements. I sort of expected this to be the case, but was curious to see how others might have tackled this issue of determining when to load up certain data and when not to.
I am flattening my Data Contract to contain the most used fields of reference data elements. This should work for a majority of consumers. If the supplied data is not enough for a given consumer, they'll have the option to query a separate service to pull back the full details for a particular reference entity (for example a Currency, State, etc). For simple lookups that really are basically Key/Value pairs, we'll be handling them with a generic Key/Value pair Data Contract. I might even use the KnownType attribute for my more specialized Key/Value pairs.
[DataContract]
public OrderDTO
{
[DataMember(Required)]
public CustomerDTO Customer;
//in this case, I think consumers will need currency data,
//so I pass back a full currency item
[DataMember(Required)]
public Currency Currency;
//in this case, I think consumers are not likely to need full StateRegion data,
//so I pass back a "reference" to it
//User's can call a separate service method to get full details if needed, or
[DataMember(Required)]
public KeyValuePair ShipToStateRegion;
//etc..
}
[DataContract]
[KnownType(Currency)]
public KeyValuePair
{
[DataMember(Required)]
public string Key;
[DataMember(Required)]
public string Value;
//enum consisting of all possible reference types,
//such as "Currency", "StateRegion", "Country", etc.
[DataMember(Required)]
public ReferenceType ReferenceType;
}
[DataContract]
public Currency : KeyValuePair
{
[DataMember(Required)]
public decimal ExchangeRate;
[DataMember(Required)]
public DateTime ExchangeRateAsOfDate;
}
[DataContract]
public CustomerDTO
{
[DataMember(Required)]
public string CustomerID;
[DataMember(Required)]
public string Name;
//etc....
}
Thoughts? Opinions? Comments?
We've faced this problem in object-relational mapping as well. There are situations where we want the full object and others where we want a reference to it.
The difficulty is that by baking the serialization into the classes themselves, the datacontract pattern enforces the idea that there's only one right way to serialize an object. But there are lots of scenarios where you might want to partially serialize a class and/or its child objects.
This usually means that you have to have multiple DTOs for each class. For example, a FullCustomerDTO and a CustomerReferenceDTO. Then you have to create ways to map the different DTOs back to the Customer domain object.
As you can imagine, it's a ton of work, most of it very tedious.
One other possibility is to treat the objects as property bags. Specify the properties you want when querying, and get back exactly the properties you need.
Changing the properties to show in the "short" version then won't require multiple round trips, you can get all of the properties for a set at one time (avoiding chatty interfaces), and you don't have to modify your data or operation contracts if you decide you need different properties for the "short" version.
I typically build in lazy loading to my complex web services (ie web services that send/receive entities). If a Person has a Father property (also a Person), I send just an identifier for the Father instead of the nested object, then I just make sure my web service has an operation that can accept an identifier and respond with the corresponding Person entity. The client can then call the web service back if it wants to use the Father property.
I've also expanded on this so that batching can occur. If an operation sends back 5 Persons, then if the Father property is accessed on any one of those Persons, then a request is made for all 5 Fathers with their identifiers. This helps reduce the chattiness of the web service.