系统架构技能之设计模式-组合模式

这篇具有很好参考价值的文章主要介绍了系统架构技能之设计模式-组合模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、上篇回顾

我们上篇主要讲述了结构型模式中的外观模式,外观模式作为结构型模式中的一个简单又实用的模式,外观模式通过封装细节来提供大粒度的调用,

直接的好处就是,封装细节,提供了应用写程序的可维护性和易用性。外观模式一般应用在系统架构的服务层中,当我们是多个不同类型的客户端应用程序

时,比如一个系统既可以在通过Web的形式访问,也可以通过客户端应用程序的形式时,可能通过外观模式来提供远程服务,让应用程序进行远程调用,

这样通过外观形式提供服务,那么不管是什么样的客户端都访问一致的外观服务,那么以后就算是我们的应用服务发生变化,那么我们不需要修改没一个客

户端应用的调用,只需要修改相应的外观应用即可。

我们主要是讲述了以下的几种情况,使用外观模式可能更适合:

1、我们在使用第三方类库或者API的时候,我们通过本地的API接口的封装,来完成对第三方API接口的粗粒度外观对象,通过这个外观对象可以

很容易的完成服务的调用。

2、我们在架构设计的过程中,一次的功能访问可能需要同时的调用很多个对象,那么如果我们在服务调用的时候,能够在应用程序调用中一次就

能完成所有要同时调用的对象那该多好啊,外观模式无疑是最好的原则,特别是在分布式应用中,通过远程调用服务,通过外观模式降低应用程序与服务的

交互次数,同时可以降低应用程序的复杂性。

二、摘要

本文将会讲述结构性模式中的另外一个常用的模式-组合模式,我们平时在面向对象的设计中,我想有一个原则经常被提及就是,我们在设计的时候,

对象组合>类的继承,本篇将会将结合简单的实例来说明这方面的优势,并且完成对组合模式的主题思想的掌握。我们这样来简单的理解组合模式,组合模

式就是把一些现有的对象或者元素,经过组合后组成新的对象,新的对象提供内部方法,可以让我们很方便的完成这些元素或者内部对象的访问和操作。我

们也可以把组合对象理解成一个容器,容器提供各种访问其内部对象或者元素的API,我们只需要使用这些方法就可以操作它了。那么对象组合相比继承的

优势有哪些呢?可能具体的优势,也不是一句二句就能表述清楚的,还是我们来看看图形的可视化的描述吧。

系统架构技能之设计模式-组合模式,系统架构,设计模式,组合模式我们这里设计的是持久化服务写到一个基类中,

然后继承自该基类的子类都会拥有内置的持久化方法,可能后续我们又要添加其他的针对某个具体的对象类,有一些个性化的服务,我们通过扩展这个类,

进行继承,这样多重继承后,会有一个很大的问题。子类膨胀的问题,而且一般来说继承的重数达到5层左右的时候,性能上可能就会有一定的瓶颈,。也

不是好的设计的思路。这时候对象组合可能为我们提供了更好的解决方案。基于组合方式的话,可能我们可以这样来做,换个思路:就像我们的一个负责的

对象,可以通过简单的对象来组成的道理差不多,其实。

系统架构技能之设计模式-组合模式,系统架构,设计模式,组合模式通过上图,我们知道了,组合对象可以

看作是一系列简单的对象组合成负责的对象的一个模式,复杂对象可以看作是简单对象的一个容器。这个复杂对象完成了简单对象的封装,通过这个容器完

成对象内部简单对象的访问。

三、本文大纲

a、上篇回顾。

b、摘要。

c、本文大纲。

d、组合模式的特点及使用场景。

e、组合模式的经典实现。

f、组合模式的其他方案。

g、原型模式使用总结。

h、系列进度。

i、下篇预告。

四、组合模式的特点及使用场景

组合模式是将一系列对象组合成树形结构用来表示整体和部分之间的关系,组合模式的主要目的是达到,访问组合对象和访问单个对象具有一致性。这里的组合对象比较特殊,本身他可以是由其他的对象组合而成,同时,这个组合对象又可以是组成更复杂对象的一个部分。我们来举个例子来说明吧,可能更直观。

