策略者模式(代码实践C++/Java/Python)————设计模式学习笔记

文章目录

  • 1 设计目标
  • 2 Java
    • 2.1 涉及知识点
    • 2.2 实现
      • 2.2.1 实现两个接口飞行为和叫行为
      • 2.2.2 实现Duck抽象基类(把行为接口作为类成员)
      • 2.2.3 实现接口飞行为和叫行为的具体行为
      • 2.2.4 具体实现鸭子
      • 2.2.5 模型调用
  • 3 C++(用到了大量C++2.0的知识)
    • 3.1 涉及知识点
    • 3.2 实现
      • 3.2.1 实现飞行为和叫行为接口
      • 3.2.2 实现Duck基类(使用委托/组合,把指向抽象接口类的指针作为类成员)
      • 3.2.3 实现接口类的飞行为和叫行为
      • 3.2.4 实现具体的鸭子行为
      • 3.2.5 具体调用
  • 4 Python实现
    • 4.1 涉及知识点
    • 4.2 实现代码
      • 4.2.1 实现两个接口飞行为和叫行为
      • 4.2.2 实现Duck抽象基类(把行为接口作为类成员)
      • 4.2.3 实现接口飞行为和叫行为的具体行为
      • 4.2.4 具体实现鸭子
      • 4.2.5 模型调用
  • 5 完整代码
  • 6 其他知识阅读(快速入门)

1 设计目标

此篇为实现篇下,如果对策略者模式不熟,可以看知识点篇上。
在这里插入图片描述
实现要求:鸭子共有三种行为,游泳行为(所有鸭子都会),飞行行为(能飞/不能飞/具有火箭动力的飞行),叫声行为(嘎嘎叫/吱吱叫/什么都不会叫),不同具体鸭子(绿头鸭/模型鸭/…)飞行行为和叫声行为可能不一样。

2 Java

2.1 涉及知识点

  • 接口(interface):定义一种方法约束
  • 继承(extend):子类会具有父类的一般特性也会具有自身的特性,提高代码复用性。

区别:

修饰符不同:接口使用interface修饰,继承使用extends修饰。
多继承方式不同:接口支持多继承,继承只支持单继承。
定义方式不同:接口只能定义全局常量和抽象方法,继承可以定义属性、方法、变量、常量等。
作用不同:接口是一种约束,类实现接口就一定要实现它所有的方法;继承是一种扩展,继承了类,它的私有成员以外的成员变量和成员方法子类都将拥有。
  • 组合(委托):把A类作为B类的成员变量,具体实现在A类中,B类对外暴露调用接口,解耦合。
  • 抽象基类:不能实例化,只能作为类模版,子类需要实现起抽象方法。
  • 构造函数:类的初始化方法。

2.2 实现

2.2.1 实现两个接口飞行为和叫行为

public interface FlyBehavior {
    public void fly();
}

public interface QuackBehavior {
    public void quack();
}

2.2.2 实现Duck抽象基类(把行为接口作为类成员)

package com.jiangxue.strategy;

public abstract class Duck {
    //组合(委托):策略类作为抽象基类的成员变量
    QuackBehavior quackBehavior;
    FlyBehavior flyBehavior;
    //定义抽象方法:子类必须要实现
    public abstract void display();
    //调用类成员的方法
    public void performQuack(){
        quackBehavior.quack();;
    }
    public void performFly(){
        flyBehavior.fly();
    }
    //所有子类都有的共有行为
    public void swim(){
        System.out.println("All ducks float, even decoys");
    }
    //setter方法设置鸭子行为(运行时改变行为)
    public void setFlyBehavior(FlyBehavior fb){
        flyBehavior = fb;
    }

    public void setQuackBehavior(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }
}

2.2.3 实现接口飞行为和叫行为的具体行为

  • 具体实现飞行为接口:
public class FlyWithWings implements FlyBehavior{
    @Override
    public void fly(){
        System.out.println("I'm flying");
    }
}

public class FlyNoWay implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("I can't fly");
    }
}

public class FlyRocketPowered implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("I'm fly with rocket!");
    }
}
  • 具体实现叫行为接口:
public class Quack implements QuackBehavior{
    @Override
    public void quack() {
        System.out.println("Quack");
    }
}

