Design object for availability product stock of partner store - oop

Allowing a store whether a product is available in the stock of another store partner, the latter may either accept or reject the request, in all cases the applicant is informed of réponse.
I want to implement a diagram class.
Now I have a class product, and a class list of collections of products.
I don't know how to represent a class of operation "request for product availability.
Is there a design pattern corresponding to this situation?
or a simple example of class diagram would be welcome.

I'm assuming that you are talking about representing your design in some suitable diagram, in which case you need to study some "Modeling Language" - probably the most widely used today being UML. This is a big topic, but you could start here.
Now diagrams such as these are really only useful when your design reaches some level of complexity. Here you are thinking about just a couple of classes and one method a diagram won't help much. So maybe you are doing this as a learning exercise?
You probably need both a Class diagram and a Sequence Diagram.
The major thing you seem to be confused about is how to represent Operations, they are just listed against the class. So your Store class would have an operation transferInventory().
So your class diagram is very simple only a couple of classes Store, Product. But the interesting thing is that your Sequence diagram will show that you have more than one instance of the Store class: StoreA, StoreB and the instances communicate with each other.
One thing you haven't talked about: how did StoreA know that StoreB exists? Why did it choose that Store to ask for a product. There's some additional classes here such as a registry of Stores. I would be much more interested in figuring out that than in drawing diagrams.

Related

The components of a Class Diagram and how it differs to ERD

I want to understand a class diagram more fully and I am finding lots of conflicting information.
My first question is, what is the difference between class diagram and ERD? Not necessarily in look, but in classification. e.g. I have read that a class diagram is a type of ERD and I have read that a class diagram and an ERD are two different things.
My second question is around how the class diagram should look, I was given a basic tutorial on how to create a class diagram and I was taught that each class should be connected with a single line, with an arrow that looks like a 'Play' symbol (example 1 in the attached image)
But since doing some research into it, I am finding lots of examples where different connectors are used to denote association, aggregation, composition, inheritance etc. (example 2 in the attached image)
As mine is more simplistic, just showing the relationship and the multiplicities, does that mean that I have just learned a more basic version of class diagram and the extra connectors are an advanced step?
Or are they both something different?
Thanks for your help
Holly
First of all, welcome to Stack Overflow!
A class diagram is a type of static structure diagram that describes the structure of a system by showing the system's classes, their attributes, operations (or methods), and the relationships among objects. Wiki link
An entity relationship diagram (ERD) shows the relationships of entity sets stored in a database. Link
Therefore the answer to your question of "what is the difference between class diagram and ERD"?
The class diagram has nothing to do with fact how the classes are persisted in the data layer. It shows only the logical relationship between classes and the properties of the classes. While the ERD diagram illustrates the logical structure of database; what the database tables, table-column, primary keys, foreign keys, etc. are, and last but not least the relationships between database tables.
As for the question "Is this just a more advanced version of class diagram? Or a more updated version?":
There are cases when the ERD diagram can look similar to the corresponding class diagram, but the persistence data model can be way different from the class (domain) model. Furthermore a class diagram has no any information about how a class is persisted in the database - as I've already mentioned -, therefore an ERD has other kind of information than a class diagram.
As for the notations you linked:
A proper class diagram contains notations like in the second link. An example is the following diagram:
For more info what those arrows mean, click here for the corresponding SO answer.
What you are taught about how to make a class diagram (like at the first link you shown), can also be useful but it is a customized class diagram rather than an proper class diagram following the UML standards and notations because:
I find it strange that the arrow is not on the line itself
There is a shared ownership relationship (aggregation) between Customer and Vehicle. It means that a Customer can have (own) a Vehicle but the Vehicle can still exist as its own, without a Customer. This relationship can be represented with the aggregation notation. (See arrow 5a, or the class diagram below)
I find it also strange that a vehicle can have multiple Customers, as you notated with "0..*". But of course it is possible, since I do not know what kind of domain you try to model with the diagram...I made an UML diagram with proper signs, check this out:
Summing up, it is wise to follow the UML standards and conventions, since it is widely accepted and known so the information can be exchanged as efficient as possible, without misunderstanding.

How to model a non member aggregate in UML class diagram

