首页 > > 详细

COMP 3023留学生辅导、讲解C/C++程序、辅导UML、讲解C/C++设计 辅导R语言程序|讲解留学生Processing

Revision 1, 2018-10-06
COMP 3023 Software Development with C++ - Assignment SP5 2018 Page 1 of 29
School of Information Technology and Mathematical Sciences
COMP 3023 Software Development with C++
Group Project
Networked Asset Manager
Introduction
This document specifies the requirements for the group project of the Software Development with C++ course,
SP5 2018. This assignment will develop your skills by developing an application in a team environment while
allowing you to put into practice what has been taught in class during this course.
The assignment will require you to design, implement, test, and debug a GUI-based networked database1
application using object-oriented methods and the application of Design Patterns. The application will store
information about Assets, their types and properties, and their maintenance as well as support the sharing of this
information with other running instances of the application over the network. To realise this, several Design
patterns will need to be incorporated into the design and implementation of the application. The project will
require you to use collaboration tools and version control to manage the project and collaborate with your team
members as you progress through the assignment as well as document your classes appropriately through UML
class diagrams and Doxygen comments. To support concurrent development by each team member, Unit Testing
will be very important to ensure that things are working before a GUI is able to test each component of the
application. The work in this assignment is to be performed as a group and will be submitted via LearnOnline at
the end of week 13: due by 2 November 2018 11:59 PM. Refer to section Submission Details for specific
instructions.
If any parts of this specification appear unclear, please ensure you seek clarification.
Learning Outcomes
After completing this assignment, you will have learnt to:
Collaboratively design a class hierarchy using UML
Apply Object-Oriented principles (encapsulation, reuse, etc.) and Design Patterns to the software design
Implement the software design in C++ within a team environment
Develop a cross-platform application using a cross-platform framework (Qt)
Use professional tools for collaboration and software development, such as: version control, project
management, issue tracking, and continuous integration
Write code adhering to coding standards, guidelines and good programming practices
Design Patterns
In developing the class design for the Networked Asset Manager, the following the Design Patterns will be
incorporated:
Singleton (extensible version)
Abstract Factory
Prototype

1 You will not actually be using a database, just manipulating objects in memory.Revision 1, 2018-10-06
COMP 3023 Software Development with C++ - Assignment SP5 2018 Page 2 of 29
? Type-Object
Unlike the previous assignment you do not have to identify where to apply the Design Patterns (there is
complexity elsewhere in this project). However, you should read the description of the patterns.
For more information on Abstract Factory and Prototype2
, refer to the book:
Gamma, E, Helm, R, Johnson, R and Vlissides, J 1995, Design patterns: elements of reusable object-oriented
software, Addison-Wesley, ISBN: 978-0-201-63361-0.
3
Be aware that the C++ examples from the book are for an older version of C++. If using them for guidance, they
must be updated to C++ 14.
For the Type-Object pattern, refer to the article (posted to the course website for convenience):
Woolf, B., Johnson, R.: The type object pattern. Pattern Lang. Progr. Des. 3, 132 (1996)
Adequate descriptions of the above patterns along with some code examples can also be found on Wikipedia and
elsewhere:
Singleton: https://en.wikipedia.org/wiki/Singleton_pattern (Note: the Wikipedia entry does not consider
extensibility of the Singleton.)
Abstract Factory: https://en.wikipedia.org/wiki/Abstract_factory_pattern
Prototype: https://en.wikipedia.org/wiki/Prototype_pattern
Type-Object: http://gameprogrammingpatterns.com/type-object.html
Task Description
In this assignment, you will design and implement a GUI-based networked database application that fulfils the
following specification. The application will store details about assets that a company owns, including records of
maintenance for auditing purposes. However, the company operates in a highly dynamic environment with new
types of assets becoming available all the time; therefore, the application will also keep track of the types of asset
and their properties, which may differ between asset types.
The aim of the assignment is to build a software application in a team environment using a cross-platform
framework (Qt), GUI and networking libraries. The style of application (a database application with a web servicestyle
API) is very common in the real-world and something you are likely to come across when you graduate. The
design and implementation of the application will require features of C++ taught in the latter half of the course,
such as templates, in addition to those features covered previously, such as inheritance and polymorphism. The
focus of this assignment is the collaborative development of the application. Due to the added difficulty and
complexity of managing a team, this specification will be more detailed when it comes to the application of the
Design Patterns and the major interfaces that are required. You will be required to develop a UML Class Diagram
that incorporates the described interfaces plus additional classes/functions your group considers necessary. This
will be a key piece of documentation that supports communication between team members. Moreover, the
separation of tasks between team members and the use of Unit Testing will be important to allow concurrent
development of different aspects of the application by different team members. The specification consists of
some larger and more complex aspects, as well as some smaller components: the idea being that group members
of different capability levels should each be able to contribute to the group effort.
First, you will need to develop a class design using UML class diagrams based on the requirements in the
remainder of this specification. A simple and free UML editor that can be used for this assignment is UMLet

