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

本文介绍了一种使用策略模式设计教师、学生及管理员不同登录方式的系统。通过定义抽象策略类及其具体实现类,实现了登录行为的解耦,并可以通过更换策略的方式灵活调整登录方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

设计思路

  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 ;
}
策略模式可以用于实现权限判断。在权限判断中,可以定义一个权限策略接口,其中包含一个判断权限的方法。然后,针对不同的权限需求,可以实现不同的权限策略类,每个类都实现了权限策略接口的方法,用于判断不同的权限情况。在权限判断的上下文中,可以持有一个权限策略的引用,并提供一个执行权限判断的方法。通过设置不同的权限策略,可以实现不同的权限判断逻辑。这样,当需要进行权限判断时,只需要调用上下文类的执行方法,传入相应的参数,即可根据不同的权限策略进行权限判断。这种方式可以实现权限判断的灵活性和可扩展性,使得权限判断的逻辑可以独立于具体的业务逻辑。\[1\]\[3\] #### 引用[.reference_title] - *1* [策略模式和责任链模式](https://blog.youkuaiyun.com/qq_43170213/article/details/120381719)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [设计模式(3) 策略模式 初步实现多种登陆策略](https://blog.youkuaiyun.com/nishisiyuetian/article/details/80295404)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [java中冗余if-else代码块的优化(策略模式法,反射法,其他最新方案)](https://blog.youkuaiyun.com/ITBigGod/article/details/105436512)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值