In the below UML diagram, Account has an aggregation of Orders. Based on most online resources, this would typically mean Account class has something similar to a List as an instance.
But in reality, for a real world web app with persistent storage, that is not usually how the Account Class would be. It won't have a list of orders as instance. Instead some other controller class will just query a datastore asking for all Orders belonging to an Account. So in a UML class diagram for such an app, is this still the right way to represent relations? The cardinality and maybe the concept of aggregation looks right from a database entity perspective. Just that the diamond makes no sense from a Class perspective.
Or should it show a DataStore/DataManager with a getOrdersForAccount() method and connect it to Account class and Orders class through a dependency relation (dotted line with arrow) ?
This depends on what you want to represent.
The class model you have already would be sufficient as a logical domain model, expressing the logical relationships between entities in your domain. This might not be how you implement your software in code precisely, but it will guide you (and others) in understanding the entities and their relationships without getting bogged down in that implementation detail. At this level, your diagram may have a few design choices (strong aggregation for example is arguably a design choice, but it may not be, as is the use of enumerations and keys) but not that many and nothing that really detracts from the underlying logic. If anything, you could loose some design choices here and improve the expression of logic.
What you may also want is to provide a representation of how the OO code is implemented physically as well. This would be an additional class diagram that shows more precisely the implementation detail. You will have far more design choices in this diagram -- whether to use a collection or not for orders (e.g. a list or some other collection type class), what your data access patterns are (Adapters, Managers, ORMs etc.). At this level you will most likely loose the strong aggregate notation, as at this level we are talking about classes referencing each other which is most simply denoted using basic associations. You might want to use arrows and/or dot-notation to indicate end ownership and reference directions so that it's more clear what the relationships between classes are.
So, I think your question is a classic question about levels of abstraction in models and analysis vs design. Thanks for asking it!
The aggregation just means: "if you delete the account you need to delete the orders as well".
I also recommend to just leave the aggregation away (for most cases) since it only adds little extra semantics to your model. In this case it seems obvious to delete the order when the account is deleted. The only thing the aggregation added here is (as in most cases) some confusion or some futile discussions about the worth of that diamond.
If you have a domain where the filled diamond is used it should be documented in the modeling rules. When using the shared aggregation the documentation is even mandatory since there is no semantics per se in the specs (see box on p. 110 of UML 2.5).
It depends on how deep you want to go with UML design.
If you target code generation from UML then you probably need to add the class you mentioned.
It would look a lot like Registry Pattern:
UML Diagram
You can add abstraction so you can change implementation of your DataManager (if your DataManager is third-party then just call the API from DataManagerImplementation).
After that, depending on your implementation, once you have the list, if you need to keep it then add the association Account -> Order, if you can live with the list on the stack then you are good to go.
C++ instanciation example:
DataManagerImplementation *db = new DataManagerImplementation();
// Dependency injection
Account *acc = new Account(db);
Then in 'Account' class:
Account::Account(DataManager *db)
{
// Fetch list at creation
// Here 'orders' could be a member
m_db = db;
vector<Order*> *orders = m_db->GetOrders(this);
}
PS: I also recommend to put arrow (direction) on association/aggregation, otherwise it implies that the association is bi-directional and so that account has a pointer to an order list, and every order also has a pointer to an account, and I am not sure this is needed.
To edit PlantUML: http://www.plantuml.com/plantuml/png/SoWkIImgAStDuN99B4dqJSnBJ4yjyimjo4dDJSqhIIp9pCzJqDMjiLFmBqf9BK9ImuKk05Hcfw2afGHHYIbjfL2McboINsG3bj6oKz1oJoq1iuir79EJyqlpIZIve0m5a566IfYMEgJcfG0T2m00

OO Analysis--Operation placement

