Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа 3 Объектная модель увц.rtf
Скачиваний:
2
Добавлен:
01.03.2025
Размер:
872 Кб
Скачать
☆

На данном этапе можно остановиться, если устраивает оценка “удовлетворительно”. Для получения более высокой оценки следует выполнить остальные задания.

  1. Отображение основных абстракций на языке программирования C++:

  • Для всех выявленных классов создать на языке C++ декларации:

    • классов;

    • атрибутов;

    • конструкций, реализующих отношения между классами:

    • отношения обобщения в виде наследования классов;

    • отношения агрегации и ассоциации, используя механизмы языка программирования, наиболее близко отражающие семантику диаграммы (например, ссылки, указатели, коллекции, объекты smart pointers, и т.п.).

  • Снабдить все декларации качественными комментариями (по возможности, на английском языке).

  • Создать необходимые для организации работы класса объявления и определения ключевых операций, учитывающие семантику всех атрибутов и отношений:

    • конструктор(ы);

    • деструктор;

    • операции-селекторы для описательных атрибутов, для навигации по связям;

    • операции для формирования связей (если имеются отношения с кратностью 1..*, *..* , либо связь является необязательной).

Заголовки классов следует размещать в отдельных заголовочных файлах, а реализации методов классов следует размещать в отдельных C++ файлах, имена которых должны соответствовать именам классов (например, класс Reservation – объявление в reservation.hpp, реализация в reservation.cpp) ;

  1. Формирование тестовой программы, подтверждающей работоспособность модели:

  • Составьте консольную тестовую С++ программу, отражающую несколько реалистичных примеров структуры объектной модели, использующих большинство созданных классов:

    • Программа должна создавать некоторое количество тестовых объектов модели, вручную организовывать связи между ними. Вводить данные об объектах извне во время выполнения не требуется, конкретный состав объектной модели примера может быть жестко задан в коде тестовой программы.

    • Программа должна уметь обходить созданную модель от вершины иерархии целое-часть ко всем листьям, и при этом распечатывать данные об посещаемых во время обхода объектах (адрес, тип, значения атрибутов).

    • Вложенность объектов по иерархии целое-часть уместно выразить при помощи отступов или любым другим подходящим способом.

    • Распечатка может осуществляться или на экран, или в дисковый файл.

Пример простейшей объектной модели

Ниже приведена UML-диаграмма простейшей объектной модели, предназначенной для хранения данных о заказах товаров в магазине.

Созданные классы имеют следующие обязанности:

  1. Класс Shop – представляет собой информацию о магазине, существенную для данного примера. Этот класс будет создаваться только в одном экземпляре за время выполнения программы.

  2. Класс Order – представляет заказ в магазине, имеет уникальный идентификатор, время регистрации. Имеется ярко выраженная операция вычисления стоимости.

  3. Класс Item – представляет строку заказа: товар, количество штук, цену на момент заказа.

  4. Класс Product – представляет собой описание товара, включая уникальный номер, название, описание, код страны происхождения, а также текущую стоимость.

  5. Класс Money – тип-значение, представляющий денежную единицу с целой частью и копейками.

Ниже приведена упрощенная реализация данной модели на языке С++.

money.hpp

#ifndef _MONEY_HPP_

#define _MONEY_HPP_

//-----------------------------------------------------------------------------

#include <string>

//-----------------------------------------------------------------------------

class Money

{

//-------------------------

public:

//-------------------------

Money ();

Money ( unsigned int _integralPart, unsigned char _fractionalPart );

static Money fromString ( const std::string & _moneyAsText );

//-------------------------

std::string toString () const;

bool operator == ( const Money & _m ) const;

Money operator + ( Money const & _m ) const;

Money operator * ( unsigned int _n ) const;

//-------------------------

private:

//-------------------------

unsigned int m_integralPart;

unsigned char m_fractionalPart;

//-------------------------

};

//-----------------------------------------------------------------------------

#endif // _MONEY_HPP_

money.cpp

//-----------------------------------------------------------------------------

#include "money.hpp"

#include <boost/lexical_cast.hpp>

//-----------------------------------------------------------------------------

Money::Money ()

: m_integralPart( 0 ),

m_fractionalPart( 0 )

{

}

//-----------------------------------------------------------------------------

Money::Money ( unsigned int _integralPart, unsigned char _fractionalPart )

: m_integralPart( _integralPart ),