系统架构技能之设计模式-组合模式,系统架构,设计模式,组合模式这里我们可以理解为一个简单的查询组件可能有要满足

上述的几类查询条件的输入类型,将这个组件作为一个容器,那么同事,这个容器又可以作为另外一个容器的组件来运行,那么我们又可以在分页控件中,

将这个查询组件包含到其中。以为分页提供相应的查询元素的集成。

我们一般在如下场景中使用组合模式比较方便:

1、我们有的时候想用户使用一个复杂对象像使用简单对象一样的方式去访问,并且用户同意使用对象内部的所有的对象时,我们可以考虑使用该模

式。这个怎么理解呢?我们使用复杂对象像使用简单对象一样的方式去访问的话,那么我们可以使用组合对象,我们把这些简单的对象进行组合,用组合对

象进行包装,并且提供相应的操作组合对象内部的方法。结合上图中的例子,我们可以这样理解,我们把查询组件封装成一个用户控件,然后可以在其他的

页面中进行调用。这个时候,我们可能考虑如何分部页面,如何能够动态的维护界面上的控件,是否显示,控件里面显示的文本和值是什么?等等,这些都

是我们可以考虑的元素,那么我们如何来做呢?提供下面的几个方法。我还是给出图来说话吧:

系统架构技能之设计模式-组合模式,系统架构,设计模式,组合模式包含上面的这些元素,那么我们可以通过一些相应的方法来进行访

问内部的元素。我们给出简单的示例代码:

public QueryControl()
{
InitializeComponent();

this.InitControlList();
}

public event EventHandler handler;

private Dictionary<string,Control> _controlList = null;
///
/// 初始化控件信息
///
private void InitControlList()
{
this._controlList = new Dictionary<string,Control>();
}
///
/// 返回界面控件中所有的查询条件控件列表
///
///
public Dictionary<string,Control> GetControls()
{
return this._controlList;
}

///
/// 添加查询控件到界面中
///
///
///
public bool AddControl(string key,Control control)
{
if(this._controlList.ContainsKey(key))
return false;
this._controlList.Add(key,control);

return true;
}

///
/// 移除指定键值的对象
///
///
///
public bool RemoveControl(string key)
{
if (this._controlList.ContainsKey(key))
return false;
this._controlList.Remove(key);

return true;
}

public virtual void OnQuery()
{
if (this.handler != null)
handler(this, new EventArgs());
}

public void Query(object sender, EventArgs e)
{
this.CreateSQL();
this.OnQuery();
}

///
/// 根据选中的条件生成SQL语句
///
private void CreateSQL()
{
throw new NotImplementedException();
}

上面的代码很简单就是给出了基本的思路,并不是完整的功能。我们来看其他的可能会用到组合模式的情况

2、如果有的时候,我们希望用户不了解自己使用的对象有多复杂,并且组合对象可以的内部可以自由的变化和组合,但是不会影响到客户应用程序使用这

个组合对象,如果项目中需要新增一个组合对象的时候,客户调用的程序还是一样,不会因为这个组合对象发生变更而发生变化。组合模式在解决整体和部

分之间的问题应用很广泛,也可以降低系统的复杂度,因为我们可以把复杂的组件看作另一个组件的组成部分来处理。就像上面的查询组件,那么我们可以

把查询组件作为分页组件的一个部分来处理。我这里就不给出示例代码了通过上面的情况,我们可以大概的知道,组合模式的使用场景。下面我们就要结合

实例说明组合模式的用处了。

五、组合模式的经典实现

我们先来看看使用经典的组合模式来实现我们上面说的查询控件吧,看看和其他的方案有什么样的不同,不过大体的思路都是一致的,把其他的对象

进行组合成复杂的对象,然后提供操作内部对象的方法,具体的方式可以很多。我们这里还是以上面的查询组件和分页组件为例来说明具体的实现思路,当

然我这里只是给出核心代码,但不是完整的代码:

我们先给出控件内部的完整定义:

