目录
在一个系统中,一个对象可能与不同的对象相关,以下是不同的关系:
程序类之间的“依赖”关系主要体现出的是一种使用关系,对于两个相对独立的对象, 当一个对象负 责构造另一个对象的实例,或者当一个对象依赖于另一个对象所提供的服务时,这两个对象之间主要体现为依赖关系。
在类型的设计中,依赖关系主要体现在目标类型的对象(实例),作为当前类型方法的局部对象或 者方法的参数类型。
- class Book{}; // 书籍
- class Food{}; // 食物
- class Human // 人类
- {
- public:
- void Read(Book book);
- void Eat(Food food);
- };
- ///
- class Notebook_computer //笔记本计算机
- {
- };
- class desktop_computer //台式计算机
- {
- private:
- string cup;
- int Memory;
- int ssdist; //Solid state disk
- };
- class Student
- {
- public:
- void Study_Programming(Notebook_computer compute); //学习编程
- void Study_Programming(desktop_computer compute);
- void Study_Programming(Book book); //
- };
对于两个相互独立的对象,当对象A与另一个对象B存在固定的对应关系时,这两个对象之间为关 联关系。关联关系是依赖关系的特例。

在类型的设计中,关联关系主要体现在目标类型的指针或引用,作为当前类型的属性成员。没有整 体和部分的关系,只是有关系而已。
- class Book{}; // 书籍
- class Person
- {
- private:
- Book *ptr;// 弱关联
- public:
- Person():ptr(nullptr) {}
- Person(Book *p):ptr(p) {}
- ~Person() {}
- void SetBook(Book *p) { ptr = p;}
- void Study()
- {
- if(Ptr != nullptr)
- {
- cout<<"看一会书 ... "<
- }else
- {
- cout<<"没有书可以看 ... "<
- }
- }
- };
- // 人对象与书籍对象没有整体和部分的关系,只是有关系而已。
- class Student
- {
- Book &_book ;// 强关联
- public:
- Student() {} // error;
- Student(Book bk):_book(bk) {} // error;
- Student(Book &book):_book(book){} // ok;
- Student() {}
- };
- // 学生对象与书籍对象没有整体和部分的关系,只是有关系而已
- class Dog;
- class Master // 狗主
- {
- Dog *pdog;
- public:
- };
- class Dog
- {
- Mastrer *pm;
- };
- // 主人对象与狗对象没有整体和部分的关系,只是有关系而已。
如果Employee类所代表的物理事物与TimeCard类所代表的物理事物存在组成或者构成关系,则此 时的关联就演变为聚合(松散的包含)或者组合(较强的构成)关系。
关联与聚合

在概念上,它们都是对象实例间的一种静态关系,都是在类的抽象层次上的定义,并且最终都可以通过对象的属性来体现。但它们差别是,聚合关系所涉及的两个类型的对象,在现实世界中的含义有明显的has - a (有一个)的语义,能够区分哪个是整体,哪个是部分,而关联所涉及的对象之间没有这种语义,即分不出整体和部分的关系。用...来组成。
- class Point // 点
- {
- private:
- float _x;
- float _y;
- public:
- Point():_x(0.0),_y(0.0) {}
- Point(float x,float y):_x(x),_y(y) {}
- Point(const Point &p):_x(p._x),_y(p._y) // 按位拷贝 inline 函数
- {}
- Point & operator=(const Point &p) // 按位赋值 inline 函数
- {
- if(this != &p)
- {
- _x = p._x;
- _y = p._y;
- }
- return *this;
- }
- ~Point() {}
- float & pointX() { return _x;}
- const float & pointX() const { return _x;}
- float & pointY() { return _y;}
- const float & pointY() const { return _y;}
- };
- class Circle
- {
- private:
- Point _center; // 圆心
- float _radius; // 半径
- };
- //此时整体与部分之间是可分离的,它们可以具有各自的生命周期,
- //部分可以属于多个整体对象,也可以为多个整体对象共享。
- class Circle
- {
- private:
- Point *pCenter;
- float _radius;
- };
组合
当对象A是对象B的属性时,称对象B包含对象A。意味着 "用...来实现,用...来构造"
相比于聚合,组合是一种耦合度更强的关联关系。存在组合关系的类表示“整体-部分”的关联关系,“整 体”负责“部分”的生命周期,他们之间是共生共死的;并且“部分”单独存在时没有任何意义。

