• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Tim Cooke
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Knute Snortum
  • paul wheaton
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Ron McLeod
  • Piet Souris
  • Ganesh Patekar
Bartenders:
  • Tim Holloway
  • Carey Brown
  • salvin francis

Which Design Pattern to use?

 
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Assignment:
Factories keep records of the production and distribution of products to retail outlets. During production each product is assigned a unique serial number. Sales outlets can submit a request to the headquarter for a delivery of the required products, stating how much they need. There are more factories and multiple outlets within the company, where outlets send requests to company headquarter, and each factory can ship products to any outlet as needed.

I've read Strategy, Observer, Factory and Decorator Pattern from Head First. So far, this looks like situation where Observer should be used. But, bit where it says that company can send request to any factory, is not aligned with Observer (since in Observer patter all factories would have been notified on state change). Also, here we have one headquarter, and multiple sales places. Initially, state of (any) sale place will change (once it got customer's request) and it will need to inform headquarter, not the other way around.

Any suggestions which pattern should use if any? Or to read up any other which will help in this situation.

P.S. this a job interview assignment for a student internship. We are supposed to show good OOP skills.

 
Saloon Keeper
Posts: 10495
224
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Observer is used when a class can trigger events that classes that it doesn't know about are interested in. It's not applicable here, because presumably the outlets know about the headquarters, and the headquarters act like a mediator between the outlets and the factories.

I don't know why you're looking for any specific kind of pattern. To me it seems like the headquarters can act like a controller, which delegates requests from the outlets to the factories. When the requests return, the headquarters routes the responses back to the outlet.
 
Sheriff
Posts: 13677
226
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I agree with the sentiment of the question "Why are you looking for a specific pattern?"

This is like being asked to build a house and asking "What tool should I use to build this house? A hammer? A saw? A chisel?"

The level of abstraction of the problem you described does not match the level to which most design patterns are targeted for.

If this were an interview assignment geared at gauging your skill at OOP, leading off with "What pattern should I use? Maybe the Observer..." will already put you at a great disadvantage. At least it would if I were evaluating you.

Object-orientation is mostly about assigning responsibilities for behavior and data management. This involves identifying "entities" in the problem domain that would be assigned responsibilities to carry out tasks and to manage the data that is used to accomplish those tasks. Design patterns come in later, when you're trying to figure out how to structure those entities (objects) in a way that makes sense and is easy to maintain.

And don't conflate "factory" as described in your problem and "Factory" as described in design pattern books. Those are totally different ideas.
 
Mike Gosling
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you guys for a reply, I am first year student, just getting started with design patterns. I did few student OOP projects, therefore I assumed (apparently wrong), that this is suitable situation to use some DP. Okey s*** happens  


Junilu Lacar wrote: And don't conflate "factory" as described in your problem and "Factory" as described in design pattern books. Those are totally different ideas.


Oh, no, I didn't. I get it. Completely separate things...

One quick thing, does it sound reasonable to create company/headquarter as a Singleton object?
 
Marshal
Posts: 65370
248
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Miljan Puletic wrote:. . . does it sound reasonable to create company/headquarter as a Singleton object?

Why would you want your company to be a singleton? Unless it is simply for practice writing singletons, the answer is no. Many people think singletons are an anti‑pattern, which should be avoided.
Of course, the best way to create a singleton is with a one‑element enum.
 
Mike Gosling
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Why would you want your company to be a singleton?



Well, my idea was to not allow any additional creation of Company object.

Campbell Ritchie wrote:Unless it is simply for practice writing singletons, the answer is no



But, you're right. Mainly for practicing purpose.
 
Campbell Ritchie
Marshal
Posts: 65370
248
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Remember, you are allowed to do just about anything if it is for practice only. But work out the scenario where you are only allowed one company in the whole world. I would think that will suggest my Company object shouldn't be a singleton.

Remember also that there are variants of the singleton “pat‍tern” which have exactly two or three or four etc. instances.
 
Stephan van Hulst
Saloon Keeper
Posts: 10495
224
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The Singleton flies in the face of dependency injection, and therefore should be avoided at all cost.