m_fractionalPart( _fractionalPart )

{

}

//-----------------------------------------------------------------------------

Money

Money::fromString ( const std::string & _moneyAsText )

{

double money = boost::lexical_cast< double >( _moneyAsText );

if ( money < 0. )

throw std::exception();

unsigned int integralPart = static_cast< unsigned int >( money );

unsigned char fractionalPart = static_cast< unsigned char >(

( money - integralPart ) * 100.0

);

return Money( integralPart, fractionalPart );

}

//-----------------------------------------------------------------------------

std::string

Money::toString () const

{

char buf[ 100 ];

sprintf( buf, "%d.%02d", m_integralPart, m_fractionalPart );

return buf;

}

//-----------------------------------------------------------------------------

bool

Money::operator == ( const Money & _m ) const

{

return m_integralPart == _m.m_integralPart &&

m_fractionalPart == _m.m_fractionalPart;

}

//-----------------------------------------------------------------------------

Money

Money::operator + ( Money const & _m ) const

{

unsigned int resultIngeralPart = m_integralPart + _m.m_integralPart;

unsigned char resultFractionalPart = m_fractionalPart + _m.m_fractionalPart;

if ( resultFractionalPart >= 100 )

{

++resultIngeralPart;

resultFractionalPart %= 100;

}

return Money( resultIngeralPart, resultFractionalPart );

}

//-----------------------------------------------------------------------------

Money

Money::operator * ( unsigned int _n ) const

{

unsigned int moneyInCents = m_integralPart * 100 + m_fractionalPart;

moneyInCents *= _n;

return Money( moneyInCents / 100, moneyInCents % 100 );

}

//-----------------------------------------------------------------------------

product.hpp

#ifndef _PRODUCT_HPP_

#define _PRODUCT_HPP_

//-----------------------------------------------------------------------------

#include "money.hpp"

#include <string>

//-----------------------------------------------------------------------------

class Product

{

//-------------------------

public:

//-------------------------

Product (

unsigned int _uniqueID,

const std::string & _name,

const std::string & _description,

const Money & _initialPrice

);

//-------------------------

unsigned int getUniqueID () const;

const std::string & getName () const;

const std::string & getDescription () const;

const Money & getCurrentPrice () const;

void setPrice ( const Money & _newPrice );

//-------------------------

private:

//-------------------------

const unsigned int m_uniqueID;

const std::string m_name;

const std::string m_description;

Money m_currentPrice;

//-------------------------

};

//-----------------------------------------------------------------------------

inline

unsigned int

Product::getUniqueID () const

{

return m_uniqueID;

}

//-----------------------------------------------------------------------------

inline

const std::string &

Product::getName () const

{

return m_name;

}

//-----------------------------------------------------------------------------

inline

const std::string &

Product::getDescription () const

{

return m_description;

}

//-----------------------------------------------------------------------------

inline

const Money &

Product::getCurrentPrice () const

{

return m_currentPrice;

}

//-----------------------------------------------------------------------------

inline

void

Product::setPrice ( const Money & _newPrice )

{

m_currentPrice = _newPrice;

}

//-----------------------------------------------------------------------------

#endif // _PRODUCT_HPP_

product.cpp

//-----------------------------------------------------------------------------

#include "product.hpp"

//-----------------------------------------------------------------------------

Product::Product (

unsigned int _uniqueID,

const std::string & _name,

const std::string & _description,

const Money & _initialPrice

)

: m_uniqueID( _uniqueID ),

m_name( _name ),

m_description( _description ),

m_currentPrice( _initialPrice )

{

}

//-----------------------------------------------------------------------------

item.hpp

#ifndef _ITEM_HPP_

#define _ITEM_HPP_

//-----------------------------------------------------------------------------

#include "money.hpp"

//-----------------------------------------------------------------------------

class Product;

//-----------------------------------------------------------------------------

class Item

{

//-------------------------

public:

//-------------------------

Item ( Product const & _product, unsigned int _quantity );

//-------------------------

Product const & getProduct () const;

unsigned int getQuantity () const;

void setQuantity ( unsigned int _newQuantity );

Money getPrice () const;

Money getCost () const;

//-------------------------

private:

//-------------------------

Product const & m_product;

unsigned int m_quantity;

Money const m_price;

//-------------------------

};

//-----------------------------------------------------------------------------

inline

Product const &

Item::getProduct () const

{

return m_product;

}

//-----------------------------------------------------------------------------