public class MuteQuack implements QuackBehavior{
    @Override
    public void quack() {
        System.out.println("<<Silence>>");
    }
}

public class Squeak implements QuackBehavior{
    @Override
    public void quack() {
        System.out.println("Squack");
    }
}

2.2.4 具体实现鸭子

  • 实现绿头鸭
public class MallardDuck extends Duck{
    //重新构造函数
    public MallardDuck(){
        quackBehavior = new Quack();
        flyBehavior = new FlyWithWings();
    }
    public void display(){
        System.out.println("I'm a real Mallard duck");
    }
}

  • 实现模型鸭:
public class ModelDuck extends Duck{
    public ModelDuck(){
        flyBehavior = new FlyNoWay();
        quackBehavior = new Quack();
    }

    @Override
    public void display() {
        System.out.println("I'm a model duck");
    }
}

2.2.5 模型调用

public class Test {

    public static void main(String[] args) {
        //示例1
        Duck mallardDuck = new MallardDuck();
        mallardDuck.performQuack();
        mallardDuck.performFly();
        //示例2
        Duck model = new ModelDuck();
        model.performFly();
        //改变飞行行为
        model.setFlyBehavior(new FlyRocketPowered());
        model.performFly();

;    }
}

3 C++(用到了大量C++2.0的知识)

3.1 涉及知识点

  • 纯虚函数(用于实现接口)【virtua和= 0】:在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。有纯虚函数的类是抽象类,不能生成对象,只能派生。
  • virtual析构函数:当父类指针指向子类对象时,执行释放操作,子类对象也会被释放掉。
  • explicit:该构造函数只能显式调用,禁止隐式转换。
  • &&(右值引用):结合了移动语义和完美转发;可以绑定到临时对象。
    • 移动语义:不复制对象,而只是让新的对象名指向原对象名所指对象,并且将原对象所指的置空。
    • 完美转发:可以撰写接受任意参数的函数模版,并将其转发到其他函数,目标函数会接受与其转发函数所接受的完全相同的参数。
  • std::move(把实参强制转换为右值):无条件地右值类型的强制类型转换;
  • std::forward:仅对绑定到右值的引用实施向右值类型的强制转换。
    • 针对右值引用实施std::move,万能引用实施std::forward
  • 智能指针unique_ptr:独占对象,不允许复制;动态管理分配对象的生命周期。
  • make_unique函数:动态分配指定类型的内存,并返回一个指向分配内存的唯一指针。
  • 子类继承父类的构造:不能直接从初始化列表初始化基类成员,应该使用父类的构造函数。
  • 公有继承:基类的公有成员和保护成员的访问属性在派生类中不变

3.2 实现

3.2.1 实现飞行为和叫行为接口

class QuackBehavior{
public:
    //纯虚函数只有函数的名字而不具备函数的功能,不能被调用,要求任何派生类都要定义自己的实现方法
    //有纯虚函数的类是抽象类,不能生成对象,只能派生。
    virtual void quack() const = 0;
    //virtual析构函数好处:当父类指针指向子类对象时,执行释放操作,子类对象也会被释放掉
    virtual ~QuackBehavior() =default;
};

class FlyBehavior{
public:
    virtual void fly() const = 0;
    virtual ~FlyBehavior() = default;
};

3.2.2 实现Duck基类(使用委托/组合,把指向抽象接口类的指针作为类成员)

#include <memory>
#include "FlyBehavior.h"
#include "QuackBehavior.h"
#include <iostream>

