3、结构型模型

结构型模型

代理模式

代理模式的定义
为其他对象提供一种代理以控制这个对象的访问,在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介作用

个人理解:就像是水果商店是水果工厂的代理商,我们去水果商店买水果,然后由水果商店来控制是否把水果工厂的水果卖给我们,卖多少
在这里插入图片描述
注意:我们代理与原服务端必须要有相同的接口,等代理端同意了客户端的请求就可以调用原服务端的接口,去实现这个目的

代理模式
优点:必须有权限验证,不是所有人都能启动我的启动,必须提供用户名和密码

#include <iostream>
using namespace std;

//提供一种代理来控制对其他对象的访问
class AbstraactCommonInterface {
public:
	virtual void run() = 0;

};

//我已经写好的系统
class Mysystem :public AbstraactCommonInterface{
public:
	virtual void run() {
		cout << "系统启动..." << endl;
	}
};

//必须有权限验证,不是所有人都能来启动我的启动,必须提供用户名和密码
class MysystemProxy :public AbstraactCommonInterface {
public:
//接受传入密码与用户
	MysystemProxy(string username,string password) {
		this->mUsername = username;
		this->mPassword = mPassword;
		
	}
	bool checkUsernameAndPassword() {
		if (mUsername == "admin"&&mPassword == "admin") {
			return true;
		}
		return false;
	}
	virtual void run() {
		if (checkUsernameAndPassword()) {
			cout << "用户名和密码正确,验证通过..." << endl;
			this->pSystem->run();//调用系统的启动程序
		}
		else {
			cout << "用户名或密码错误,权限不足...." << endl;
		}
	}
	~MysystemProxy() {
		if (pSystem != NULL) {
			delete pSystem;
		}
	}
public:
	Mysystem* pSystem;//该指针指向系统
	string mUsername;
	string mPassword;
};

void test01() {
	MysystemProxy* proxy = new MysystemProxy("root","admin");
	proxy->run();
}


int main() {
#if 0
	//这样不行。是个人都能启动
	Mysystem* system = new Mysystem;
	system -> run();
#endif
	//调用代理模式
	test01();
	return 0;
}

代理模式的举例

1、上外网
在这里插入图片描述

我们无法直接访问yutube,但是我们可以访问代理服务器,然后代理服务器会将我们的要求传给youtube服务端,然后将我们请求的传给我

优点:

1、能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。

2、客户端可以针对抽象主题角色进行编程,增加和更换代理类无须修改源代码,符合开闭原则,系统具有较好的灵活性和可扩展性。

缺点:

代理实现较为复杂。

装饰模式

装饰模式又叫包装模式,通过一种对客户端透明的方式来扩展对象功能,是继承关系的一种替代

在这里插入图片描述
装饰模式就是把要附加的功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择的、按顺序的使用装饰功能包装对象。
下面就是我们主体是英雄,然后装饰就是各种装备(装备其实就是对英雄的部分属性发生了改变,继承重写),这样只要我们把英雄作为参数传入装备类进行实例化,就像是英雄穿上了装备

#include <iostream>
using namespace std;

//一般情况下,用继承实现类的功能拓展
//装饰模式 可以动态给一个类增加功能

//抽象英雄
class AbstractHero {
public:
	virtual void ShowStatus() = 0;
public:
	int mHp;
	int mMp;
	int mAt;
	int mDf;
};

//具体英雄
class HeroA :public AbstractHero {
public:
	HeroA() {
		mHp = 0;
		mMp = 0;
		mAt = 0;
		mDf = 0;
	}
	virtual void ShowStatus() {
		cout << "血量:" << mHp << endl;
		cout << "魔法:" << mMp << endl;
		cout << "攻击:" << mAt << endl;
		cout << "防御:" << mDf << endl;
	}
};

//英雄穿上某个装饰物 那么他还是个英雄
//装饰物
class AbstractEquipmet : public AbstractHero {
public:
	AbstractEquipmet(AbstractHero* hero) {
		this->pHero = hero;
	}
	virtual void ShowStatus() = 0;
public:
	AbstractHero* pHero;

};

