设计模式(3) 策略模式 初步实现多种登陆策略

现在我要实现教师,学生,管理员不同登录方式的系统

设计思路

  1. 一个抽象策略类,由多种登录策略继承
  2. 一个登录系统,内含一种策略作为参数
  3. 可以更改策略

未解决的问题

抽象策略类

class Strategy {
public:
    virtual void Login () = 0 ;
    virtual ~Strategy () = default ;
} ;

教师登录策略类

class Teacher_Login : public Strategy {
public:
    void Login () {
        cout << endl << "教师登录" << endl ;
    }
} ;

学生登录策略类

class Student_Login : public Strategy {
public:
    void Login () {
        cout << endl << "学生登录" << endl ;
    }
} ;

管理员登陆策略类

class Admin_Login : public Strategy {
public:
    void Login () {
        cout << endl << "管理员登录" << endl ;
    }
} ;

现在已经有了针对同一行为的多种策略,但是还缺少一个 equip 装备这些策略的机器——登录系统

class Login_System {
private:
    Strategy* strategy ;
    ~Login_System () {
        if ( strategy != nullptr )
            delete strategy ;
        strategy = nullptr ;
    }
public:
    Login_System ( Strategy* _strategy = nullptr )
        : strategy ( _strategy )
    {}
    void Login () {
        if ( strategy )
            strategy->Login () ;
        else 
            cout << endl << "登录策略为 nullptr\n" ,
            cout << __FILE__ << "\t 第  " << __LINE__ << "  行" << endl ;
    }
    void Change ( Strategy* _strategy = nullptr ) {
        if ( strategy != nullptr )
            delete strategy ;
        strategy = _strategy ;
    }
} ;

测试的程序结果
这里写图片描述
测试源代码

#include <iostream>
#include <string>
#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 Strategy {
public:
    virtual void Login () = 0 ;
    virtual ~Strategy () = default ;
} ;

class Teacher_Login : public Strategy {
public:
    void Login () {
        cout << endl << "教师登录" << endl ;
    }
} ;

class Student_Login : public Strategy {
public:
    void Login () {
        cout << endl << "学生登录" << endl ;
    }
} ;

class Admin_Login : public Strategy {
public:
    void Login () {
        cout << endl << "管理员登录" << endl ;
    }
} ;

class Login_System {
private:
    Strategy* strategy ;
public:
    Login_System ( Strategy* _strategy = nullptr )
        : strategy ( _strategy )
    {}
    void Login () {
        if ( strategy )
            strategy->Login () ;
        else 
            cout << endl << "登录策略为 nullptr\n" ,
            cout << __FILE__ << "\t 第  " << __LINE__ << "  行" << endl ;
    }
    void Change ( Strategy* _strategy = nullptr ) {
        if ( strategy != nullptr )
            delete strategy ;
        strategy = _strategy ;
    }
    ~Login_System () {
        if ( strategy != nullptr )
            delete strategy ;
        strategy = nullptr ;
    }
} ;

int main () {
    Strategy* for_a_student = new Student_Login () ;
    Login_System YHL ( for_a_student ) ;
    YHL.Login () ;

    Strategy* for_a_teacher = new Teacher_Login () ;
    YHL.Change ( for_a_teacher ) ;
    YHL.Login () ;

    Strategy* for_a_admin = new Admin_Login () ;
    YHL.Change ( for_a_admin ) ;
    YHL.Login () ;

    Strategy* for_a_null = nullptr ;
    YHL.Change ( for_a_null ) ;
    YHL.Login () ;

    cin.get () ;
    cin.ignore ( cin.rdbuf ()->in_avail () ).get () ;
    // cin.ignore ( 1024 , '\n' ) ; 
    return 0 ;
}

2018.5.14
继续理解策略模式
imlk 大佬的指点:

for ( auto &it : 英雄们 ) 
    it.attack () ;

这样一来,每个英雄,对于attack 这个行为,就不需要先判断是什么attack ,可以直接 call 。当多个对象需要进行攻击时,不需要 if (这个英雄的 attack 是冲刺) 或者 if (这个英雄的 attack 是用刀) 或者if (这个英雄的 attack 是用枪) 等等,可以直接调用,而且如果需要改变,只需要把策略替换就行了,很方便。

#include <iostream>
#include <typeinfo>
#include <vector>
#include <list>
#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 ;

class Strategy {
public:
    virtual void Login () = 0 ;
    virtual ~Strategy () = default ;
} ;

class Teacher_Login : public Strategy {
public:
    void Login () {
        cout << endl << "教师登录" << endl ;
    }
} ;

class Student_Login : public Strategy {
public:
    void Login () {
        cout << endl << "学生登录" << endl ;
    }
} ;

class Admin_Login : public Strategy {
public:
    void Login () {
        cout << endl << "管理员登录" << endl ;
    }
} ;

class Login_System {
private:
    Strategy* strategy ;
public:
    explicit Login_System ( Strategy* _strategy = nullptr )
        : strategy ( _strategy )
    {}
    void Call_strategy () {
        if ( strategy )
            strategy->Login () ;
        else 
            cout << endl << "登录策略为 nullptr\n" ,
            cout << __FILE__ << "\t 第  " << __LINE__ << "  行" << endl ;
    }
    void Change ( Strategy* _strategy = nullptr ) {
        if ( strategy != nullptr )
            delete strategy ;
        strategy = _strategy ;
    }
    ~Login_System () {
        if ( strategy != nullptr ) 
            delete strategy ;
        strategy = nullptr ;
    }
    Login_System ( const Login_System& One ) {   
        if ( One.strategy != nullptr ) {
            if ( typeid ( *One.strategy ) == typeid ( Teacher_Login ) ) 
                this->strategy = new Teacher_Login () ;
            else if ( typeid ( *One.strategy ) == typeid ( Student_Login ) )
                this->strategy = new Student_Login () ;
            else 
                this->strategy = new Admin_Login () ;
        }
    }
    Login_System ( Login_System&& One ) : strategy ( One.strategy ) {
        One.strategy = nullptr ;
    }
} ;

int main () {
    std::vector< Login_System > YHL ;
    rep ( i , 0 , 4 ) 
        YHL.emplace_back ( new Teacher_Login () ) ; 
    rep ( i , 0 , 3 ) 
        YHL.emplace_back ( new Student_Login () ) ;
    rep ( i , 0 , 2 )
        YHL.emplace_back ( new Admin_Login () ) ;
    for ( auto &it : YHL )
        it.Call_strategy () ;
    YHL.clear () ;
    return 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值