class Duck {
protected:
    //智能指针unique_ptr:独占对象,不允许复制;动态管理分配对象的生命周期
    std::unique_ptr<FlyBehavior> _flyBehavior;
    std::unique_ptr<QuackBehavior> _quackBehavior;
public:
    //explicit表示该构造函数只能显式调用,禁止隐式转换。
    /*
     * 移动语义:不复制对象,而只是让新的对象名指向原对象名所指对象,并且将原对象所指的置空。
     * 完美转发:可以撰写接受任意参数的函数模版,并将其转发到其他函数,目标函数会接受与其转发函数所接受的完全相同的参数。
     * &&(右值引用):结合了移动语义和完美转发;可以绑定到临时对象。
     * std::move(把实参强制转换为右值):无条件地右值类型的强制类型转换;
     * std::forward:仅对绑定到右值的引用实施向右值类型的强制转换。
     * 针对右值引用实施std::move,万能引用实施std::forward
    */
    explicit Duck(std::unique_ptr<FlyBehavior> &&flyBehavior ={},
                  std::unique_ptr<QuackBehavior> &&quackBehavior={})
                  :_flyBehavior(std::move(flyBehavior))
                  ,_quackBehavior(std::move(quackBehavior)){

    }
    //上下文允许在运行时替换策略对象。
    void setFlyBehavior(std::unique_ptr<FlyBehavior>&&flyBehavior){
        _flyBehavior = std::move(flyBehavior);
    }

    void setQuackBehavior(std::unique_ptr<QuackBehavior>&&quackBehavior){
        _quackBehavior = std::move(quackBehavior);
    }
    //执行飞
    void performFly() const{
        _flyBehavior->fly();
    }
    //执行叫
    void performQuack() const{
        _quackBehavior->quack();
    }
    void swim() const{
        std::cout<<"All ducks float, even decoys"<<std::endl;
    }

    virtual void display() const = 0;

};

3.2.3 实现接口类的飞行为和叫行为

  • 实现飞行为:
#include <iostream>
#include "FlyBehavior.h"

//公有继承:基类的公有成员和保护成员的访问属性在派生类中不变
class FlyWithWings: public FlyBehavior{
public:
    void fly() const override{
        std::cout<<"I'm flying"<<std::endl;
    }
};

class FlyNoWay: public FlyBehavior{
public:
    void fly() const override{
        std::cout<<"I can't fly"<<std::endl;
    }
};

class FlyRocketPowered : public FlyBehavior{
public:
    void fly() const override{
        std::cout<<"I'm fly with rocket!"<<std::endl;
    }
};


  • 实现叫行为:
#include "QuackBehavior.h"
#include <iostream>

class Quack: public QuackBehavior{
    void quack() const override{
        std::cout<<"quack"<<std::endl;
    }
};

class MuteQuack : public QuackBehavior{
public:
    void quack() const override{
        std::cout<<"<<Silence>>"<<std::endl;
    }
};

class Squeak: public QuackBehavior{
    void quack() const override{
        std::cout<<"Squack"<<std::endl;
    }
};

3.2.4 实现具体的鸭子行为

  • 绿头鸭
#include "Duck.h"
#include "Quack.h"
#include "FlyWithWings.h"
#include <iostream>

class MallardDuck : public Duck{
public:
    //子类继承父类的构造
    //不能直接从初始化列表初始化基类成员,应该使用父类的构造函数
    explicit MallardDuck(std::unique_ptr<FlyWithWings>&& flyWithWings ={},
                         std::unique_ptr<Quack>&& quack={})
                         : Duck(std::move(flyWithWings), std::move(quack)){

    }
    //虚函数方法重写
    void display() const override{
        std::cout<<"I'm a real Mallard duck"<<std::endl;
    }

};
  • 模型鸭
#include "Duck.h"
#include "FlyNoWay.h"
#include "Quack.h"


class ModelDuck :public Duck{
public:
    explicit ModelDuck(std::unique_ptr<FlyNoWay>&& flyNoWay,
                       std::unique_ptr<Quack>&& quack)
                       : Duck(std::move(flyNoWay), std::move(quack)){

    }
    void display() const override{
        std::cout<<"I'm a model duck"<<std::endl;
    }

};

3.2.5 具体调用

#include "MallardDuck.h"
#include "ModelDuck.h"
#include "FlyRocketPowered.h"

void testCode() {
    //make_unique函数:动态分配指定类型的内存,并返回一个指向分配内存的唯一指针
    MallardDuck mallardDuck(std::make_unique<FlyWithWings>(),
            std::make_unique<Quack>());
    mallardDuck.performQuack();
    mallardDuck.performFly();

    ModelDuck modelDuck(std::make_unique<FlyNoWay>(),
            std::make_unique<Quack>());
    modelDuck.performFly();
    modelDuck.setFlyBehavior(std::make_unique<FlyRocketPowered>());
    modelDuck.performFly();


}

