Assignment 3
Due Year 2025
,COS3711: Advanced Programming
Assignment 3 2025
Table of contents
1. Summary of objectives
2. Design overview (classes, relationships, patterns)
3. Source-code structure and CMake outline
4. Class skeletons (headers + short comments)
➢ Container hierarchy (abstract base, Box, Cylinder)
➢ ContainerFactory (Factory Method)
➢ Pallet and PalletManager
➢ Memento for backup/restore
➢ Models for Qt (Unallocated container list and Pallet model)
5. GUI skeleton (QMainWindow, tabs, widgets, actions)
6. XML serialization (QXmlStreamWriter) and parsing (DOM / QXmlStreamReader)
7. Threaded serialization worker (Qt threading) and TCP client (send XML to
127.0.0.1:6164)
8. TCP server (separate project) — listen, parse XML, validate codes, update
model/view
9. Notes on memory management, patterns, validation, and testing
10. Minimal CMakeLists.txt examples
11. References
,1. Summary of objectives
Produce a complete solution that:
• Models containers (Box, Cylinder) with code, weight, and computed volume.
• Only allows concrete instantiation of Box or Cylinder.
• Displays unallocated containers using Qt model/view.
• Moves containers to pallets identified by arbitrary numbers.
• Supports in-memory backup and restore of unallocated containers (no pointer-
only backups).
• Serializes pallet list to XML, sends XML to a TCP server (127.0.0.1:6164) in a
thread, and shows XML in the UI.
• Implements a separate TCP server project that receives XML, validates container
codes via regex, shows **** for invalid codes, and displays container data via
model/view.
2. Design overview
Key classes and responsibilities (high-level)
• Container (abstract): holds code, weight, virtual volume() and virtual
toXml(QXmlStreamWriter&).
• Box and Cylinder: implement volume() and serialization details.
• ContainerFactory: create Box or Cylinder instances and generate container
codes.
• Pallet: holds container pointers, computes total weight and total volume.
, • PalletManager: map of pallet number → Pallet pointer; responsible for
serialization of all pallets.
• Memento / BackupManager: stores serializable snapshots of unallocated
containers (not raw pointers).
• ContainerListModel (subclass of QAbstractListModel): model for unallocated
container codes.
• PalletModel / PalletsTreeModel (e.g., QStandardItemModel): model for pallet
display.
• MainWindow (QMainWindow): provides GUI and orchestrates actions.
• XmlSerializerWorker (runs in a QThread): produces XML and uses TcpSender to
deliver it.
• TcpSender (client object): connects to 127.0.0.1:6164 and sends XML bytes.
• TcpServerApp (separate Qt app): listens on 6164, parses XML, validates codes
via regex, updates a QStandardItemModel.
Design patterns used
• Factory Method for creating Box/Cylinder.
• Memento for backup/restore of unallocated containers.
• Model–View for UI lists (Qt QAbstractItemModel).
• RAII / parent ownership of Qt widgets to manage memory.
• Worker thread pattern for background serialization and network IO.
Rationale: The Factory centralizes code format and serial numbering. The Memento
avoids pointer resurrection while allowing in-memory rollback. Qt model/view separates
data and presentation, enabling responsive UI updates.
,3. Source-code layout
COS3711_A3/
├─ app/ # main application (GUI)
│ ├─ include/
│ │ ├─ container.h
│ │ ├─ box.h
│ │ ├─ cylinder.h
│ │ ├─ containerfactory.h
│ │ ├─ pallet.h
│ │ ├─ palletmanager.h
│ │ ├─ memento.h
│ │ ├─ containerlistmodel.h
│ │ ├─ xmlserializerworker.h
│ │ └─ tcpsender.h
│ ├─ src/
│ │ └─ *.cpp
│ ├─ resources/ (icons)
│ └─ CMakeLists.txt
├─ server/ # TCP server project
│ ├─ src/
│ └─ CMakeLists.txt
└─ CMakeLists.txt
, 4. Class skeletons and brief explanation
4.1 container.h (abstract base)
// include/container.h
#pragma once
#include <QString>
#include <QXmlStreamWriter>
#include <memory>
class Container {
public:
explicit Container(QString code, double weight)
: m_code(std::move(code)), m_weight(weight) {}
virtual ~Container() = default;
QString code() const { return m_code; }
double weight() const { return m_weight; }
void setWeight(double w) { m_weight = w; }
// volume must be integer per spec; return as integer
virtual int volume() const = 0;
virtual void toXml(QXmlStreamWriter& writer) const = 0;
protected:
QString m_code;
double m_weight;
};
using ContainerPtr = std::unique_ptr<Container>;