inline

unsigned int

Item::getQuantity () const

{

return m_quantity;

}

//-----------------------------------------------------------------------------

inline

void

Item::setQuantity ( unsigned int _newQuantity )

{

m_quantity = _newQuantity;

}

//-----------------------------------------------------------------------------

inline

Money

Item::getPrice () const

{

return m_price;

}

//-----------------------------------------------------------------------------

#endif // _ITEM_HPP_

item.cpp

//-----------------------------------------------------------------------------

#include "item.hpp"

#include "product.hpp"

//-----------------------------------------------------------------------------

Item::Item ( Product const & _product, unsigned int _quantity )

: m_product( _product ),

m_price( _product.getCurrentPrice() ),

m_quantity ( _quantity )

{

}

//-----------------------------------------------------------------------------

Money

Item::getCost () const

{

return m_price * m_quantity;

}

//-----------------------------------------------------------------------------

order.hpp

#ifndef _ORDER_HPP_

#define _ORDER_HPP_

//-----------------------------------------------------------------------------

#include "money.hpp"

#include <vector>

//-----------------------------------------------------------------------------

class Item;

class Product;

//-----------------------------------------------------------------------------

class Order

{

//-------------------------

public:

//-------------------------

Order ( unsigned int _uniqueID, time_t _registeredAt );

~Order ();

//-------------------------

unsigned int getUniqueID () const;

time_t getRegistrationTime () const;

//-------------------------

unsigned int getItemsCount () const;

Item const & getItem ( unsigned int _itemIndex ) const;

Item & newItem ( Product const & _item, unsigned int _quantity );

void removeItem ( Item & _item );

//-------------------------

Money getCost () const;

//-------------------------

private:

//-------------------------

const unsigned int m_uniqueID;

const time_t m_registeredAt;

typedef std::vector< Item * > Items;

Items m_items;

//-------------------------

};

//-----------------------------------------------------------------------------

inline

unsigned int

Order::getUniqueID () const

{

return m_uniqueID;

}

//-----------------------------------------------------------------------------

inline

time_t

Order::getRegistrationTime () const

{

return m_registeredAt;

}

//-----------------------------------------------------------------------------

inline

unsigned int

Order::getItemsCount () const

{

return m_items.size();

}

//-----------------------------------------------------------------------------

inline

Item const &

Order::getItem ( unsigned int _itemIndex ) const

{

return * ( m_items.at( _itemIndex ) );

}

//-----------------------------------------------------------------------------

#endif // _ORDER_HPP_

order.cpp

//-----------------------------------------------------------------------------

#include "order.hpp"

#include "item.hpp"

#include <algorithm>

#include <boost/checked_delete.hpp>

#include <exception>

//-----------------------------------------------------------------------------

Order::Order ( unsigned int _uniqueID, time_t _registeredAt )

: m_uniqueID( _uniqueID ),

m_registeredAt( _registeredAt )

{

}

//-----------------------------------------------------------------------------

Order::~Order ()

{

std::for_each(

m_items.begin(),

m_items.end(),

boost::checked_deleter< Item >()

);

}

//-----------------------------------------------------------------------------

Item &

Order::newItem ( Product const & _product, unsigned int _quantity )

{

Item * pNewItem = new Item( _product, _quantity );

m_items.push_back( pNewItem );

return * pNewItem;

}

//-----------------------------------------------------------------------------

void

Order::removeItem ( Item & _item )

{

Items::iterator it = std::find( m_items.begin(), m_items.end(), & _item );

if ( it == m_items.end() )

throw std::exception();

m_items.erase( it );

}

//-----------------------------------------------------------------------------

Money

Order::getCost () const

{

Money totalCost = Money();

Items::const_iterator it = m_items.begin();

while ( it != m_items.end() )

{

const Item * pItem = * it;

totalCost = totalCost + pItem->getCost();

++ it;

}

return totalCost;

}

//-----------------------------------------------------------------------------

shop.hpp

#ifndef _SHOP_HPP_

#define _SHOP_HPP_

//-----------------------------------------------------------------------------

#include <string>

#include <vector>

#include <map>

#include <memory>

//-----------------------------------------------------------------------------

class Product;

class Order;

class Money;

//-----------------------------------------------------------------------------

class Shop