int main() {
    testCode();
    return 0;
}

4 Python实现

4.1 涉及知识点

  • 抽象基类(继承ABC):不能被实例化,只能被继承。
  • 抽象方法(@abstractmethod):继承的子类必须实现的方法。
  • 属性(@property,@flyBehavior.setter):调用时不需要加(),为的是提供更加友好访问类数据的方式。
  • 构造函数(def __init__):初始化类成员变量。
  • 继承(super().__init__):继承父类的属性。
  • from __future__ import annotations:允许你在程序中声明变量或函数的类型,并由编译器或其他工具来检查代码的类型是否正确。有助于提高代码的可读性,并且有助于发现类型错误。

4.2 实现代码

4.2.1 实现两个接口飞行为和叫行为

from abc import ABC, abstractmethod

# 抽象基类
class FlyBehavior(ABC):
    # 抽象方法
    @abstractmethod
    def fly(self):
        pass

class QuackBehavior(ABC):
    @abstractmethod
    def quack(self):
        pass

4.2.2 实现Duck抽象基类(把行为接口作为类成员)

class Duck(ABC):
    def __init__(self, flyBehavior: FlyBehavior, quackBehavior: QuackBehavior) -> None:
        self._flyBehavior = flyBehavior
        self._quackBehavior = quackBehavior

    @abstractmethod
    def perform(self) -> None:
        pass

    def performFly(self) -> None:
        return self._flyBehavior.fly()

    def performQuack(self) -> None:
        return self._quackBehavior.quack()

    @property
    def flyBehavior(self) -> FlyBehavior:
        return self._flyBehavior

    @property
    def quackBehavior(self) -> QuackBehavior:
        return self._quackBehavior

    @flyBehavior.setter
    def flyBehavior(self, fly: FlyBehavior) -> None:
        self._flyBehavior = fly

    @quackBehavior.setter
    def quackBehavior(self, quack: QuackBehavior) -> None:
        self._quackBehavior = quack

    def swim(self) -> None:
        print("All ducks float, even decoys")

4.2.3 实现接口飞行为和叫行为的具体行为

  • 具体实现飞行为接口:
class FlyWithWings(FlyBehavior):
    def fly(self) -> None:
        print("I'm flying")

class FlyNoWay(FlyBehavior):
    def fly(self) -> None:
        print("I can't fly")

class FlyRocketPowered(FlyBehavior):
    def fly(self) -> None:
        print("I'm fly with rocket!")
  • 具体实现叫行为接口:
class Quack(QuackBehavior):
    def quack(self) -> None:
        print("Quack")

class Square(QuackBehavior):
    def quack(self) -> None:
        print("Squack")

class MuteQuack(QuackBehavior):
    def quack(self) -> None:
        print("<<Silence>>")

4.2.4 具体实现鸭子

  • 实现绿头鸭
class ModelDuck(Duck):
    def __init__(self, flyBehavior: FlyNoWay, quackBehavior: Quack) -> None:
        super().__init__(flyBehavior, quackBehavior)
        # 下面的初始化方法,并不能继承父类的属性
        # _flyBehavior = flyBehavior
        # _quackBehavior = quackBehavior

    def perform(self) -> None:
        print("I'm a model duck")

  • 实现模型鸭:
class MallardDuck(Duck):
    def __int__(self, flyBehavior: FlyWithWings, quackBehavior: Quack) -> None:
        super().__init__(flyBehavior, quackBehavior)

    def perform(self) -> None:
        print("I'm a real Mallard duck")

4.2.5 模型调用

# import sys , os
# base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# sys.path.append(base_dir)
# 没有把当前项目加入到PYTHONPATH环境变量

from Strategy.duck import *

if __name__ == "__main__":
    mallardDuck = MallardDuck(FlyWithWings(), Quack())
    mallardDuck.performQuack()
    mallardDuck.performFly()

    modelDuck = ModelDuck(FlyNoWay(), Quack())
    modelDuck.performFly()
    modelDuck.flyBehavior = FlyRocketPowered()
    modelDuck.performFly()

5 完整代码