//狂徒
class KuangtuEquipment :public AbstractEquipmet {
public:
	KuangtuEquipment(AbstractHero* hero) :AbstractEquipmet(hero) {}
	//增加额外的功能
	void AddKuangtu() {
		cout << "英雄穿上狂徒之后..." << endl;
		this->mHp = this->pHero->mHp;
		this->mMp = this->pHero->mMp;
		this->mAt = this->pHero->mAt;
		this->mDf = this->pHero->mDf + 30;

		delete this->pHero;
	}
	virtual void ShowStatus() {
		AddKuangtu();
		cout << "血量:" << mHp << endl;
		cout << "魔法:" << mMp << endl;
		cout << "攻击:" << mAt << endl;
		cout << "防御:" << mDf << endl;
	}
};

//无尽
class Wujing : public AbstractEquipmet {
public:
	Wujing(AbstractHero* hero) :AbstractEquipmet(hero) {}
	//增加额外的功能
	void AddWujing() {
		cout << "英雄穿上无尽之后..." << endl;
		this->mHp = this->pHero->mHp;
		this->mMp = this->pHero->mMp;
		this->mAt = this->pHero->mAt + 80;
		this->mDf = this->pHero->mDf;

		delete this->pHero;
	}
	virtual void ShowStatus() {
		AddWujing();
		cout << "血量:" << mHp << endl;
		cout << "魔法:" << mMp << endl;
		cout << "攻击:" << mAt << endl;
		cout << "防御:" << mDf << endl;
	}
};


void test01() {
	AbstractHero* hero = new HeroA;
	hero->ShowStatus();
	cout << "----------------------------" << endl;

	//给裸奔的英雄穿上衣服后
	hero = new KuangtuEquipment(hero);
	hero->ShowStatus();

	cout << "----------------------------" << endl;

	//装备武器
	hero = new Wujing(hero);
	hero->ShowStatus();

}
int main() {
	test01();

	return 0;
}

优点:

1、对于扩展一个对象的功能,装饰模式比继承更加灵活性,不会导致类的个数急剧增加。

2、可以通过一种动态的方式来扩展一个对象的功能,从而实现不同的行为。

3、可以对一个对象进行多次装饰。

4、具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,原有类库代码无须改变,符合“开闭原则”。

缺点:

​ 使用装饰模式进行系统设计时将产生很多小对象,大量小对象的产生势必会占用更多的系统资源,影响程序的性能。

外观模式

如果两个类不必彼此直接通信,那么这两个类就不应该发生直接的相互作用

总结:外观模式就是将复杂的子系统抽象到同一个接口进行管理,外界只需要通过此接口与子类系统进行交换,而不必要直接与复杂的子类系统进行交互

外观模式的案例
根据类图,实现家庭影院外观模式应用。

实现KTV模式:电视打开,灯关掉,音响打开,麦克风打开,dvd打开;

实现游戏模式:电视打开,音响打开,游戏机打开。

我们不需要去一个一个开关去打开,而是直接打开ktv模式直接就好了

#include <bits/stdc++.h>
using namespace std;

//电视机
class Televison {
public:
	void On() {
		cout << "电视机打开..." << endl;
	}
	void Off() {
		cout << "电视机关闭" << endl;
	}
};
//灯
class Light {
public:
	void On() {
		cout << "灯打开..." << endl;
	}
	void Off() {
		cout << "灯关闭" << endl;
	}
};
//音箱
class Audio {
public:
	void On() {
		cout << "音箱打开..." << endl;
	}
	void Off() {
		cout << "音箱关闭" << endl;
	}
};
//麦克风
class Microphone {
public:
	void On() {
		cout << "麦克风打开..." << endl;
	}
	void Off() {
		cout << "麦克风关闭" << endl;
	}
};
//DVD
class DVDPlayer {
public:
	void On() {
		cout << "DVD播放器打开..." << endl;
	}
	void Off() {
		cout << "DVD播放器关闭" << endl;
	}
};
//游戏机
class Gamemachine {
public:
	void On() {
		cout << "游戏机打开..." << endl;
	}
	void Off() {
		cout << "游戏机关闭" << endl;
	}
};

