2

I would like your feedback regarding some best practices on design relationship between objects, specially when a singleton object is involved.

Let's imagine I need to simulate a Shop with Customers.

There is only one Shop in my application and a Customer belong only to that Shop.

When the Shop closes I need to notify each Customer.

Below some pseudo code.

In both approaches I consider a Shop as a single object.

In approach 01, I call addCustomer on shop.

In approach 02, I call addCustomer when actually creating a Customer object keeping a reference on Shop in every Customer.

I believe a third approach could be also possible, basically where shop and Customer communicate with events. So for example when creating a Customer, an event is broadcasted, shop listen to that event and add a Customer to itself.

What are your opinions, pro/cons regarding these approaches? I am using JavaScript as language. Thanks in advance for your support.

 // 01 approch
 var shop = {
 customers: [],
 addCustomer: function (customer) {
 this.customers.push(customer);
 },
 close: function () {
 this.customers.forEach(function (customer) {
 customer.goOut();
 });
 }
 };
 function Customer(name) {
 this.name = name;
 this.goOut = function () {
 console.log(this.name + ' goes out')
 }
 }
 // set up
 shop.addCustomer(new Customer('a'));
 shop.addCustomer(new Customer('b'));
 shop.addCustomer(new Customer('c'));
 shop.close();
 console.log('-------------------------');

 // 02 approch
 var shop2 = {
 customers: [],
 addCustomer: function (customer) {
 this.customers.push(customer);
 },
 close: function () {
 this.customers.forEach(function (customer) {
 customer.goOut();
 });
 this.customers = [];
 }
 };
 function Customer2(name) {
 this.shop = shop2;
 this.name = name;
 this.goOut = function () {
 console.log(this.name + ' goes out')
 }
 this.shop.addCustomer(this); // make sense?
 }
 new Customer2('d');
 new Customer2('e');
 new Customer2('f');
 shop2.close();
GlenPeterson
15k7 gold badges50 silver badges75 bronze badges
asked Oct 15, 2015 at 9:46
4
  • what does "single tone" mean? singleton? Commented Oct 15, 2015 at 11:19
  • 2
    You first option is the best. Why? Because as in real-life, it's the shop that contains the one and only copy of customers. It's also the shop that notifies each customer. Following the one-time-one-place principal is always best. The shop then, is responsible for knowing what customers are in store and notifying them of an action. Commented Oct 15, 2015 at 13:13
  • @JohnPeters thanks for your comments, what do you think about the third approach? Commented Oct 15, 2015 at 13:29
  • 1
    Events are the implementation of the Observer pattern and are always extremely powerful. The reason is that the Listener can operate as normal only acting when an inbound event is sent. This is especially powerful when you are talking about multiple threads each communicating with each other. Finally a newer framework exists equally or even more powerful than events known as ReactiveExtensions (RX). RX is a super-Observer implementation and takes push notifications to a new level. Commented Oct 15, 2015 at 13:46

2 Answers 2

2

It is difficult to recommend anything in particular because we are discussing only small amount of code. But there are some comments

In approach 01, I call addCustomer on shop.

In this case shop knows about customers. Customers doesn't know about shop. So, there is a one link.

In approach 02, I call addCustomer when actually creating a Customer object keeping a reference on Shop in every Customer.

In this case both shop knows about customers and customers know about shop. So, there are two links and the coupling between classes becomes even stronger (which is mostly bad)

I believe a third approach could be also possible, basically where shop and Customer communicate with events.

This relaxes the coupling somewhat, but does not remove it anyway.

For my understanding coupling should be removed as Shop is not referenced in ? Customer as in the second approach. Am I wrong?

Well, will it be removed or not depends on what exactly you do when event is received. Coupling is just knowledge. If after event is received, customer adds itself to the shop or stores inside itself a reference to the shop, coupling is still there.

There is also an indirect coupling. You are sending an event and this event is processed. It might be processed without involving actual object reference, but it is still there. Your system imposes knowledge about relation between these two classes.

So, you must give objects minimum knowledge about each other. But not less knowledge, that is required for them to function correctly.

answered Oct 15, 2015 at 13:18
1
  • Regarding your latest point (third approach), I understand your point on "relaxes the coupling" but what do you mean by "does not remove it anyway"?. For my understanding coupling should be removed as Shop is not referenced in Customer as in the second approach. Am I wrong? Thanks again for your time on this. Commented Oct 15, 2015 at 13:34
0

The classical pattern you could use to implement this is the observer pattern. It's the abstraction of your first solution basically. With the observer pattern it doesn't matter to your shop, which type of objects are listening to your "close-event". So that could be customers but also suppliers (well ..whatever you can think of :) ).

See those links as a starting point:

answered Oct 15, 2015 at 13:39

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.