zoukankan      html  css  js  c++  java
  • 雇员记录系统

    雇员记录系统

             由于内容来自于《Professional C++》,所以书中相关说明不再赘述。

             一、Employee

    我们先实现一个Employee类:

    // Employee类声明
    // Employee.h
    #pragma once
    #include <string>
    
    namespace EmployeeRecorder
    {
        const int kDefaultStartingSalary = 30000;
    
        class Employee
        {
        public:
            Employee(void);
            ~Employee(void);
            
            void promote(int inRaiseAmount = 1000); // 升职
            void demote(int inDemeriteAmount = 1000); // 降职
            void hire(); // 雇用
            void fire(); // 解雇
            void display() const; // 显示
    
            // 检测器、修改器
            void setFirstName(const std::string& inFirstName);
            std::string getFirstName() const;
            void setLastName(const std::string& inLastName);
            std::string getLastName() const;
            void setEmployeeNumber(int inEmployeeNumber);
            int getEmployeeNumber() const;
            void setSalary(int inNewSalary);
            int getSalary() const;
            void setIsHired(bool inIsHired);
            bool getIsHired() const;
    
        protected:
            std::string mFirstName;
            std::string mLastName;
            int mEmployeeNumber;
            int mSalary;
            bool bHired;
        };
    }
    // Employee类实现
    // Employee.cpp
    #include "Employee.h"
    #include <iostream>
    
    namespace EmployeeRecorder
    {
        Employee::Employee(void)
            : mFirstName("")
            , mLastName("")
            , mEmployeeNumber(-1)
            , mSalary(kDefaultStartingSalary)
            , bHired(false)
        {
        }
    
        Employee::~Employee(void)
        {
        }
    
        void Employee::promote(int inRaiseAmount)
        {
            setSalary(getSalary() + inRaiseAmount);
        }
    
        void Employee::demote(int inDemeritAmount)
        {
            setSalary(getSalary() - inDemeritAmount);
        }
    
        void Employee::hire()
        {
            bHired = true;
        }
    
        void Employee::fire()
        {
            bHired = false;
        }
    
        void Employee::display() const
        {
            std::cout << "Employee: " << getLastName() << ", " << getFirstName() << std::endl;
            std::cout << "--------------------------------" << std::endl;
            std::cout << (bHired ? "Current Employee" : "Former Employee") << std::endl;
            std::cout << "Employee Number: " << getEmployeeNumber() << std::endl;
            std::cout << "Salary: $" << getSalary() << std::endl;
            std::cout << std::endl;
        }
    
        void Employee::setFirstName(const std::string& inFirstName)
        {
            mFirstName = inFirstName;
        }
    
        std::string Employee::getFirstName() const
        {
            return mFirstName;
        }
    
        void Employee::setLastName(const std::string& inLastName)
        {
            mLastName = inLastName;
        }
    
        std::string Employee::getLastName() const
        {
            return mLastName;
        }
    
        void Employee::setEmployeeNumber(int inEmployeeNumber)
        {
            mEmployeeNumber = inEmployeeNumber;
        }
    
        int Employee::getEmployeeNumber() const
        {
            return mEmployeeNumber;
        }
    
        void Employee::setSalary(int inNewSalary)
        {
            mSalary = inNewSalary;
        }
    
        int Employee::getSalary() const
        {
            return mSalary;
        }
    
        void Employee::setIsHired(bool inIsHired)
        {
            bHired = inIsHired;
        }
    
        bool Employee::getIsHired() const
        {
            return bHired;
        }
    }
    // Employee类测试
    // EmployeeTest.cpp
    #include "Employee.h"
    #include <iostream>
    using namespace std;
    using namespace EmployeeRecorder;
    
    int main()
    {
        // 测试Employee类
        cout << "Testing the Employee class." << endl;
        Employee emp;
        emp.setFirstName("Marni");
        emp.setLastName("Kleper");
        emp.setEmployeeNumber(71);
        emp.setSalary(50000);
        emp.promote();
        emp.promote(50);
        emp.hire();
        emp.display();
    
        return 0;
    }

             二、Database

             下面设计Database类来存储Employee类对象。

    // Database类定义
    // Database.h
    #pragma once
    #include "Employee.h"
    #include <iostream>
    #include <vector>
    
    namespace EmployeeRecorder
    {
        const int kFirstEmployeeNumber = 1000;
    
        class Database
        {
        public:
            Database(void);
            ~Database(void);
    
            Employee& addEmployee(const std::string& inFirstName,
                const std::string& inLastName);
            Employee& getEmployee(int inEmployeeNumber) /*const*/;
            Employee& getEmployee(const std::string& inFirstName,
                const std::string& inLastName) /*const*/;
            void displayAll() const;
            void displayCurrent() const;
            void displayFormer() const;
    
        protected:
            std::vector<Employee> mEmployees;
            int mNextEmployeeNumber;
        };
    }
    // Database类实现
    // Database.cpp
    #include "Database.h"
    #include <iostream>
    #include <stdexcept>
    
    namespace EmployeeRecorder
    {
        Database::Database(void)
        {
            mNextEmployeeNumber = kFirstEmployeeNumber;
        }
    
        Database::~Database(void)
        {
        }
    
        Employee& Database::addEmployee(const std::string& inFirstName, const std::string& inLastName)
        {
            Employee theEmployee;
            theEmployee.setFirstName(inFirstName);
            theEmployee.setLastName(inLastName);
            theEmployee.setEmployeeNumber(++mNextEmployeeNumber);
            theEmployee.hire();
            mEmployees.push_back(theEmployee);
            return mEmployees[mEmployees.size() - 1];
        }
    
        Employee& Database::getEmployee(int inEmployeeNumber) /*const*/
        {
            for (auto iter = mEmployees.begin(); iter != mEmployees.end(); ++iter)
            {
                if (iter->getEmployeeNumber() == inEmployeeNumber)
                {
                    return *iter;
                }
            }
            std::cerr << "No employee with number " << inEmployeeNumber << std::endl;
            throw std::exception();
        }
    
        Employee& Database::getEmployee(const std::string& inFirstName, const std::string& inLastName) /*const*/
        {
            for (auto iter = mEmployees.begin(); iter != mEmployees.end(); ++iter)
            {
                if (iter->getFirstName() == inFirstName && iter->getLastName() == inLastName)
                {
                    return *iter;
                }
            }
            std::cerr << "No employee with number " << inFirstName << ' ' << inLastName << std::endl;
            throw std::exception();
        }
    
        void Database::displayAll() const
        {
            for (auto iter = mEmployees.begin(); iter != mEmployees.end(); ++iter)
            {
                iter->display();
            }
        }
    
        void Database::displayCurrent() const
        {
            for (auto iter = mEmployees.begin(); iter != mEmployees.end(); ++iter)
            {
                if (iter->getIsHired())
                {
                    iter->display();
                }
            }
        }
    
        void Database::displayFormer() const
        {
            for (auto iter = mEmployees.begin(); iter != mEmployees.end(); ++iter)
            {
                if (!iter->getIsHired())
                {
                    iter->display();
                }
            }
        }
    }
    // Database类测试
    // DatabaseTest.cpp
    #include "Database.h"
    #include <iostream>
    using namespace std;
    using namespace EmployeeRecorder;
    
    int main()
    {
        Database myDB;
        Employee& emp1 = myDB.addEmployee("Greg", "Wallis");
        emp1.fire();
        Employee& emp2 = myDB.addEmployee("Scott", "Kleper");
        emp2.setSalary(100000);
        Employee& emp3 = myDB.addEmployee("Nick", "Solter");
        emp3.setSalary(10000);
        emp3.promote();
        cout << "All employees: " << endl;
        cout << endl;
        myDB.displayAll();
        cout << endl;
    
        cout << "Current employees: " << endl;
        cout << endl;
        myDB.displayCurrent();
        cout << endl;
    
        cout << "Former employees: " << endl;
        cout << endl;
        myDB.displayFormer();
        cout << endl;
    
        return 0;
    }

             三、用户界面

    // UserInterface.cpp
    #include "Database.h"
    #include <iostream>
    #include <stdexcept>
    using namespace std;
    using namespace EmployeeRecorder;
    
    int displayMenu();
    void doHire(Database& inDB);
    void doFire(Database& inDB);
    void doPromote(Database& inDB);
    void doDemote(Database& inDB);
    
    int main()
    {
        Database employeeDB;
        bool done = false;
        while (!done)
        {
            int selection = displayMenu();
            switch (selection)
            {
            case 1:
                doHire(employeeDB);
                break;
    
            case 2:
                doFire(employeeDB);
                break;
    
            case 3:
                doPromote(employeeDB);
                break;
    
            case 4:
                doDemote(employeeDB);
                break;
    
            case 5:
                employeeDB.displayAll();
                break;
    
            case 6:
                employeeDB.displayCurrent();
                break;
    
            case 7:
                employeeDB.displayFormer();
                break;
    
            case 0:
                done = true;
                break;
    
            default:
                cerr << "Unknown command." << endl;
                break;
            }
        }
    
        return 0;
    }
    
    int displayMenu()
    {
        int selection;
        cout << endl;
        cout << "Employee Database" << endl;
        cout << "-----------------" << endl;
        cout << "1) Hire a new employee" << endl;
        cout << "2) Fire an employee" << endl;
        cout << "3) Promote an employee" << endl;
        cout << "4) Demote an employee" << endl;
        cout << "5) List all employees" << endl;
        cout << "6) List all current employees" << endl;
        cout << "7) List all previous employees" << endl;
        cout << "0) Quit" <<endl;
        cout << endl;
        cout << "---> ";
        cin >> selection;
        return selection;
    }
    
    void doHire(Database& inDB)
    {
        string firstName;
        string lastName;
        cout << "First name? ";
        cin >> firstName;
        cout << "Last name? ";
        cin >> lastName;
        try
        {
            inDB.addEmployee(firstName, lastName);
        }
        catch (const exception&)
        {
            cerr << "Unable to add new employee!" << endl;
        }
    }
    
    void doFire(Database& inDB)
    {
        int employeeNumber;
        cout << "Employee number? ";
        cin >> employeeNumber;
        try
        {
            Employee& emp = inDB.getEmployee(employeeNumber);
            emp.fire();
            cout << "Employee " << employeeNumber << " terminated." << endl;
        }
        catch (const exception&)
        {
            cerr << "Unable to terminate employee!" << endl;
        }
    }
    
    void doPromote(Database& inDB)
    {
        int employeeNumber;
        int raiseAmount;
        cout << "Employee number? ";
        cin >> employeeNumber;
        cout << "How much of a raise? ";
        cin >> raiseAmount;
        try
        {
            Employee& emp = inDB.getEmployee(employeeNumber);
            emp.promote(raiseAmount);
        }
        catch (const exception&)
        {
            cerr << "Unable to promote employee " << employeeNumber << '!' << endl;
        }
    }
    
    void doDemote(Database& inDB)
    {
        int employeeNumber;
        int lowerAmount;
        cout << "Employee number? ";
        cin >> employeeNumber;
        cout << "How much of a lower? ";
        cin >> lowerAmount;
        try
        {
            Employee& emp = inDB.getEmployee(employeeNumber);
            emp.demote(lowerAmount);
        }
        catch (const exception&)
        {
            cerr << "Unable to demote employee " << employeeNumber << '!' << endl;
        }
    }

             四、对雇员记录系统的分析和讨论

             以上雇员记录系统一共涉及了两个类:

             Employee

             Database

             其中,Employee用于代表具体的一个雇员,Database是存放所有的雇员,即Database有Employee聚合而成。

             Employee的成员函数有:

                       void promote(int inRaiseAmount = 1000); // 升职

                       void demote(int inDemeriteAmount = 1000); // 降职

                       void hire(); // 雇用

                       void fire(); // 解雇

                       void display() const; // 显示

     

                       // 检测器、修改器

                       void setFirstName(const std::string& inFirstName);

                       std::string getFirstName() const;

                       void setLastName(const std::string& inLastName);

                       std::string getLastName() const;

                       void setEmployeeNumber(int inEmployeeNumber);

                       int getEmployeeNumber() const;

                       void setSalary(int inNewSalary);

                       int getSalary() const;

                       void setIsHired(bool inIsHired);

                       bool getIsHired() const;

             Database的成员函数有:

                       Employee& addEmployee(const std::string& inFirstName,

                                const std::string& inLastName);

                       Employee& getEmployee(int inEmployeeNumber) /*const*/;

                       Employee& getEmployee(const std::string& inFirstName,

                                const std::string& inLastName) /*const*/;

                       void displayAll() const;

                       void displayCurrent() const;

                       void displayFormer() const;

             在具体的UserInterface.cpp中关于雇员的promote、demote操作是作用于Database上的,在具体的promote、demote操作是先通过Database的getEmployee获取具体的雇员,然后针对具体的雇员通过Employee中的promote、demote进行相应的操作。

             这里就有个问题,为什么是要获取了具体的雇员,然后通过Employee里的promote、demote进行操作,而不再Database中设置相应的promote、demote操作对具体的雇员进行操作呢?这里我的理解是Database是Employee的聚合,promote、demote是针对某个具体的Employee进行的,虽然也可以通过EmployeeNumber在Database中对具体的雇员进行操作,但是这种操作不应该属于Database的,因为针对某个具体雇员的操作不应该放在全局的Database中,而应该放在单个的Employee中。这也就是类与类之间尽可能的耦合松些。

             既然是通过Employee中的成员函数进行的操作,那么是如何实现的呢?

             程序中,Database的成员函数getEmployee的返回类型为Employee&,在具体的doPromote、doDemote实现中具体变量为Employee&引用类型,所以,赋值之后操作的是Database中的某个Employee。

             有关函数返回值类型、被赋值变量类型有以下几种情况:    

    函数返回值类型

    被赋值变量类型

    效果

    数据份数

    引用

    引用

    通过变量操作的是原数据

    1份:原数据

    引用

    非引用

    通过变量操作的是被赋值的变量

    2份:原数据、被赋值变量

    非引用

    引用

    通过变量操作的事返回的值,但是返回的值是一个局部临时值,执行完赋值语句后函数返回对象会析构,所以后续执行会报错

    2份:原数据、函数返回值

    非引用

    非引用

    通过变量操作的是被赋值的变量

    3份:原数据、函数返回值、被赋值变量

             上面我们说到Employee和Database之间是聚合关系,下面我们给出他们的类图:

    // by StarUML

  • 相关阅读:
    HTTP Server
    分享:uSTL 2.0 发布,STL 标准模板库
    Boost.Asio和ACE之间关于Socket编程的比较
    使用BOOST实现简单的HTTP网页下载
    HTTP Client
    轩辕高端IT培训中心系昆山轩辕软件技术有限公司旗下的IT培训部门
    分享:链表实现的队列
    镕、喆、冇用五笔为何打不出来,在此向各位好友请教! 已回答 搜搜问问
    第一讲 Linux 编程入门与基本编程工具的使用
    C++03:使用Boost-用Asio实现简易Echo Server
  • 原文地址:https://www.cnblogs.com/unixfy/p/3265543.html
Copyright © 2011-2022 走看看