I'm confused as where I should place the operation/function when identifying classes. The following example--taken from the lecture slides of object-oriented design using UML, patterns and Java--particularly confuses me.
In this example 3 classes are identified from the following part of use case description "The customer enters the store to buy a toy".
2 functions are also identified, one is enters() (placed in the Store class) and the other is buy() (placed in the Toy class).
Why those functions are not associated with the Customer who perform them? Is there any heuristic to help with operation placement?
Your example is extremely simple, and it's hard to say something about it without a context. Anyway, I'll try to answer your question. So, first of all: oo modeling is not about building your classes in a "natural" way. The reason is very simple: even if we wanted to model the "real world" objects, it's simply impossible. The relations between real-world (Customer, Store, Toy) objects are almost infinitely complex. Let's think about your case for a while. When a customer enters a store, there is a lot of things happening, let's try to order them:
Customer enters a store
Customer needs to interact with the "Store gateway" somehow, for example with a door. Even this interaction can be complex: store can be closed, full, an accident can happen, door can be blocked, etc
When customer finally is inside the store, maybe there's a special store policy to greet customers (or every n-th customer). We can also imagine a lot of other things.
Finally, the customer wants to buy a toy. First, she needs to find that toy, which might not be so easy (how would you model this interaction?).
When the desired toy is found, she needs to take it and add to the shopping basket.
Then, customer goes to the queue and waits for her turn.
When waiting is over, the customer interacts with the cashier (a lot of small things, like take the toy, check it's price, maybe some quick chat...)
Finally, the customer can pay for the toy (check if she have enough money, select the paying method (cash, card, nfc?), leave the queue...).
The customer leaves the store (similar to the "enters a store" interaction, plus maybe security checking).
I'm absolutely sure I forgot about something. As you can see, the simple scenario is in fact very complex in real world. That's why it's impossible to model it exactly the same way. Even if we tried, the naive 1-to-1 mapping would probably lead to the design, where almost every action is a method of the Customer class: customer.enter(), customer.leave(), customer.buy(), customer.findToy(), customer.interactWithCashier(), customer.openDoor()... and lot more. This naive mapping would be entirely bad, because every step in the "Customer enters a store" scenario is in fact a collaboration of multiple objects, each somehow connected with another. From the other hand, if we tried to implement this scenario with all interactions, we would create a system that would take years to build and would be simply impossible to deal with (every change would require insane amounts of hours).
Ok, so how to follow ood principles? Take just a part of the interaction. Do not try to model it exactly the same way as it works in the real world. Try to adjust the model to the needs of your client. Don't overload your classes with responsibility. Every class should be easy to understand, and relatively small. You can follow some of the basic principles of software modeling, such as SOLID, YAGNI. Learn about design patterns in practice (find some GOF patterns and try to implement them in your projects). Use code metrics to analyze your code (Lack of Cohesion of methods, Efferent coupling, Afferent coupling, Cyclomatic complexity) to keep your code simple.
Let's get back to your specific example. According to the rules I mentioned before, the very important part of object modeling is to place methods where they belong. So, the data and the methods should be "coherent" (see Lack of Cohesion of Methods metric). So, your classes should generally do one thing. In your example, the responsibility of the Store class could be, for example, to allow customers to buy toys. So, we could model it this way:
public class Store {
public void buyToy(Toy toy, Customer customer)
throws ToyNotAvailableException, InsufficientFundsException {
// some validation - check* methods are private
if(!checkToyIsAvailable(toy)) {
throw new ToyNotAvailableException();
}
if(!checkCustomerHasFunds(customer, toy.price())){
throw new InsufficientFundsException();
}
// if validation succeeds, we can remove the toy from store
// and charge the customer
// removeFromStore is a private method
removeFromStore(toy);
customer.charge(toy.price());
}
}
Keep in mind that this is just a simple example, created to be easy to understand and read. We should refine it many times to make it production-ready (for example handle payment method, number of items etc).

How to model classes that do calculations and store them?

I have to develop a class, part of a financial application, which receives two properties and returns two results. Before you think that it is not a class, but method(s), I have to say that I have to persist both: the two user-provided parameters and the two outputs. Let's illustrate like follows in this mock:
----------------
|PetWash |
|----------------|
|petWeight |<- user provided
|petHeight |<- user provided
|ammountSoapUsed |<- system calculated
|price |<- system calculated
----------------
Should I do calculations in model classes? eg., the same model class that represents this entity should enclose the methods that do these calculations? Or should I create a kind of "calculation Engine" that would return data and store it in calculated fields?
If the first case, should I invoke calculations in the getter methods or just create a "calculate" method which would update the value for ammountSoapUsed and price? In this sense, should I just store petWeight and petHeight and calculate ammountSoapUsed and price everytime that they are needed (remember that in the real-life case calculation is much more complex)?
In truth, I'm not interested in what I could do, but in what OOP best practices recommend to do. Can you help me?
The ideal object oriented approach starts with an analysis of the problem domain. PetWash does not sound like a problem-domain concept, it sounds like the record of a pet washing event that occurred, or an estimate for a pet washing that you will offer to a customer. Which is it? Be clear.
Model the problem domain to better understand the information and operation requirements. Classes must resonate with the real world of the problem domain. CalculationEngine certainly doesn't fit this criterion. Classes can certainly do calculations, but they should provide business value recognizable to a non-technical business person. Assuming the purpose is to provide an estimate for a potential customer, what makes sense to me is an instance of a Customer class that links to multiple instances of an Animal class, where each has a height and weight. Linked to an instance of a Customer class might be instances of an Estimate class that links to instances of the Animal to be washed. And so on.
Your question is too low-level. You should neither invoke calculations in getters nor provide a calculate() operation. Focus on operations that would make sense to a non-technical business person. Again, assuming you are providing an estimate, provide operations on an instance of a Customer that add or update his or her Animals. Provide an operation that provides an Estimate when given one or more of the customer's Animals. That Estimate encapsulates the rules and calculations. If a Customer agrees to an Estimate, you can use that to manage your soap inventory or whatever. Keep the implementation hidden behind this problem-domain facade so you can swap out a bad implementation when (not if) you need to.
Most of the OO code I've seen these days dismisses the problem domain altogether and seems to build applications out of chewing gum and duct tape while trying to be agile. A good model of the problem domain is relatively durable. In stark contrast, a focus on the solution domain (a duct-taped design de jour) is not durable and is the cause of much cost overrun, expensive re-work, and canceled projects. Don't make your project one of those!

Aren't Information Expert & Tell Don't Ask at odds with Single Responsibility Principle?

Information-Expert, Tell-Don't-Ask, and SRP are often mentioned together as best practices. But I think they are at odds. Here is what I'm talking about.
Code that favors SRP but violates Tell-Don't-Ask & Info-Expert:
Customer bob = ...;
// TransferObjectFactory has to use Customer's accessors to do its work,
// violates Tell Don't Ask
CustomerDTO dto = TransferObjectFactory.createFrom(bob);
Code that favors Tell-Don't-Ask & Info-Expert but violates SRP:
Customer bob = ...;
// Now Customer is doing more than just representing the domain concept of Customer,
// violates SRP
CustomerDTO dto = bob.toDTO();
Please fill me in on how these practices can co-exist peacefully.
Definitions of the terms,
Information Expert: objects that have the data needed for an operation should host the operation.
Tell Don't Ask: don't ask objects for data in order to do work; tell the objects to do the work.
Single Responsibility Principle: each object should have a narrowly defined responsibility.
I don't think that they are so much at odds as they are emphasizing different things that will cause you pain. One is about structuring code to make it clear where particular responsibilities are and reducing coupling, the other is about reducing the reasons to modify a class.
We all have to make decisions each and every day about how to structure code and what dependencies we are willing to introduce into designs.
We have built up a lot of useful guidelines, maxims and patterns that can help us to make the decisions.
Each of these is useful to detect different kinds of problems that could be present in our designs. For any specific problem that you may be looking at there will be a sweet spot somewhere.
The different guidelines do contradict each other. Just applying every piece of guidance you have heard or read will not make your design better.
For the specific problem you are looking at today you need to decide what the most important factors that are likely to cause you pain are.
You can talk about "Tell Don't Ask" when you ask for object's state in order to tell object to do something.
In your first example TransferObjectFactory.createFrom just a converter. It doesn't tell Customer object to do something after inspecting it's state.
I think first example is correct.
Those classes are not at odds. The DTO is simply serving as a conduit of data from storage that is intended to be used as a dumb container. It certainly doesn't violate the SRP.
On the other hand the .toDTO method is questionable -- why should Customer have this responsibility? For "purity's" sake I would have another class who's job it was to create DTOs from business objects like Customer.
Don't forget these principles are principles, and when you can et away with simpler solutions until changing requirements force the issue, then do so. Needless complexity is definitely something to avoid.
I highly recommend, BTW, Robert C. Martin's Agile Patterns, Practices and principles for much more in depth treatments of this subject.
DTOs with a sister class (like you have) violate all three principles you stated, and encapsulation, which is why you're having problems here.
What are you using this CustomerDTO for, and why can't you simply use Customer, and have the DTOs data inside the customer? If you're not careful, the CustomerDTO will need a Customer, and a Customer will need a CustomerDTO.
TellDontAsk says that if you are basing a decision on the state of one object (e.g. a customer), then that decision should be performed inside the customer class itself.
An example is if you want to remind the Customer to pay any outstanding bills, so you call
List<Bill> bills = Customer.GetOutstandingBills();
PaymentReminder.RemindCustomer(customer, bills);
this is a violation. Instead you want to do
Customer.RemindAboutOutstandingBills()
(and of course you will need to pass in the PaymentReminder as a dependency upon construction of the customer).
Information Expert says the same thing pretty much.
Single Responsibility Principle can be easily misunderstood - it says that the customer class should have one responsibility, but also that the responsibility of grouping data, methods, and other classes aligned with the 'Customer' concept should be encapsulated by only one class. What constitutes a single responsibility is extremely hard to define exactly and I would recommend more reading on the matter.
Craig Larman discussed this when he introduced GRASP in Applying UML and Patterns to Object-Oriented Analysis and Design and Iterative Development (2004):
In some situations, a solution suggested by Expert is undesirable, usually because of problems in coupling and cohesion (these principles are discussed later in this chapter).
For example, who should be responsible for saving a Sale in a database? Certainly, much of the information to be saved is in the Sale object, and thus Expert could argue that the responsibility lies in the Sale class. And, by logical extension of this decision, each class would have its own services to save itself in a database. But acting on that reasoning leads to problems in cohesion, coupling, and duplication. For example, the Sale class must now contain logic related to database handling, such as that related to SQL and JDBC (Java Database Connectivity). The class no longer focuses on just the pure application logic of “being a sale.” Now other kinds of responsibilities lower its cohesion. The class must be coupled to the technical database services of another subsystem, such as JDBC services, rather than just being coupled to other objects in the domain layer of software objects, so its coupling increases. And it is likely that similar database logic would be duplicated in many persistent classes.
All these problems indicate violation of a basic architectural principle: design for a separation of major system concerns. Keep application logic in one place (such as the domain software objects), keep database logic in another place (such as a separate persistence services subsystem), and so forth, rather than intermingling different system concerns in the same component.[11]
Supporting a separation of major concerns improves coupling and cohesion in a design. Thus, even though by Expert we could find some justification for putting the responsibility for database services in the Sale class, for other reasons (usually cohesion and coupling), we'd end up with a poor design.
Thus the SRP generally trumps Information Expert.
However, the Dependency Inversion Principle can combine well with Expert. The argument here would be that Customer should not have a dependency of CustomerDTO (general to detail), but the other way around. This would mean that CustomerDTO is the Expert and should know how to build itself given a Customer:
CustomerDTO dto = new CustomerDTO(bob);
If you're allergic to new, you could go static:
CustomerDTO dto = CustomerDTO.buildFor(bob);
Or, if you hate both, we come back around to an AbstractFactory:
public abstract class DTOFactory<D, E> {
public abstract D createDTO(E entity);
}
public class CustomerDTOFactory extends DTOFactory<CustomerDTO, Customer> {
#Override
public CustomerDTO createDTO(Customer entity) {
return new CustomerDTO(entity);
}
}
I don't 100% agree w/ your two examples as being representative, but from a general perspective you seem to be reasoning from the assumption of two objects and only two objects.
If you separate the problem out further and create one (or more) specialized objects to take on the individual responsibilities you have, and then have the controlling object pass instances of the other objects it is using to the specialized objects you have carved off, you should be able to observe a happy compromise between SRP (each responsibility has handled by a specialized object), and Tell Don't Ask (the controlling object is telling the specialized objects it is composing together to do whatever it is that they do, to each other).
It's a composition solution that relies on a controller of some sort to coordinate and delegate between other objects without getting mired in their internal details.