{

//-------------------------

public:

//-------------------------

Shop ( const std::string &_title );

~Shop ();

//-------------------------

const std::string & getTitle () const;

//-------------------------

Product const & addProduct (

const std::string & _productName,

const std::string & _description,

const Money & _initialPrice

);

void dropProduct ( const std::string & _name );

unsigned int getProductsCount () const;

Product const * findProduct ( const std::string & _name ) const;

class ProductIterator

{

public:

virtual bool hasNext () const = 0;

virtual Product const & getProduct () const = 0;

virtual void next () = 0;

};

std::auto_ptr< ProductIterator > browseProducts () const;

//-------------------------

unsigned int getOrdersCount () const;

const Order & getOrder ( unsigned int _orderIndex ) const;

Order & newOrder ();

//-------------------------

private:

//-------------------------

const std::string m_title;

typedef std::map< std::string, Product * > ProductDescriptions;

ProductDescriptions m_products;

std::vector< Order * > m_orders;

//-------------------------

};

//-----------------------------------------------------------------------------

inline

const std::string &

Shop::getTitle () const

{

return m_title;

}

//-----------------------------------------------------------------------------

inline

unsigned int

Shop::getProductsCount () const

{

return m_products.size();

}

//-----------------------------------------------------------------------------

inline

unsigned int

Shop::getOrdersCount () const

{

return m_orders.size();

}

//-----------------------------------------------------------------------------

inline

const Order &

Shop::getOrder ( unsigned int _orderIndex ) const

{

return *( m_orders.at( _orderIndex ) );

}

//-----------------------------------------------------------------------------

#endif // _SHOP_HPP_

shop.cpp

//-----------------------------------------------------------------------------

#include "shop.hpp"

#include "order.hpp"

#include "product.hpp"

#include <ctime>

#include <algorithm>

#include <exception>

#include <boost/checked_delete.hpp>

//-----------------------------------------------------------------------------

Shop::Shop ( const std::string & _title )

: m_title( _title )

{

}

//-----------------------------------------------------------------------------

Shop::~Shop ()

{

std::for_each(

m_orders.begin(),

m_orders.end(),

boost::checked_deleter< Order >()

);

std::for_each(

m_products.begin(),

m_products.end(),

std::compose1(

boost::checked_deleter< Product >(),

std::select2nd< ProductDescriptions::value_type >()

)

);

}

//-----------------------------------------------------------------------------

Order &

Shop::newOrder ()

{

Order * pNewOrder = new Order( getOrdersCount(), time( NULL ) );

m_orders.push_back( pNewOrder );

return * pNewOrder;

}

//-----------------------------------------------------------------------------

Product const &

Shop::addProduct (

const std::string & _productName,

const std::string & _description,

const Money & _initialPrice

)

{

if ( findProduct( _productName ) )

throw std::exception();

Product * pProduct = new Product(

m_products.size(), /* id */

_productName,

_description,

_initialPrice

);

m_products.insert(

std::make_pair(

pProduct->getName(),

pProduct

)

);

return * pProduct;

}

//-----------------------------------------------------------------------------

void

Shop::dropProduct ( const std::string & _name )

{

ProductDescriptions::iterator it = m_products.find( _name );

if ( it != m_products.end() )

{

Product * pProduct = it->second;

m_products.erase( it );

delete pProduct;

}

else

throw std::exception();

}

//-----------------------------------------------------------------------------

Product const *

Shop::findProduct ( const std::string & _name ) const

{

ProductDescriptions::const_iterator it = m_products.find( _name );

if ( it == m_products.end() )

return NULL;

return it->second;

}

//-----------------------------------------------------------------------------

std::auto_ptr< Shop::ProductIterator >

Shop::browseProducts () const

{

class ProductIteratorImpl

: public ProductIterator

{

//-----------------------

public:

//-----------------------

ProductIteratorImpl ( ProductDescriptions const & _descriptions )

: m_descriptions( _descriptions ),

m_it( _descriptions.begin() )

{

}

//-----------------------

virtual bool hasNext () const

{

return m_it != m_descriptions.end();

}

//-----------------------

virtual Product const & getProduct () const

{

return *( m_it->second );

}

//-----------------------

virtual void next ()

{

++ m_it;

}

//-----------------------

private:

//-----------------------

ProductDescriptions const & m_descriptions;

ProductDescriptions::const_iterator m_it;

//-----------------------

};

return std::auto_ptr< ProductIterator >(

new ProductIteratorImpl( m_products )

);

}

//-----------------------------------------------------------------------------