惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
月光博客
月光博客
AI
AI
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
CXSECURITY Database RSS Feed - CXSecurity.com
WordPress大学
WordPress大学
GbyAI
GbyAI
L
Lohrmann on Cybersecurity
O
OpenAI News
Schneier on Security
Schneier on Security
P
Palo Alto Networks Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Troy Hunt's Blog
V2EX - 技术
V2EX - 技术
W
WeLiveSecurity
L
LINUX DO - 最新话题
人人都是产品经理
人人都是产品经理
S
Security Affairs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
A
Arctic Wolf
Recorded Future
Recorded Future
Microsoft Security Blog
Microsoft Security Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
G
GRAHAM CLULEY
N
Netflix TechBlog - Medium
TaoSecurity Blog
TaoSecurity Blog
C
Check Point Blog
Scott Helme
Scott Helme
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Apple Machine Learning Research
Apple Machine Learning Research
PCI Perspectives
PCI Perspectives
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Vercel News
Vercel News
The Hacker News
The Hacker News
Y
Y Combinator Blog
Latest news
Latest news
SecWiki News
SecWiki News
Hugging Face - Blog
Hugging Face - Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Google Online Security Blog
Google Online Security Blog
Webroot Blog
Webroot Blog
Google DeepMind News
Google DeepMind News
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
Cisco Blogs
博客园_首页
H
Hackread – Cybersecurity News, Data Breaches, AI and More
宝玉的分享
宝玉的分享
L
LINUX DO - 热门话题

博客园 - wjwdive

如何使用git submodule拆分大的git项目 MAC多github账号配置步骤 记录一次flutter boost5.0.2示例调试的过程 【算法】可获得的最大点数问题 使用1panel一键建站 关于混合加密(AES+RSA) C++设计模式汇总 设计模式C++005__桥模式 设计模式C++007__抽象工厂方法模式 设计模式C++004__装饰器模式 设计模式C++003__观察者模式 设计模式C++002__策略模式 使用bundler自动化构建Xcode项目时遇到的问题。 AI图片生成网站 suno AI编曲创作利器 iOS组件化开发之私有库 iOS、Android获取apk公钥MD5信息 阿里图标库批量下载iOS适配的图标 C语言实现回调函数标准方式 swift 自定义tabbar为基本结构的项目 swift 可选类型
设计模式C++001__模板方法
wjwdive · 2024-07-25 · via 博客园 - wjwdive

设计模式C++001__模板方法

“组件协作”模式:

现代软件专业分工之后的第一个结果就是“框架与应用程序的划分”,组件“协作”模式通过晚绑定,来实现框架与应用程序之间的松耦合。

包括:
模版方法,观察者模式,策略模式

1、模板方法模式:

动机:在软件构建过程中,对于一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固定的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
如何在稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求。

从静态编译的角度看,结构化软件设计流程是符合人们的直觉的,先开发好类库或者库函数。然后我们业务开发的程序员来调用Lib库中的函数。
但是一般库函数是稳定的,业务变更频繁,不同业务对2、4步骤实现会千差万别。


图中红色部分是稳定部分,类库一旦写好,核心功能基本确定。整体系统的运行还需要根据具体业务填充蓝色部分2、4步骤。我们做开发时要想到设计模式的原则:
依赖倒置原则,即上层不应该依赖底层。这里1,3,5就是底层实现,2,4所在的Application是上层业务层。那么我们应该1,3,5依赖2,4所在Application。
即细节应该依赖抽象,而不是抽象依赖细节。

在面向开发过程中,由于有多态的特性,或者类似其他语言运行时的支持,例如C++的多态特性,C语言的函数指针,OC的runtime。一些函数的调用关系被放到了运行时才确定。
这样,就可以将一些步骤延迟到子类,或者运行时来做。

这里就引出了早绑定和晚绑定的概念。正是因为有了晚绑定的概念,库和业务程序之间这种跨时间维度的开发交互成为现实。
库的开发人员只需要知道,2,4步骤将来一定会由外部业务开发人员来实现。我只需要开发好1,3,5.并把调用整体流程的框架搭好就行了。

2、早绑定和晚绑定

//C语言中的函数调用,编译期就已经确定好调用关系-----早绑定
#import <stdio.h>
void printHello(){
  printf("Hello, world!");
}

void printGoodBye(){
  printf("Goodby, world!");
}

void doSomeThing(int type){
  if(type == 0){
    printHello();
  }else{
    printGoodbye();
  }
}

//C语言中 运行时才确定好调用关系 ----晚绑定
#import <stdio.h>
void printHello(){
  printf("Hello, world!");
}

void printGoodBye(){
  printf("Goodby, world!");
}

void doSomeThing(int type){
  void (*func)();//声明一个函数指针,
  if(type == 0){
    func = printHello;
  }else{
    func = printGoodbye;
  }
  func();//这个函数调用的指令,不过待调用的函数地址无法硬编码在指令中,只有在运行时读出来。
}

以结构化的程序开发流程为例:

//lib库的开发
//程序库开发人员
class Library{

public:
	void Step1(){
		//...
	}

    void Step3(){
		//...
    }

    void Step5(){
		//...
    }
};
//Application的开发
//应用程序开发人员
class Application{
public:
	bool Step2(){
		//...
    }

    void Step4(){
		//...
    }
};

int main()
{
	Library lib();
	Application app();

	lib.Step1();

	if (app.Step2()){
		lib.Step3();
	}

	for (int i = 0; i < 4; i++){
		app.Step4();
	}

	lib.Step5();

}

面向对象的开发流程

//程序库开发人员
class Library{
public:
	//稳定 template method
    void Run(){
        
        Step1();

        if (Step2()) { //支持变化 ==> 虚函数的多态调用
            Step3(); 
        }

        for (int i = 0; i < 4; i++){
            Step4(); //支持变化 ==> 虚函数的多态调用
        }

        Step5();

    }
	virtual ~Library(){ }

protected:
	
	void Step1() { //稳定
        //.....
    }
	void Step3() {//稳定
        //.....
    }
	void Step5() { //稳定
		//.....
	}

	virtual bool Step2() = 0;//变化
    virtual void Step4() =0; //变化
};

主程序的开发

//应用程序开发人员
class Application : public Library {
protected:
	virtual bool Step2(){
		//... 子类重写实现
    }

    virtual void Step4() {
		//... 子类重写实现
    }
};




int main()
	{
	    Library* pLib=new Application();
	    lib->Run();

		delete pLib;
	}
}

3、模板方法模式的定义:

定义一个操作中的算法骨架(稳定),而将一些步骤(变化)延迟到子类中。Template Method使得子类可以不改变(复用)一个算法的结构即可重定义(override)该算法的某些特定步骤。--GoF

结构:

4、要点:

Template Method模式是一种非常基础的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数多态特性)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
除了可以灵活应对子步骤的变化外,“不要调用我,让我来调用你”的反向控制结构式Template Method的典型应用。
在具体实现方面,被Template Method调用的虚方法可以具有实现,也可以没有任何实现(抽象方法,纯虚方法),但一般不推荐将他们设置为protected方法。