完整的实现代码,见Gitee仓库。如果对您有用的话,欢迎留下star,谢谢。

6 其他知识阅读(快速入门)

Java快速入门
Python快速入门
深入了解C++2.0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/541714.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

笔记本台式机电脑 “睡眠和休眠”有什么区别,那个更省电

笔记本台式机电脑 Windows 系统里睡眠和休眠有什么区别&#xff0c;睡眠和休眠那个更省电&#xff0c;睡眠和休眠使用那个更好&#xff0c;当不用电脑时&#xff0c;通常有三种方式让电脑休息&#xff1a;关机、睡眠和休眠。关机的定义大家都懂&#xff0c;但睡眠和休眠就容易让…

IEDA 启动项目时出现 java: java.lang.OutOfMemoryError: GC overhead limit exceeded 异常

问题 通过Idea启动项目时&#xff0c;出现java: java.lang.OutOfMemoryError: GC overhead limit exceeded 内存溢出问题&#xff1b; 解决方案 错误是发生在编译阶段&#xff0c;而不是运行阶段&#xff1a; 【1】idea编译Java项目使用的虚拟机和idea软件自身使用的虚拟机是…

APP开发教学:开发同城O2O外卖跑腿系统源码详解

同城O2O外卖跑腿系统&#xff0c;满足了人们对于外卖送餐和生活服务的需求。今天&#xff0c;小编将为您讲解如何开发同城O2O外卖跑腿系统源码。 1.前期准备 首先&#xff0c;我们需要明确系统的功能需求和用户需求&#xff0c;包括外卖订购、配送员接单、支付功能等。其次&am…

SPP论文笔记

这篇论文讨论了在深度卷积网络中引入空间金字塔池化&#xff08;SPP&#xff09;层的方法&#xff0c;以解决传统深度卷积网络需要固定图像尺寸的限制。以下是论文各部分的总结&#xff1a; 1. 引言 论文指出现有的深度卷积神经网络&#xff08;CNN&#xff09;需要固定大小的…

计算机毕业设计Python+Flask电商商品推荐系统 商品评论情感分析 商品可视化 商品爬虫 京东爬虫 淘宝爬虫 机器学习 深度学习 人工智能 知识图谱

一、选题背景与意义 1.国内外研究现状 国外研究现状&#xff1a; 亚马逊&#xff08;Amazon&#xff09;&#xff1a;作为全球最大的电商平台之一&#xff0c;亚马逊在数据挖掘和大数据方面具有丰富的经验。他们利用Spark等大数据技术&#xff0c;构建了一套完善的电商数据挖…

CTF之game1

拿到题目&#xff0c;真不错先玩几把。 对比一下不同分数的包&#xff0c;发现 分数不同时不同的包差距在于 score和 sign 对比sign发现 sign是由 zM **** 构成 再拿一个sign去md5解密和base64解码一下发现 sign zM base64(score) 接着便改一下包把分数改成不可能有…

React Hooks 全解: 常用 Hooks 及使用场景详解

React Hooks 是 React 16.8 版本引入的一项重要特性,它极大地简化和优化了函数组件的开发过程。 React 中常用的 10 个 Hooks,包括 useState、useEffect、useContext、useReducer、useCallback、useMemo、useRef、useLayoutEffect、useImperativeHandle 和 useDebugValue。这些…

Linux的内存管理子系统

大家好&#xff0c;今天给大家介绍Linux的内存管理子系统&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 Linux的内存管理子系统是Linux内核中一个非常重要且复杂的子系统&#…

wangeditor与deaftjs的停止维护,2024编辑器该如何做技术选型(一)

wangeditor暂停维护的声明&#xff1a; wangeditor是国内开发者开发的编辑器&#xff0c;用户也挺多&#xff0c;但是由于作者时间关系&#xff0c;暂停维护。 deaft的弃坑的声明&#xff1a; draft是Facebook开源的&#xff0c;但是也弃坑了&#xff0c;说明设计的时候存在很大…

微服务(基础篇-008-Elasticsearch分布式搜索【上】)