//KTV模式
class KTVModel {
public:
	KTVModel() {
	  //创建开关对象
		pTv = new Televison;
		pLight = new Light;
		pAudio = new Audio;
		pMicrophone = new Microphone;
		pDVD = new DVDPlayer;
	}
	
  // 启动开关
	void OnKtv() {
		pTv->On();
		pLight->Off();
		pAudio->On();
		pMicrophone->On();
		pDVD->On();
	}

	void OffKtv() {
		pTv->Off();
		pLight->On();
		pAudio->Off();
		pMicrophone->Off();
		pDVD->Off();
	}

	~KTVModel() {
		delete pTv;
		delete pLight;
		delete pAudio;
		delete pMicrophone;
		delete pDVD;
	}

public:
	Televison* pTv;
	Light* pLight;
	Audio* pAudio;
	Microphone* pMicrophone;
	DVDPlayer* pDVD;
};

void test01() {
	KTVModel* ktv = new KTVModel;//创建ktv模式对象
	ktv->OnKtv();//打开ktv对象的开关
}


int main() {
	test01();
	system("pause");
	return 0;
}

适配器模式

在这里插入图片描述
将一个5v 与 220 v 的连接在一起

将一个类的接口转换成客户希望的另一个接口。使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作
下面例子就是适配器继承目标的接口,然后将之作为一个类常用函数,组合起来,这个适配器就可以接受两个参数,这样就可以u原来的接口通信

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//适配器模式 就是将已经写好的接口,但是这个接口不符合需求
//将写好的接口转换成目标接口

//这函数我已经写好
struct Myprint{
	void operator()(int v1,int v2)//第一个括号是重载的括号,第二个是传入参数
	 {
		cout << v1 + v2 << endl;
	}
};

//定义目标接口 我要是配偶 适配成什么样的,
//要适配成只能传一个参数的,适配for_each第三个参数的适用
class Target {
public:
	virtual void operator()(int v) = 0;

};

//写适配器,先继承目标接口
class Adapater :public Target {
public:
	Adapater(int param) {
		this->param = param;
	}
	virtual void operator() (int v) {
		print(v,param);
	}
public:
	Myprint print;
	int param;
};

//MyBind2nd,原来param固定的10,现在提供一个方法改
Adapater MyBind2nd(int v) {
	return Adapater(v);
}


int main(void) {
	vector<int> v;
	for (int i = 0; i < 10; i++) {
		v.push_back(i);
	}
	
	//适配器模式的运用
	//for_each()的第三个参数是个带一个参数的函数,但是Myprint需要两个参数
	for_each(v.begin(),v.end(), MyBind2nd(10));

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
结构方程模型(Structural Equation Modeling,简称SEM)是一种统计分析方法,用于探索变量之间的因果关系。在使用SEM进行分析时,需要满足以下数据要求: 1. 变量类型:SEM可以处理多种类型的变量,包括连续型变量、二元变量、有序分类变量和无序分类变量。不同类型的变量需要使用适当的测量方法和模型。 2. 样本容量:SEM对样本容量的要求相对较高,通常需要至少200个样本。较小的样本容量可能导致模型估计不准确或不稳定。 3. 变量测量:SEM要求变量具有可靠和有效的测量。因此,在使用SEM之前,需要进行合适的测量工作,包括编制问卷、设计实验或选择合适的测量工具。 4. 数据分布:SEM通常假设变量服从正态分布。如果数据不符合正态分布,可以尝试进行变换或使用非参数方法。 5. 缺失数据处理:SEM对缺失数据比较敏感,因此需要采用适当的缺失数据处理方法,如删除缺失数据、插补缺失数据或使用半参数方法。 6. 相关性:SEM基于变量之间的协方差矩阵进行分析,因此需要确保变量之间存在一定的相关性。如果变量之间相关性较低,可能无法获得稳定的模型估计结果。 7. 模型识别:SEM要求模型具有良好的识别性,即可以通过观察数据来唯一确定模型参数。模型识别可以通过理论基础、先验知识或模型比较方法来进行验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值