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 + Comments)
Container hierarchy (abstract base, Box, Cylinder)
ContainerFactory (Factory Method)
Pallet and PalletManager
Memento for backup/restore
Models for Qt (Unallocated list, Pallet model)
5. GUI Skeleton (QMainWindow, Tabs, Widgets, Actions)
6. XML Serialization (QXmlStreamWriter) and Parsing (DOM/QXmlStreamReader)
7. Threaded Serialization Worker and TCP Client (Send XML)
8. TCP Server (Separate Project) — Listen, Parse, Validate, Update Model/View
9. Notes on Memory Management, Validation, and Testing
10. Minimal CMakeLists.txt Examples
11. Critical Justification and Theoretical Alignment
12. Example Scenarios and Expected Behaviours
13. Limitations and Enhancements
14. Final Checklist for Submission
15. References
,1. Summary of Objectives
The system must:
• Model containers (Box, Cylinder) with codes, weights, and computed integer
volumes.
• Prevent instantiation of the abstract base Container.
• Display unallocated containers using Qt’s model/view architecture.
• Allow containers to be moved onto pallets, each identified by an arbitrary
number.
• Provide in-memory backup and restore of unallocated containers using
snapshots (not raw pointers).
• Serialize pallets to XML, transmit them to a TCP server (127.0.0.1:6164) in a
worker thread, and display the XML in the GUI.
• Implement a separate TCP server that receives XML, validates container codes
via regex, substitutes **** for invalid codes, and displays parsed container data in
a Qt model/view.
2. Design Overview
Core Classes and Responsibilities
• Container (abstract): Holds code, weight, and declares volume() and toXml().
• Box, Cylinder: Compute volumes and implement serialization.
• ContainerFactory: Generates valid codes and instantiates concrete containers.
• Pallet: Aggregates containers; computes totals.
• PalletManager: Maps pallet numbers to Pallet objects; serializes all pallets.
• Memento / BackupManager: Captures snapshots of unallocated containers for
restoration.
, • ContainerListModel (QAbstractListModel): Represents unallocated container
codes.
• PalletModel (QStandardItemModel): Displays pallets and contents.
• MainWindow: Provides GUI, menus, toolbar, and tabbed interface.
• XmlSerializerWorker: Runs in a QThread, produces XML, sends via TCP.
• TcpSender: Client utility to deliver XML to 127.0.0.1:6164.
• TcpServerApp: Separate Qt app that receives XML, validates codes, and
updates model.
Design Patterns Applied
• Factory Method: For container creation and code generation.
• Memento: For backup and restore of unallocated containers.
• Model/View: Qt’s architecture for separating data and presentation.
• Observer (Qt signals/slots): To keep GUI responsive and reactive.
• RAII and smart pointers: For safe memory management.
• Worker thread: For non-blocking serialization and TCP transmission.
,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>;