目录 初识elasticsearch&#xff08;1&#xff09; 了解ES&#xff08;1.1&#xff09; 倒排索引&#xff08;1.2&#xff09; es的一些概念&#xff08;1.3&#xff09; 安装es、kibana&#xff08;1.4&#xff09; ik分词器&#xff08;1.5&#xff09; ik分词器的拓展…

抽样调查方法

抽样方法是指从总体中选择一部分样本的方法。在进行统计研究时&#xff0c;往往无法对整个总体进行分析&#xff0c;而只能通过对样本的研究来推断总体的特征。因此&#xff0c;选择合适的抽样方法非常重要&#xff0c;它直接影响到研究结果的准确性和可靠性。抽样方法主要分为…

YOLOv5目标检测优化点(添加小目标头检测)

文章目录 1、前言2、如何计算参数3、YOLOv5小目标改进-13.1、结构文件3.2、结构图3.3、参数对比3.3.1、yolov5l.yaml 解析表3.3.2、 yolov5l-4P.yaml 解析表 4、YOLOv5小目标改进-24.1、结构文件4.2、结构图 5、YOLOv5小目标改进-35.1、结构文件 6、YOLOv5小目标改进-46.1、结构…

KDTree索引(K近邻搜索,半径R内近邻搜索)——PCL

K近邻搜索&#xff08;K Nearest Neighbors&#xff09; K近邻搜索是一种基于点数量的搜索方法&#xff0c;它会找到指定点附近最接近的K个邻居点。K近邻搜索中的K值是一个参数&#xff0c;您需要指定要搜索的邻居数量。该方法适用于需要查找固定数量邻居点的情况&#xff0c;…

如何将三方库集成到hap包中——通过IDE集成cmak构建方式的C/C++三方库

简介 cmake构建方式是开源三方库的主流构建方式。DevEco Studio目前以支持cmake的构建方式。本文将通过在IDE上适配cJSON三方库为例讲来解如何在IDE上集成cmake构建方式得三方库。 创建工程 在开发进行三方库适配以及napi接口开发前&#xff0c;我们需要创建一个三方库对应的…

给你的AppImage创建桌面快捷方式

原文链接 https://www.cnblogs.com/HGNET/p/16396589.html 运行环境:Ubuntu 22.04 LTS 1.首先准备好AppImage文件并放在一个你知道的地方 2.打开终端&#xff0c;在/usr/share/applications下新建APP.desktop文件&#xff08;APP可以改成你的应用名称&#xff09; cd /usr/s…

如何对图像进行聚类

文章来源&#xff1a;https://medium.com/voxel51/how-to-cluster-images-6e09bdff7361 2024 年 4 月 10 日 使用 FiftyOne、Scikit-learn和特征嵌入 在 2024 年深度学习的计算密集型环境中&#xff0c;集群一词最常出现在讨论 GPU 集群时--高度优化的矩阵乘法机器的大规模集…

谈谈我的软考高级考证之路(系统架构设计师篇)

系统架构设计师备考资料请移步 2023年软考高级系统架构设计师视频教程&#xff0c;推荐下载&#xff01;获取。 备考总体策略 • 总体策略&#xff1a;刷视频记笔记刷真题 • 备考时间&#xff1a;建议报完名之后&#xff0c;开始备考&#xff0c;大致2-3个月&#xff08;基础…

最优算法100例之45-不用循环乘法求1-n的和

专栏主页&#xff1a;计算机专业基础知识总结&#xff08;适用于期末复习考研刷题求职面试&#xff09;系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句。不能用循…

JS - BOM(浏览器对象模型)

BOM 浏览器对象模型 BOM可以使我们通过JS来操作浏览器 在BOM中为我们提供了一组对象&#xff0c;用来完成对浏览器的操作 BOM对象 BOM&#xff08;Browser Object Model&#xff09;是指浏览器对象模型&#xff0c;它提供了与浏览器窗口进行交互的对象和方法。BOM包括一些核…

数据库系统概论(超详解!!!)第四节 数据库安全性

问题的提出&#xff1a; 数据库的一大特点是数据可以共享 数据共享必然带来数据库的安全性问题 数据库系统中的数据共享不能是无条件的共享。 1.数据库的安全概述 数据库的安全性是指保护数据库以防止不合法使用所造成的数据泄露、更改或破坏 。 系统安全保护措施是否有效…