设计模式(2) 工厂模式 ( 二 ) 学生成绩管理系统设计

续上篇 工厂模式 ( 一 ) 学生成绩管理系统设计

  1. 一个实体”根类” Entity , 派生出三种类——老师,学生,课程
  2. 一个接口工厂,派生出三种工厂,分别 Create 老师,学生,课程

挂一个尚未解决问题的设计

我的想法是,将工厂类和 Entity 实体类都继承自一个“单根类”,Object ——就类似于 Java 的 Object, 这样一来就会很方便。利用一种指针操纵所有子类,当然,包括清理子类对象。

遇到的问题:

  1. 用 Object 对象提供统一,每次遇到非 Object 权限时,就要进行 dynamic_cast 强制转换,一来可能不安全,有可能转换失败,而来还要进行检查。
  2. 如果用 Object 来管理 Factory 对象,如何将新生成的 Factory 或者是 Factory 的子类放进垃圾收集器?我的第一想法是 emplace_back ( this ) ,但是这样会“误伤”栈中的对象,因为垃圾收集器需要 delete, 而栈内存的对象是主动释放的,两者冲突 ——所以,如果要这么做,就必须默认全部通过指针来实现,不能出现非指针类的情况。
  3. 整体来说,虽然可以满足 Object 统一管理,但是,变得有些复杂,而且不安全,设计非但没有变简单,反而复杂了。

无非是想更好地内存管理,其他可以尝试的思路

  1. 自己实现智能指针,主动释放指针指向的内存
  2. 实现一个内存池
  3. 重载 operator new 和 operator delete
  4. 考虑菱形继承

本次尝试,还是挂在这里吧。

#include <bits/stdc++.h>
#define rep( i , j , n ) for ( int i = int(j) ; i < int(n) ; ++i )
#define dew( i , j , n ) for ( int i = int(n-1) ; i > int(j) ; --i )
#define _PATH __FILE__ , __LINE__
typedef std::pair < int , int > P ;
using std::cin ;
using std::cout ;
using std::endl ;
using std::string ;

class Object {  
protected:
    // 一个静态的垃圾收集器, 收集所有的 Object 的子类产生的 Object* 指针
    static std::vector< Object* > Litter ;
private:
    // 这个函数用 atexit 登记, main 函数结束之后启动 // 设置为私有, 只能接口释放
    static void End_OK () {
        cout << endl << "main 函数结束后开始清理\n\n" ;
        for ( auto &it : Litter ) 
            if ( it != nullptr ) 
                delete it ;
        Litter.clear () ;
        Litter.shrink_to_fit () ;   // 清空容器
    }
public:
    Object () {
        static std::once_flag flag ;
        std::call_once ( flag , [&] () { atexit ( End_OK ) ; } ) ;
    }
    virtual ~Object () = default ;
} ;
// 静态变量的类外声明
std::vector< Object* > Object::Litter ;


class Entity : public Object {
protected:
    int NO ;
public:
    string name ;
    explicit Entity ( const int _NO , const string& _name ) 
        : NO ( _NO ) , name ( std::move ( _name ) ) 
    {}
    virtual ~Entity () = default ;
    virtual void display () const = 0 ;
} ;

class Student : public Entity {
public:
    explicit Student ( const int _NO , const string& _name ) 
        : Entity ( _NO , _name ) 
    {}
    void display () const override {
        cout << endl << "学号  :  " << NO << "\t" << name << endl ;
    }
} ;

class Teacher : public Entity {
private:
    double salary ;
public:
    explicit Teacher ( const int _NO , const string& _name ) 
        : Entity ( _NO , _name ) 
        , salary ( 10000 ) 
    {}
    void display () const override {
        cout << endl << "工号  :  " << NO << "\t" << name ;
        cout << "\t\t薪水  :  " << salary << endl ;
    }
} ;

class Course : public Entity {
public:
    explicit Course ( const int NO , const string& name ) 
        : Entity ( NO , name ) 
    {}
    void display () const override {
        cout << endl << "编号  :  " << NO << "\t" << name << endl ;
    }
} ;

class Factory : public Object {
public:
    Factory () {
        Litter.emplace_back ( this ) ;
    }
    virtual ~Factory () = default ;
    virtual Entity* Make_Entity ( const int NO , const string& name ) = 0 ;
} ;

class Teacher_Factory : public Factory {
public:
    Entity* Make_Entity ( const int NO , 
                const string& name ) override {
        Object* One = new Teacher ( NO , name ) ;
        Litter.emplace_back ( One ) ;    // 垃圾收集器收集
        if ( Entity* null = dynamic_cast< Entity* > ( One ) ) 
            return null ;
        throw std::bad_alloc () ;
    }
} ;

class Student_Factory : public Factory {
public:
    Entity* Make_Entity ( const int NO , 
                const string& name ) override {
        Object* One = new Student ( NO , name ) ;
        Litter.emplace_back ( One ) ;    // 垃圾收集器收集
        if ( Entity* null = dynamic_cast< Entity* > ( One ) ) 
            return null ;
        throw std::bad_alloc () ;
    }
} ;

class Course_Factory : public Factory {
public:
    Entity* Make_Entity ( const int NO , 
                const string& name ) override {
        Object* One = new Course ( NO , name ) ;
        Litter.emplace_back ( One ) ;    // 垃圾收集器收集
        if ( Entity* null = dynamic_cast< Entity* > ( One ) ) 
            return null ;
        throw std::bad_alloc () ;
    }
} ;

int main () {
    Object* One = new Student_Factory () ;
    if ( Student_Factory* A = dynamic_cast< Student_Factory* > ( One ) ) {

        Entity* YHL = A->Make_Entity ( 212 , "YHL" ) ;
        YHL->display () ;
        Entity* Fluence = A->Make_Entity ( 1229 , "Fluence" ) ;
        Fluence->display () ;

        YHL = Fluence = nullptr ;  
    }

    Object* Two = new Teacher_Factory () ;  // 不支持非指针
    if ( Teacher_Factory* B = dynamic_cast< Teacher_Factory* > ( Two ) ) {

        Entity* Zhang = B->Make_Entity ( 212 , "Zhang" ) ;
        Zhang->display () ;
        Entity* Tan = B->Make_Entity ( 1229 , "Tan" ) ;
        Tan->display () ;

        Zhang = Tan = nullptr ;  
    }
    return 0 ;
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/nishisiyuetian/article/details/80286657