public QueryPanel()
{
InitializeComponent();

this.InitControlList();
}

public event EventHandler handler;

private Dictionary<string,Control> _controlList = null;
///
/// 初始化控件信息
///
private void InitControlList()
{
this._controlList = new Dictionary<string,Control>();
}
///
/// 返回界面控件中所有的查询条件控件列表
///
///
public Dictionary<string,Control> GetControls()
{
return this._controlList;
}

///
/// 添加查询控件到界面中
///
///
///
public bool AddControl(string key,Control control)
{
if(this._controlList.ContainsKey(key))
return false;
this._controlList.Add(key,control);

return true;
}

///
/// 移除指定键值的对象
///
///
///
public bool RemoveControl(string key)
{
if (this._controlList.ContainsKey(key))
return false;
this._controlList.Remove(key);

return true;
}

public virtual void OnQuery()
{
if (this.handler != null)
handler(this, new EventArgs());
}

public void Query(object sender, EventArgs e)
{
this.CreateSQL();
this.OnQuery();
}

///
/// 根据选中的条件生成SQL语句
///
private void CreateSQL()
{
throw new NotImplementedException();
}

public virtual Control this[string key]
{
get
{
return this._controlList[key];
}
set
{
this._controlList[key] = value;
}
}

public virtual IEnumerable GetControlList()
{
if (this._controlList.Count > 0)
{
foreach (Control control in this._controlList.Values)
{
foreach (Control item in control.Controls)
{
yield return control;
}
}
}
}

这时候我们如果想要重写上面的方案,可能有时候我们的查询控件需要基于上面的几个基本的操作方法进行重写,完成自定义的组合对象的操作:

public partial class QueryPanelText : QueryPanel
{
public QueryPanelText()
{
InitializeComponent();
}

public override Control this[string key]
{
get
{
return base.GetControls()[key];
}
set
{
base.GetControls()[key] = value;
}
}

///
/// 获取集合中的所有控件集合
///
///
public override IEnumerable GetControlList()
{
return base.GetControlList();
}
}

当然我上面并没有改变对象的任何行为,这里定义了公共的行为,有的时候我们需要限制一些对象内部对象的某些行为,这时候我们通过继承公共的

对象来重写对象的行为来完成。例如从组合对象衍生出来的某些组合对象,可能不具有父类的某些行为时,我们可以通过重写父类的行为来完成自定义的操

作。

六、组合模式的其他方案

6.1、通过过滤器来改进上述方案。

有的时候,我们可能并不关心对象中的所有的元素,我们只是操作其中的具有同类特征的对象,比如对于上面的查询控件中的对象,我们可能想要获

取设置条件的控件项,或者说我们相应控制文本框或者下拉框的样式或者高度等等,这个时候,我们需要对组合对象内的元素就行筛选。这个时候,我们可

能可以采用过滤器来实现这样的功能。

对于上面的结果,我们可能需要获取界面中所有的文本框,或者下拉框,或者其他类型的控件等,这时候我们可以如下方式来做,通过接口定义,根

据传入的不同的过滤器,返回过滤后的结果集合。我们先定义一个过滤器接口:

public interface ISelectRule
{
bool IsMatch(Control control);
}

我们这里定义一个文本过滤器的实现。

public class TextSelect : ISelectRule
{
#region ISelectRule 成员

public bool IsMatch(System.Windows.Forms.Control control)
{
if (control is System.Windows.Forms.TextBox)
return true;

return false;
}

#endregion
}

我们来看看具体的查询控件内部的获取内部元素的方法:

///
/// 获取集合中的所有控件集合
///
///
public IEnumerable GetControlList(ISelectRule rule)
{
foreach (Control control in base.GetControls().Values)
{
if (rule.IsMatch(control))
yield return control;
}
}

通过上面的几行代码的改进,我们就可以完成对内部的组合对象的改进,这样就可以完成根据不同的查询规则,来返回不同的内部对象集合。

通过上面的迭代器来封装我们的内部组合对象,我们通过迭代器来完成组合对象的过滤。我们还可以通过XML文件来组织我们的对象组合的结构,XML文