It's simple: if an object needs another object to do its work, pass the dependency object as an argument to a method or constructor. There is no reason to pluck the object out if thin air (by referring to a static variable), and when there's no way to pluck an object out of thin air there's no reason to limit the number of instances you can create of it.

The Singleton pattern is so prevalent because it's easy for beginners to recognize where it can be applied, and it's relatively easy to implement.

Here's an important tip: if you make a field static without the intention of letting the field represent a constant value, smack yourself in the head first and then think of there's not a better way.
 
Junilu Lacar
Sheriff
Posts: 13677
226
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Let me see if I can make this clearer this time. Thinking about what design pattern to use before you even have a clear idea of the problem is an anti-pattern. The problem statement is not specific enough to be able to determine if a specific design pattern is appropriate.  Again, go back to the analogy of being asked to build a house and asking "Do I need a hammer? A saw? A chisel?" What's the right answer here? Likewise, it's way too early in the design process to say "Use a Singleton to represent this or that concept." That's not how design patterns work. You're flipping it all around.

Patterns work like this:

1. Someone noticed that there's a solution (the pattern) that can be applied to a certain situation (the context). Note that the context came first, then the solution, then someone noticing that the solution applied can be used in other similar situations.
2. That someone describes the context, the solution, and impact. Viola, you have a pattern definition.
3. Someone else runs into a problem with pretty much the same context. They recognize that there's a known pattern that applies to contexts similar to theirs.
4. They apply the known pattern to their context.

You are basically skipping #3 and going straight to picking out a pattern and saying "How do I apply this pattern?" without a clear idea of the context.

Needing to represent a Headquarters in your design is not enough to say "I need a Singleton for this" -- there has to be more to it than just existence of a thing. I suggest you start with your candidate objects first. Then look at the relationships they have with each other, what interactions they need to have, and what outcomes you're looking for. Organize them in a way that makes sense to you. If you start having problems with your organization, then see if there's a known pattern that addresses those kinds of problems. Then and only then, when you have a pattern whose context is similar to your context, do you apply the pattern. Don't go around with a hammer looking for a nail to pound because when you only have a hammer in hand, everything will look like a nail.
 
Junilu Lacar
Sheriff
Posts: 13677
226
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The premise of the book Refactoring to Patterns by Joshua Kerievsky is that you often don't design a system with specific patterns already in mind. Rather, you come up with a design, recognize problems with the design, see that there is a pattern (or patterns) that addresses the same kind of problems, then refactor your design towards the known pattern(s).

As an example, let's say you have several types of Product. The type of a Product will determine how it will be priced, packaged, and shipped to the customer. A naive designer/developer might write code that involved a series of if-else-if-else statements that look at the product type to determine the pricing/packaging/shipping of a product. However, every time a new product type is added or rules for pricing, packaging, and shipping changes, there are a lot of code changes involved around that if-else-if-else statement. Maintenance of that section of code becomes more difficult over time and the code gets messier and messier each time a change is made.

The astute designer might recognize this situation as a violation of the Open-Closed Principle and try to apply the Replace conditionals with Polymorphism refactoring. Then they might see that the Strategy Pattern can also be applied. So now, the developer/designer starts refactoring the series of if-else-if-else conditionals to different Strategy implementations. When that's done, maintenance of specific rules/policies for a Product Type can be done on a single Strategy implementation instead of having to weed through a big if-else-if-else statement.

In real world situations it is more likely that the design will start out with a big if-else-if-else statement around different Product Types that is then refactored towards the Strategy Pattern rather than someone thinking of using Strategy right out of the gate.
 
Junilu Lacar
Sheriff
Posts: 13677
226
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One other point to consider: be careful about trying to model the real world in your system. Often there is no need to represent some things and necessary to make other things up. Like Headquarters, for example. Does it really matter that requests are submitted to headquarters? Or does it only matter that sales outlets can submit requests for products at all? Of what use is the Headquarters abstraction in the program design? Imagine someone using the system to submit an order for a sales outlet. Do they really care that they are submitting an order "to headquarters?" In a manual process, they might but in an automated computerized process does it matter?

Not all nouns in your problem statement need to be turned into program objects. I think Headquarters is one such thing yet you are already thinking of using Singleton for it. You might already be over-engineering your design from the start. That would be bad.