2 The Type-Object pattern is not in the GoF Design Patterns book.
3
Scanned PDFs of the relevant sections are available from the course website as the library has limited copies of the book.Revision 1, 2018-10-06
COMP 3023 Software Development with C++ - Assignment SP5 2018 Page 3 of 29
(http://umlet.com/). The UML class diagram must include all classes, public data members, public member
functions, protected data members and member functions (if any), and associations between classes. The
diagram must identify the key roles/participants of the Design Patterns occurring in the design. The diagram may
optionally display private member functions, but private member variables should not be included.
Workplan and Group Collaboration
To complete this assignment, it is important that you take a planned, methodical approach in collaboration with
your group members. You and your group will need to think about how to break down the assignment into
smaller chunks of functionality that can be allocated among the team and implemented and tested
independently. Working in an incremental manner, and testing as you progress, helps to limit the scope of errors
that are introduced as you perform the implementation and will assist when integrating your work with others.
Moreover, an incremental approach allows you to focus on a single problem at a time as well as refactor and
redesign the application in a controlled manner as you (re)discover requirements or issues that were not obvious
at first.
To enable adequate collaboration with your group members, the first order of business will be to organise a
platform for collaboration. At the centre of this collaboration framework will be a version control system (Git)
through an online repository. Possible online repositories include BitBucket [https://bitbucket.org/] and GitLab
[https://about.gitlab.com/] (which many of you may already be using). Note: whichever you choose you must
ensure that your repository is private and cannot be seen by anyone outside your group. Online version control
interfaces like BitBucket, GitLab, and GitHub4 provide some basic project management features such as issue
tracking and wikis. However, for improved collaboration and project management, I suggest you integrate Trello
(or similar). Trello [https://trello.com/] is a project management and collaboration tool popular among small,
agile teams. It is quite simple and will help you keep track of tasks, assign them to group members, and indicate
to your team when they are complete.
This assignment should be completed in the following stages:
1. Read this assignment specification in full.
2. Check your group allocations and contact your group members.
3. Read this assignment specification again.
4. Organise with your team an online repository and collaboration environment—someone will need to
create the repository and invite the others to access it. This step will be essential in the in ensuring
ongoing communication with team members.
5. You and your team create an initial class design of the application—this will serve as a primary
communication tool between team members on what is expected and should be maintained throughout
the project.
6. Implement class and function stubs—this will allow group members to work somewhat independently
without issues due to missing classes, functions, etc. It will also allow tests to be created based on the
expected interfaces.
7. Identify team members’ strengths and weakness and assign tasks to individual team members.
8. Perform your task(s)
9. Use the online collaboration tools and in person meetings (if possible) to manage the project and monitor
progress. (Back to 8.)
10. Successfully complete the project.

4 GitHub is highly popular for open source projects; however, it requires a paid subscription to obtain private repositories.
While you get private repositories for free as a student, it is unclear what happens if GitHub decides you no longer fulfil the
student requirements, that is, they may make your private repositories public. Therefore, do not use GitHub for your project.Revision 1, 2018-10-06
COMP 3023 Software Development with C++ - Assignment SP5 2018 Page 4 of 29
General Functionality
The Networked Asset Manager application will need to support the creation, management, and deletion of assets
and asset related information in a networked environment. Logged on users (in the real-world security and
permissions, as well as knowing who modified the data, are serious concerns) will be able to view and modify the
details of assets, etc., through a GUI with changes synchronised between other instances of the application. In
addition, users will be able to search for assets using some of their common attributes (e.g., serial number).
Core to the application is an Asset Register that stores the assets and related details, such as their type, their
properties, maintenance records, and custodians (i.e., the person responsible for managing the asset). Each type
of information is stored in and retrieved from the Asset Register using its unique ID. Each stored entity has some
additional meta-data to help manage it: last edit time, and the last edit user. In a real-world application it the
storage class would be backed by a database; however, for simplicity we will just store the objects in memory
using the map data structure.
You will need to make use of Qt’s Signals and Slots mechanism (an implementation of the Observer Design
Pattern) to communicate between components and ensure that the state of the application is correctly
synchronised.
The user must be able to select at runtime (i.e., when they “login”) whether they want to run the application in
“online” or “offline” mode. This will be handled using the extensible singleton pattern with a networked and nonnetworked
version of the asset storage class. Below are some details of achieving this.
AbstractAssetRegister ?singleton? (derived from: QObject)
The AbstractAssetRegister class will provide the interface for all types of asset register (offline, networked,
possibly a future database backed implementation, etc.), including access to the singleton instance.
AbstractAssetRegister is an abstract class and must not be instantiable itself; moreover, it must be a subclass
of QObject to attain the Signals and Slots capability.
Constructors:
explicit AbstractAssetRegister(QObject*)—since the class is derived from QObject, it should have
the common QObject constructor for specifying the parent object (you could make the parent the
singleton instance of QApplication, for example). For extensibility of the Singleton pattern, the
constructor must be protected.
Instance-level interface (i.e., non-static functions) includes (but is not limited to):
username()/setUsername(…)5—accessor and mutator for managing the “logged-in” user. This will just
be a simple string (QString since we are in the Qt framework) specified by the user through the GUI.
There will not be any control over what users are allowed, permissions, etc. it will only be used to record
who created and modified an asset (or related entity) as part of the entity’s meta-data.
generateId()—since we are operating in a distributed environment it is important that we avoid clashes
between entity identifiers created by different instances of the application running on different (or the
same) computer. A relatively simple way to achieve this is to use randomly generated IDs using an
algorithm designed for such systems such as UUIDs (Universally Unique Identifiers). This function will
create and return a new UUID (as a QString) to be used as an identifier. This can be done using Qt with
the QUuid class and its createUuid() function.

5 Where an ellipsis (i.e. ‘…’) appear in the parameter section of a function signature, it means it requires 1 or more
parameters but they have not been explicitly provided as part of this specification.Revision 1, 2018-10-06
COMP 3023 Software Development with C++ - Assignment SP5 2018 Page 5 of 29
storeEntity(…)—stores an entity (Asset, AssetType, Custodian, or MaintenanceRecord) in the
AssetRegister: must return true if the entity was added, false if the it was not (e.g., due to the ID not
being unique). May be a single function using inheritance and polymorphism to a common base class, or
multiple overloaded functions. Document your design decision.
retrieveEntity(id)—retrieves an entity (Asset, AssetType, Custodian, or MaintenanceRecord) from
the AssetRegister using the entity’s identifier. Must return a nullptr if an entity with that identifier
cannot be found. As above, may be one function or a group of overloaded functions, document your
decision.
deleteEntity(id)—remove the entity with the given identifier from the register: must return true if
the entity was removed, false if it was not (e.g., it may have already been removed). Calling this function
multiple times with the same identifier will not have any negative consequences. Make sure you clear any
dynamically allocated memory when deleting an entity from the register (refer to
QObject::deleteLater() when cleaning up QObjects).
allEntities([type])
6—returns a collection of all entities stored in the register. Modifying the returned
collection must not modify the register. You must be able to retrieve all entities regardless of concrete
class, as well as all entities of a particular class (i.e., Asset, AssetType, Custodian, MaintenanceRecord).
The class level interface (static members) includes:
template instance()—static member function to return the single instance of this class (or any of
its subclasses). Use lazy initialisation to create the single instance if one does not currently exist. To
support extensibility, this function will be a template function: the type parameter will specify the
concrete subclass that is to be created (if the register instance does not already exist). Once an instance
of a type has been created, that instance will always be returned, regardless if the function is called with a
different type: i.e., there cannot be multiple register instances of different types instantiated at the same
time.
For example, to select the simple AssetRegister class as the singleton, the first call to this function
should be: AbstractAssetRegister::instance()
Note: you can create a non-template version of the function for convenience. This convenience function
should log an error if it is called before an instance of any concrete register types is created.
register—the static data member of type AbstractAssetRegister. Must be able to support
polymorphism. To allow subclasses to manipulate the static member (to support the extensibility
requirement) this member must be protected. This will allow the creation of a MockAssetRegister for
testing. Such a special subclass should have static member function that can clear the register class
variable, allowing a new register object to be created the on the subsequent call to instance().
Signals:
addedEntity(id, [type])—emitted when a new entity is added to the register.
deletedEntity(id, [type])—emitted when an entity is deleted from the register.
AssetRegister (derived from: AbstractAssetRegister)
The first concrete subclass of AbstractAssetRegister is the AssetRegister. This class is relatively
straightforward: it simply implements each of the functions of the interface defined by AbstractAssetRegister.
Important: to support the extensible singleton, this class must declare AbstractAssetRegister to be a friend
class. This will allow the instance() static function (which is defined in the scope of
AbstractAssetRegister and not its subclasses) to access the protected constructor of AssetRegister.

6 Parameters in square brackets ‘[‘ & ‘]’ are optional parameters.Revision 1, 2018-10-06
COMP 3023 Software Development with C++ - Assignment SP5 2018 Page 6 of 29
NetworkedAssetRegister (derived from: AssetRegister)
The NetworkedAssetRegister will behave in the same way as the standard AssetRegister (its core behaviour is
inherited) but adds support for synchronising itself over the network. It will be instantiated when the user
chooses to “log-in” using “online mode”. It must have a data member of type NetworkManager (refer to the
Networking section below), which it uses to exchange entities with other instances of the application running in
online mode. You may use a combination of function overrides and signals/slots to ensure the state of the
distributed application is synchronised across all participants. When updating the stored entities, you must check
the lastEditedTime and only update the local entity if the lastEditedTime is prior to that of the entity received
from the network. Refer to section RegisteredEntity for the attributes of entities.
Assets, Asset Types, and their Properties
First and foremost, the Asset Register application needs to be able to store information about the company’s
assets. This includes information such as the serial number, model, purchase price, who manages it, and what
maintenance has been performed on it. However, it also includes information about properties7
that differ
between different types of asset: for example, Pump assets have properties such as flow rate and alignment
(horizontal/vertical), while Computers may indicate their operating system, MAC address, IP address, etc.
Therefore, we need to be able represent the types of asset in the system alongside the assets themselves. In
addition, we must represent the user-defined properties (or user properties) specific to the types defined at
runtime, which will allow functionality such as validation of property values (e.g., the operating system property
for Computer may only allow the values: “OSX”, “Windows”, “Linux”).
There are a couple of Design Patterns that can help to dynamically define the types of asset at runtime. The first is
Prototype, which allows special instances (called prototypes) to be created that represent the type itself. These
prototypes can be cloned (i.e., copied) to create the actual instances of the type. Defining the Asset class as
prototype would allow the description of an asset type through the specification of the typical values for that
type; however, the copies often become disconnected from the prototype and the prototype does distinguish
between information related to the type itself and that of the real instances.

7 Qt also provides a concept of ‘dynamic properties’, do not confuse the user-defined properties that we are creating here
with the dynamic properties of Qt (which are still compile time constructs).Revision 1, 2018-10-06
COMP 3023 Software Development with C++ - Assignment SP5 2018 Page 7 of 29
The Type-Object Design Pattern also allows the dynamic definition of types/classes at runtime. Rather than
representing the type as prototype, it defines a “type” class (such as AssetType) to represent types themselves
and an “object” class (Asset) to represent the instances. The type class is then responsible for creating,
initialising, and possibly tracking, instances of the type. While this approach allows the separation of type
information vs. object information, it makes the type class responsible for creating instances (which may be
better handled by the object class) and can lead to duplication if, for example, you want to manage default values
for attributes and user-properties (which is better handled by the Prototype Pattern).
To adequately support the representation of assets, their types, and properties, we will combine the Prototype
and Type-Object patterns. The following is an extract of a UML diagram illustrating how this will be done. The
diagram is minimal, illustrating only the core interface required to support the representation of Assets,
AssetTypes, UserProperties. It also illustrates the associations to Custodian and MaintenanceRecord for
clarity. You will need to expand on what is illustrated to support your own design and implementation.
The following includes a brief description of the classes and their data members.
RegisteredEntity
DERIVES FROM: QOBJECT
Is an abstract class that is the parent of all classes that are directly stored in the AssetRegister (i.e., Asset,
AssetType, Custodian, and MaintenanceRecord). It inherits from QObject so that each of its derived classes
inherit the Signals & Slots mechanism from Qt, among other things. Its main purpose is to provide metadata that
each derived class requires to be properly managed by the AssetRegister:Revision 1, 2018-10-06
COMP 3023 Software Development with C++ - Assignment SP5 2018 Page 8 of 29
id—the unique identifier of the entity, used to store and retrieve entities in the register, as well as
synchronise entities across the network.
lastEditTime—a timestamp (QDateTime) the indicates when the last modification was made to the entity;
it is used for synchronisation across the network.
lastEditedBy—the name of the logged in user (from AssetRegister) who was the last change the entity.
These data members must not be modifiable by the user from the GUI.
Each derived class of RegisteredEntity should specify appropriate signals that allow others (such as the UI) to
be notified of interesting changes, for example, the addition of a property or change of an attribute or user
property value.
Custodian
DERIVES FROM: REGISTEREDENTITY
A Custodian is someone who has responsibility to manage an Asset. One Custodian can manage many Assets
and the details for Custodians can be managed independently of any Asset. It is suggested that this class should
be implemented before the main Asset, AssetType, and MaintenanceRecord classes; it is largely independent
and relatively simple, allowing you to learn aspects of the design and the Qt framework (GUI, and Signals/Slots,
networking, etc.) before moving on to the more complex and interrelated classes. It is dependent on
UserProperty, but will allow you to test the UserProperty and UserPropertyDefinition classes before
embedding them in the more complex Asset/AsssetType structure.
Data Members:
name—everyone needs a name
department—a UserProperty of type QString that restricts the allowable values to the following:
“Maintenance”, “Operations”, “Logistics”
phoneNumber—a UserProperty of type QString that restricts the allowable values to (mostly) valued
phone numbers. The constraints are as follows:
o 8-11 digits (inclusive)
o Optional ‘+’ at the beginning (and only the beginning)
o Spaces are allowed
o No other characters
This allows values such as: 83026611, 8302 6611, 08 8302 6611, +61 8 8302 6611
But not: 8302, 8302 6611 12345, 61+ 8 8302 6611, ext. 25000
Asset Type
DERIVES FROM: REGISTEREDENTITY
The AssetType class allows the definition of types at runtime. Its primary purpose is to describe the types of
properties that its instances can have (along with validation requirements), the default values of those properties,
and manage the Asset instances of itself (e.g., adding a new property definition must update each instance with a
matching property). The AssetType class requires the following data properties:
name—the name of the AssetType, e.g., ‘Centrifugal Pump’
prototype—this is a special instance of Asset that the AssetType uses to manage the default values of
properties as well as make new instances (by cloning the prototype).
instances—this is the collection of Assets that are the instances of this AssetType. The prototype must
not be included in this collection. Each Asset of the collection must refer back to the AssetType of the
instances collection it is in (this is the more important association, as the collection of instances can Revision 1, 2018-10-06
COMP 3023 Software Development with C++ - Assignment SP5 2018 Page 9 of 29
always be inferred from the back-references). This is a composition relation; therefore, destroying the
AssetType should destroy all of its instances.
propertyDefinitions—a collection of UserPropertyDefinitons that describe the properties specific to
the type. This is what allows individual assets to have more specific properties as well as validate the
values of those properties (the validators are attached to the UserPropertyDefinitions, not the
UserProperties themselves). The properties are managed by name, i.e., there can only be one
UserPropertyDefinition with a given name at any one time.
When the propertyDefintions of an AssetType are updated, you need to ensure that all instances of the
AssetType have their properties updated to match.
The interface for AssetType should provide functions to manipulate the property definitions (add/remove,
access, etc.), create a new instance of itself (i.e., clone its prototype), and otherwise keep track of its instances
(for example, you want to track the destruction of its instances via the QObject::destroyed signal to ensure the
instances collection is kept up-to-date when instances are deleted from the AssetRegister.
Asset
DERIVES FROM: REGISTEREDENTITY
The Asset class maintains the information related to the company’s assets. This includes details of the asset itself
(e.g., its type, model, serial number, and values for user-defined properties specified on its AssetType) as well as
who manages it (its Custodian) and details of its maintenance (i.e., its MaintenanceRecords).
Asset is forms part of the prototype pattern, and therefore needs to be “clonable” (through a clone() function),
this is not the same things as ‘copyable’. The clone() function must produce a deep-copy, that is a copy that is
completely independent of the original to prevent changes in one from affecting the other. Copyable, on the
other hand, often only performs a shallow-copy where data members are simply copied value-by-value (as is the
way of the default copy-constructor in C++) which means pointers, for example, remain pointing to the same
object. When implementing the clone() function be careful not to clone the type of the Asset, a cloned Asset
should refer to the same AssetType as the Asset from which it was cloned.
There are some properties that all Assets have, these are to be implemented as ordinary data members of the
Asset class, including:
serialNo—an identifier typically written on the object, its serial number. This is not the same as its ‘id’
(inherited from RegisteredEntity), which is an internal system identifier for keeping track of the object in
the system. It is entirely possible for two assets of different types to have the same serialNo.
brand—the maker of the asset, e.g., “ACME Pumps Co.”
model—the specific model of the Asset. While many assets may be of the same type (e.g., Pump,
Computer, etc.), they may be of different models (e.g., ‘ACME Co. Pump X3000’)
purchasePrice—the cost of the asset when it was bought (as a UserProperty of type double with a
precision of 2, refer to UserPropertyDefinition below)
purchaseDate—the date (QDateTime) at which the asset was bought by the company
disposalDate—the date (QDateTime) at which the asset was disposed of (sold, thrown away, etc.) by the
company. If an asset is not yet disposed, it will have no value for disposalDate; in contrast to
purchaseDate which will always have a value as Assets in the AssetRegister are those that have been
purchased by the company.
custodian—a reference (not necessarily C++ reference) to a Custodian object. Note the cardinality of
exactly 1 is from the user’s perspective. That is, user interface must not allow an Asset to be stored or Revision 1, 2018-10-06
COMP 3023 Software Development with C++ - Assignment SP5 2018 Page 10 of 29
saved if it has no Custodian; however, enforcing such a constraint at the lowest-level in the code is not
always possible nor useful. For example, the protoype of an AssetType does not require a Custodian.
maintenanceRecords—a collection of MaintenanceRecord objects that track the maintenance an Asset
has had. The records should be kept in order based on their timestamp (i.e., the time the maintenance
was performed, see Maintenance Record below) and there cannot be more than one record per
timestamp (for the same Asset). This is a composition relation such that deleting an Asset deletes all its
MaintenanceRecords.
When any of these values change, the Asset should emit a signal to indicate that an attribute has changed its
value. In the case of maintanenceRecords, this may be when a record is added or updated, not just assigned.
The Asset class also contains a collection of UserProperties, which match the UserProperyDefinitions of the
Asset’s type. That is, the size of the properties collection must be the same as the size of the
propertyDefinitions collection of the AssetType, and each UserProperty must refer to a
UserPropertyDefintion in the propertyDefinitions collection. When the UserPropertyDefinitions of an
AssetType are changed, the Assets that are instances must be kept synchronised.
Each UserProperty holds a value for a property described by its associated UserPropertyDefinition. When
values change, the Asset should be notified, and a signal emitted by the Asset to let interested parties know that
one of its properties has changed (e.g., a GUI might want to update the display
联系我们
  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp
热点标签

联系我们 - QQ: 99515681 微信:codinghelp
程序辅导网!