0

So I'm making a mock Starbucks app and I want that everytime a customer clicks the "Order" button, the product is added to an ArrayList and for this ArrayList to be accessed by all. I'm kind of confused where to insert the global ArrayList code...

This is code for my btnOrder:

private void btnOrderActionPerformed(java.awt.event.ActionEvent evt) {                                         
    String name = lblName.getText();
    String size = cmbSize.getSelectedItem().toString();
    int quantity = (int) spnrQuantity.getValue();
    int price=0;

    if (size.equals("Tall 12oz")) {
        price = 170;
    } else if (size.equals("Grande 16oz")) {
        price = 180;
    } else if (size.equals("Venti 20oz")) {
        price = 190;
    }

    Global.list.add(new Object());
    new Receipt(name, size, quantity, price).setVisible(true);
}

This is code for my Receipt frame which contains the JTable so I can display orders:

public class Receipt extends javax.swing.JFrame {

/**
 * Creates new form Receipt
 */
public Receipt() {
    initComponents();
}

String size, name;
int quantity, price;

public Receipt(String name, String size, int quantity, int price) {
    initComponents();

    this.name = name;
    this.size = size;
    this.quantity = quantity;
    this.price = price;

    addToTable();
}

void addToTable() {
    DefaultTableModel table = (DefaultTableModel) tblCart.getModel();

    Vector v = new Vector();

    v.add(name);
    v.add(size);
    v.add(price);
    v.add(quantity);

    table.addRow(v);
}

And this is the code for the accessible ArrayList:

public class Global {
    public static ArrayList<Object> list = new ArrayList<>();

    private Global(){

    }
}
Channa Jayamuni
  • 1,876
  • 1
  • 18
  • 29
  • 2
    Global states can be a nightmare to manage. You could use a singleton to act as a manager or you could pass a instance of the model to everyone. One thing I'd consider is not exposing the `ArrayList` directly, but instead, provide management functionality around, this allows you to better control the access to the list. A model approach would further allow you to control what different parts of your program can do (why should the custom be allowed to remove elements from the list? Why should brista be able to add them?) through the use on interfaces – MadProgrammer Mar 16 '17 at 03:34
  • [Program to interface not implementation](http://stackoverflow.com/questions/2697783/what-does-program-to-interfaces-not-implementations-mean); [Model-View-Controller](https://blog.codinghorror.com/understanding-model-view-controller/); [Single responsibility principle](https://en.wikipedia.org/wiki/Single_responsibility_principle) – MadProgrammer Mar 16 '17 at 03:51

2 Answers2

1

Managing global state can be a nightmare, while you can use a singleton to solve the issue, it violates the Single responsibility principle. It also removes access control, allowing anyone to modify the list in whatever way they see fit without control.

Another solution is to use some kind of model, which can passed between the various components, if you make clever use of interfaces, you can control who can do what and when.

This is a core concept of Model-View-Controller and program to interface not implementation principle.

The basic idea is you would create a "model" which maintains the data you want to share, in this, primarily the items in the customer's order (and maybe the customer's name)

You would create an appropriate order and pass a reference of it to the "order" view, where it would be able to add/remove/update items to the model. When complete, the "controller" would then pass the same instance of the model to the "check-out" view, which would use this information to generate a bill (and possibly a payment information) and finally store the transaction

You would then be able to take the information from the model at the end and tell what has happened.

Because there are complex states you might need to control, you might need more than one model, for example, you could pass the "order" model to the "check-out" view, but it could create a "transaction" model, which wraps the "order" model

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

You can take use Singleton design pattern here. With Singletons, you can take advantage of Polymorphism which won't be possible with static objects.

enum Global {
    INSTANCE;

    private ArrayList<Object> list = new ArrayList<>();

    public void add(Object obj) {
        //custom validations (if any)
        list.add(obj);
    }

    public Object get(int index) {
        //check here for permissions, validations etc...
        return list.get(index);
    }

    //other methods to access your shared objects
    ...
}

In this example, singleton pattern is implemented using ENUMs which ensures thread safety. You can also implement singleton using The ‘Inner Class’ Approach which is also thread safe.

Usage

private void btnOrderActionPerformed(java.awt.event.ActionEvent evt) {                                         

    ...

    Global.INSTANCE.add(new Object());
    new Receipt(name, size, quantity, price).setVisible(true);
}

Difference between static class and singleton pattern?

Community
  • 1
  • 1
Raman Sahasi
  • 30,180
  • 9
  • 58
  • 71
  • :) much nicer ... This is nitpick, but the issue for me is that this allows ANYBODY to add/remove/modify the contents of the list, which shouldn't make sense in the case of the customer (unless I'm inpatient and don't want to wait, then I can remove all the elements in the list before me :D), that would be my only issue with using a singleton in this case. You might also want do some research into [singletons are evil](https://www.google.com.au/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=singletons+are+evil&*) - personally, I like them, but that's me – MadProgrammer Mar 16 '17 at 04:12