件先天性的优势就是结构化的语言,特别适合这样的整体与局部关系的结构,所以我们的组合对象也可以通过XML文件来组织,可以将复杂对象设置为一

个复杂的节点,该节点下包含多个对象时,我们只需要将每个对象设置为一个节点,通过XPath语言完成查询。

6.2XML文件格式的组合模式

使用XML文件来完成组合模式有如下优点:

1、我们有系统提供的类库自动完成对XML文件的操作和访问。

2、XML提供了基于XPath解析的查询语言。

也有一些点,就是操作XML文件,调试起来会比较麻烦,而且进行代码编写和测试是个不太方便的事情。

我们来看看如果我们把上面的获取迭代器的代码,还原成XML文件的格式该如何书写呢?

<?xml version="1.0" encoding="utf-8" ?>

对于上面的XML文件,那么我们如何获取到这个XML文件中的某些类型的节点呢?比如我如何获取到TextBox呢?这时候我们可以使用Xpath语法来进行

选择:

public class XMLSelect
{
string xPath = “/Composite/QueryPanel/TextBox”;
private XmlNodeList list = null;
public XmlNodeList GetNodes()
{
System.Xml.XmlDocument doc = new XmlDocument();
doc.LoadXml(“Composite.xml”);

list = doc.SelectNodes(xPath);

return list;
}

public List GetControls()
{
List listControls = new List();

foreach (XmlNode node in list)
{
System.Windows.Forms.TextBox textBox = new TextBox();
textBox.Name = node.Attributes[“name”].Value.ToString();

listControls.Add(textBox);
}

return listControls;
}
}

基于上面的形式我们也可以完成组合模式的要求,通过上面的讲解,我们应该对组合模式有了一定的了解。

七、组合模式使用总结

通过上面的简单讲解,我们知道了,组合模式意图是通过整体与局部之间的关系,通过树形结构的形式进行组织复杂对象,屏蔽对象内部的细节,对

外展现统一的方式来操作对象,是我们处理更复杂对象的一个手段和方式。本文以查询控件为例,说明了,查询控件内部的组成元素,及如何操作内部的组

成元素,包括添加元素,删除和处理相应事件的Handler,当然组合模式的作用远比这些强大,后面我们肯定会在一些实例代码中运用到组合模式的。组合

模式如果在条件允许的情况下,我们尽量使用组合模式来处理复杂对象,远比通过继承出来的对象来的有效。

由于本人水平有限,加之理解有误,错误之处还请大家批评指出,多谢大伙的支持和关注!

八、系列进度

创建型

1、系统架构技能之设计模式-单件模式

2、系统架构技能之设计模式-工厂模式

3、系统架构技能之设计模式-抽象工厂模式

4、系统架构技能之设计模式-创建者模式

5、系统架构技能之设计模式-原型模式

结构型

1、系统架构技能之设计模式-组合模式

2、系统架构技能之设计模式-外观模式

3、系统架构技能之设计模式-适配器模式

4、系统架构技能之设计模式-桥模式

5、系统架构技能之设计模式-装饰模式

6、系统架构技能之设计模式-享元模式

7、系统架构技能之设计模式-代理模式

行为型

1、系统架构技能之设计模式-命令模式

2、系统架构技能之设计模式-观察者模式

3、系统架构技能之设计模式-策略模式

4、系统架构技能之设计模式-职责模式

5、系统架构技能之设计模式-模板模式

6、系统架构技能之设计模式-中介者模式

7、系统架构技能之设计模式-解释器模式

九、下篇预告

下篇,我们将会讲述结构性模式中的适配器模式,我想大家对适配器模式应该有不少的了解,因为如果我们经常在项目中使用第三方的或者因为旧的系统与新系

统的接口类型不一致,倒置无法进行调用,这时候我们可以通过适配器模式将旧的接口,转化成可以让我们的新系统调用的接口形式,完成调用,很神奇吧!下篇我们

将会进行详细的阐述。