On the other hand, did you think of a ProductRequest as an object? What other name might that have? "Order" perhaps? Also, often there are abstract ideas that you need to represent as objects in your system. For example, our book promo this week is about Event Streams. You might think of the submission of a product order as an Event and each step in the processing of it as a series of Events.
 
Mike Gosling
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Junilu for giving a nice introduction on how to start thinking about given problem and designing solution. You touched many things here, which I need to work on. Regarding that Singleton, I got some details, apparently, the point of using the singleton here was for them to see if we can implement it, so mainly for practicing purposes. The video you posted was very helpful, and I will definitely get my hands dirty with Refactoring to Patterns

I have here UML Diagram if you can comment on it would be awesome. Thanks everyone for posts. Sorry Junilu for this late response..

Here is the rest of the assignment (which is not affecting original problem), this is just to not get confused with Log objects which are on UML.

Log In:
- Production of each product individually (serial number, product type, factory where the product was made, date and time, name of supervisor)
- Delivery requirements (requesting point of sale, list of types with quantities)
- Product transport (factory name, factory name - outlet, list of types with quantities, name of responsible transporter)
- Each sale (list of serial numbers,outlet , name of the employee who made the sale, payment method (cash / card), customer name (if paid by card))

P.S. I heard for Logging but couldn't dig deeper, so I just made my log objects

UML-Diagram.png
[Thumbnail for UML-Diagram.png]
 
Junilu Lacar
Sheriff
Posts: 13677
226
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There's quite a bit to say about the diagram so I will give you bits at a time, otherwise replies will be very long.

1. Naming - WriteToStringInterface and CreateFromStringInterface are not good names. They're also not idiomatic names for interfaces. Those are verb phrases and as such are better suited as method names that evoke a sense of action. Class and interface names should be noun phrases or adjectives. Writable and Indentifiable are adjectives that I would expect to be names of interfaces because they end with "-able". Another example is the Comparable interface in the standard Java Collections Framework.

2. Archetype - you use <<Java Class>> for Company but since it has a getInstance method, this is probably better: <<Singleton>>

3. Archetype - you use <<Java Class>> for Identifiable. That will probably be better as an interface as its name suggests. This is a poor candidate for a base class and can quickly lead you to a very problematic design if you use it as a base class and extend it with subclasses that wouldn't be related otherwise, thus creating a poor inheritance structure. A couple of rules of thumb to remember: Favor composition over inheritance and Design and Document for inheritance. These two are not contradictory, as a cursory glance might make you think. Follow the first one (composition over inheritance) but if you must use inheritance, then make sure you consider it carefully and design around it properly.
 
Junilu Lacar
Sheriff
Posts: 13677
226
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This constructor signature on the Shipment class is a poor design:

Shipment(int, int, int, int, int, int, ArrayList<Product>)

1. Way too many parameters - see also long parameter list code smell

2. When applicable, prefer using the interface type (List<Product>) of the implementation type (ArrayList<Product>).
 
Junilu Lacar
Sheriff
Posts: 13677
226
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why do you have find*() methods in your Log classes? Those are incongruent with the semantics of a class that is responsible for logging, unless you're using a different definition of "Log" from what most people normally associate it in a computer program.
 
Junilu Lacar
Sheriff
Posts: 13677
226
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Naming again. You appear to be using the "Interface" suffix on any interface names. Take a look at the Java Collections Framework: none of the interfaces defined in it use that prefix. Think about why that is.
 
Junilu Lacar
Sheriff
Posts: 13677
226
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I could go on and on with a number of callouts on that UML diagram but let me just stop here and say that in my experience, spending a lot of time on UML diagrams like this before you've written any code is a huge waste in both time and effort.

If I ever create UML diagrams (and I seldom do anymore) I would want to use an automated tool that analyzes my code. That is, instead of creating UML diagrams before I code, I'd rather do it after the fact, when I have a stable, tested, and proven codebase/design. UML diagrams created to document existing code provides far more value than UML diagrams created otherwise. For me, the latter are gigantic black holes of time and effort == $$$.
 
Opportunity is missed by most people because it is dressed in overalls and looks like work - Edison. Tiny ad:
create, convert, edit or print DOC and DOCX in Java
https://products.aspose.com/words/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!