在下图的例子中,People与Soul、Body之间是组合关系,当人的生命周期开始时,必须同时有灵 魂和肉体;当人的生命周期结束时,灵魂肉体随之消亡;无论是灵魂还是肉体,都不能单独存在,他们 必须作为人的组成部分存在。
对应的类型设计:
一个类中包含了另一个类的对象作为属性成员,即在类中含有类类型的数据成员 。
- class Soul{};
- class Body{};
- class People
- {
- Soul _soul;
- Body _body;
- //组合关系中的成员变量一般会在构造方法中赋值
- public:
- People(Soul soul, Body body):_soul(soul),_body(_body)
- {
- }
- public:
- void study(){
- cout<<" 学习要用灵魂"<
getName()< - }
- void eat(){
- cout<<"吃饭用身体:"<
getName()< - }
- };
类型的组合:
对象线段是用两个点对象来实现:点与线的组合
示例:
- class Point // 点
- {
- private:
- float _x;
- float _y;
- protected:
- Point():_x(0.0),_y(0.0) {}
- Point(float x,float y):_x(x),_y(y) {}
- Point(const Point &) = default; // 按位拷贝 inline 函数
- public:
- Point & operator=(const Point &) = default; // 按位赋值 inline 函数
- ~Point() {}
- float & pointX() { return _x;}
- const float & pointX() const { return _x;}
- float & pointY() { return _y;}
- const float & pointY() const { return _y;}
- };
- class Line // 线
- {
- private:
- Point _start;
- Point _end;
- float _length;
- float distance()
- {
- float xd = _start.pointX() - _end.pointX();
- float yd = _start.pointY() - _end.pointY();
- _length = sqrt(xd*dx + yd*yd);
- }
- public:
- Line():_length(0) {}
- Line(const Point &a,const Point &b):_start(a),_end(b)
- {
- distance();
- }
- Line(const Line &) = default;
- Line & operator=(const Line &) = default;
- ~Line() {}
- float length() const
- {
- return _length;
- }
- const Point & get_Start()const { return _start;}
- const Point & get_End() const { return _end;}
- void set_Start(const Point &a)
- {
- _start = s;
- distance();
- }
- void set_End(const Point &b)
- {
- _end = b;
- distance();
- }
- };
- int main()
- {
- Point a(1,2),b(5,5);
- Line s(a,b);
- cout<
length()< - return 0;
- }
发一个可应用于多个软件的文件加密模块,该模块可以对文件中的数据进行加密并将加密之后的数 据存储在一个新文件中,具体的流程包括三个部分,分别是读取源文件、加密、保存加密之后的文件, 其中,读取文件和保存文件使用流来实现,加密操作通过求模运算实现。这三个操作相对独立,为了实 现代码的独立重用,让设计更符合单一职责原则,这三个操作的业务代码封装在三个不同的类中。
现使用外观模式设计该文件加密模块。
- class ReaderFile
- {
- public:
- string Read(const string& filename)
- {
- cout << "读取文件,获取明文:";
- ifstream ifile;
- char ch;
- std::string src;
- ifile.open(filename, ios::in);
- if (!ifile.is_open())
- {
- cout << "文件不存在!" << endl;
- return src;
- }
- while (!ifile.eof())
- {
- ifile.get(ch);
- src.push_back(ch); // src+=ch;
- }
- cout << src << endl;
- ifile.close();
- return src;
- }
- };
- class Encryptor //加密器 CipherMachine // 密码机
- {
- public:
- string Encrypt(const string& plaintext)
- {
- cout << "数据加密,将明文转换为密文:";
- std::string es;
- for (auto& x : plaintext)
- {
- char c = x;
- if (isalpha(c))
- {
- c = ((c + 5) % 26 + 'a');
- }
- es += c;
- }
- cout << es << endl;
- return es;
- }
- };
- class WriterFile
- {
- public:
- void Write(const string& filename, const string& ciphertext)
- {
- cout << "保存密文,写入文件。" << endl;
- ofstream ofile;
- ofile.open(filename);
- if (!ofile.is_open())
- {
- cout << "文件不存在" << endl;
- return;
- }
- for (auto& x : ciphertext)
- {
- ofile.put(x);
- }
- ofile.close();
- return;
- }
- };
-
- // EncryptFacade.cs
- class EncryptFacade
- {
- //维持对其他对象的引用
- private:
- ReaderFile reader;
- Encryptor encrypt;
- WriterFile writer;
- public:
- EncryptFacade() {}
- //调用其他对象的业务方法
- void FileEncrypt(string fileNameSrc, string fileNameDes)
- {
- string plainStr = reader.Read(fileNameSrc);
- string encryptStr = encrypt.Encrypt(plainStr);
- writer.Write(fileNameDes, encryptStr);
- }
- };
- int main()
- {
- EncryptFacade ef;
- ef.FileEncrypt("src.txt", "des.txt");
- return 0;
- }
-
相关阅读:
【Tomcat】Tomcat 运行原理
K-近邻算法分类和回归
实现分布式锁SchedulerLock
T02 ExtractSubject 项目开发总结
vue通过span-method合并列之后,合并列显示在中间位置,根据鼠标滑动跟随展示
DxO PureRAW:赋予RAW图像生命,打造非凡视觉体验 mac/win版
1.初识jQuery
linux软硬连接
《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(17)-Fiddler如何充当第三者,再识AutoResponder标签-下篇
react d3使用循环显示多个地图
-
原文地址:https://blog.csdn.net/weixin_59179454/article/details/127796350