转自:https://www.cnblogs.com/hegezhou_hot/archive/2010/12/06/1898161.html文章来源地址https://www.toymoban.com/news/detail-706049.html

到了这里,关于系统架构技能之设计模式-组合模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【软件架构设计】支持大规模系统的设计模式和原则

    今天,即使是小型初创公司也可能不得不处理数 TB 的数据或构建支持每分钟(甚至一秒钟!)数十万个事件的服务。所谓“规模”,通常是指系统应在短时间内处理的大量请求/数据/事件。 尝试以幼稚的方式实现需要处理大规模的服务,在最坏的情况下注定要失败,或者在最

    2024年02月13日
    浏览(30)
  • 软考 系统架构设计师系列知识点之设计模式(9)

    接前一篇文章:软考 系统架构设计师系列知识点之设计模式(8) 所属章节: 老版(第一版)教材 第7章. 设计模式         第2节. 设计模式实例 相关试题 7. 一组对象以定义良好但是复杂的方式进行通信,产生的相互依赖关系结构混乱且难以理解。采用()模式,用一个特

    2024年02月08日
    浏览(34)
  • 软考 系统架构设计师系列知识点之设计模式(4)

    接前一篇文章:软考 系统架构设计师系列知识点之设计模式(3) 所属章节: 老版(第一版)教材 第7章. 设计模式         第2节. 设计模式实例 3. 行为型模式 行为型模式可以 影响一个系统的状态和行为流 。 通过优化状态和行为流转换和修改的方式,可以简化、优化并且

    2024年02月08日
    浏览(45)
  • 软考 系统架构设计师系列知识点之设计模式(11)

    接前一篇文章:软考 系统架构设计师系列知识点之设计模式(10) 所属章节: 老版(第一版)教材 第7章. 设计模式         第2节. 设计模式实例 相关试题 10. 设计模式按照目的可划分三类,其中,创建型模式是对对象实例化过程的抽象。例如()模式确保一个类只有一个

    2024年02月07日
    浏览(46)
  • 设计模式——组合模式

    组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为“整体—部分”(Part-Whole)模式,它是一种对象结构型模式。 组合模式将

    2024年02月11日
    浏览(55)
  • 设计模式-组合模式

    组合模式可以使用一棵树来表示 组合模式使得用户可以使用一致的方法操作单个对象和组合对象 组合模式又叫部分整体模式,将对象组合成树形结构以表示“部分-整体”的层次结构,可以更好的实现管理操作,部分-整体对象的操作基本一样,但是应该还会有不一样的地方

    2024年02月10日
    浏览(39)
  • 设计模式--组合模式

    某日,小明公司最近接到一个办公管理系统的项目,并且在每个城市都有分部。这属于是很常见的OA系统,只要前期将需求分析完善好,中后期开发维护是不难的。 然而,总部公司使用后觉得很OK,想要其他城市的分公司也执行使用。但是现在的问题是,其他分公司的部门和

    2024年01月21日
    浏览(46)
  • 设计模式——10. 组合模式

    组合模式是一种结构型设计模式,用于将对象组合成树状结构以表示“部分-整体”的层次结构。它允许客户端以一致的方式处理单个对象和组合对象(包含多个对象的容器),使得客户端无需关心它们之间的差异。 组合模式通常涉及两种主要角色: 叶子节点(Leaf):这是组

    2024年02月07日
    浏览(51)
  • 设计模式——组合模式08

    组合模式:把类似对象或方法组合成结构为树状的设计思路。 例如部门之间的关系。 设计模式,一定要敲代码理解 满足开闭原则。叶子结点与非叶子结点都继承或实现同一抽象,只是叶子功能权限少,而非叶子结点需要容器记录子节点。 代码下载

    2024年04月11日
    浏览(37)
  • 设计模式:组合模式

    组合模式是一种结构型设计模式,用于将对象组织成树形结构,以表示“部分-整体”的层次结构。组合模式使得客户端可以统一地处理单个对象和组合对象,而不需要区分它们之间的差异。 在组合模式中,有两种主要类型的对象:叶节点和组合节点。叶节点表示树结构中的

    2024年02月07日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包