组合模式-C#实现

news/2025/2/12 18:17:12/

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。
组合模式依据树形结构来组合对象,用来表示部分以及整体层次。

意图:将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,
从而使得客户程序与复杂元素的内部结构解耦。

何时使用: 1、您想表示对象的部分-整体层次结构(树形结构)。 
2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。

应用实例: 1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作数也可以是操作数、操作符和另一个操作数。 
2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。

优点: 1、高层模块调用简单。 2、节点自由增加。
缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。

注意事项:定义时为具体类。

组合模式中涉及到三个角色:

抽象构件(Component)角色:这是一个抽象角色,上面实现中Graphics充当这个角色,
它给参加组合的对象定义出了公共的接口及默认行为,可以用来管理所有的子对象(在透明式的组合模式是这样的)。
在安全式的组合模式里,构件角色并不定义出管理子对象的方法,这一定义由树枝结构对象给出。

树叶构件(Leaf)角色:树叶对象时没有下级子对象的对象,上面实现中Line和Circle充当这个角色,定义出参加组合的原始对象的行为

树枝构件(Composite)角色:代表参加组合的有下级子对象的对象,
上面实现中ComplexGraphics充当这个角色,树枝对象给出所有管理子对象的方法实现,如Add、Remove等。

该实例基于WPF实现,直接上代码,下面为三层架构的代码。

一 Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Shapes;namespace 设计模式练习.Model.组合模式
{//画一个圆internal class Circle : Graphics{List<Graphics> graphics = new List<Graphics>();public Circle(string name) : base(name){}//开始绘制public override void Draw(){//绘制图形foreach (var line in graphics){line.Draw();this.Description += $"{line.Name}";}}public void Add(Graphics line){graphics.Add(line);}public void Remove(Graphics line){graphics.Remove(line);}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace 设计模式练习.Model.组合模式
{//图形抽象类public abstract class Graphics{public string Name { get; set; }public string Description { get; set; }protected Graphics(string name){Name = name;}//画图方法public abstract void Draw();}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace 设计模式练习.Model.组合模式
{public class Line : Graphics{//存储多个图形private List<Graphics> points = new List<Graphics>();//复杂图形类public Line(string name) : base(name){}//画图: 由多个点组成的线段public override void Draw(){foreach (Graphics point in points){point.Draw();this.Description += $"画{point.Name},";}}public void Add(Graphics point){points.Add(point);}public void Remove(Graphics point){points.Remove(point);}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace 设计模式练习.Model.组合模式
{//简单图形:点public class Point : Graphics{public Point(string name) : base(name){}//重写父类抽象方法public override void Draw(){this.Description = $"画{Name}";}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Animation;namespace 设计模式练习.Model.组合模式
{//绘制复杂图形public class Rectangle : Graphics{//记录加入的线段List<Graphics> lines = new List<Graphics>();public Rectangle(string name) : base(name){}//开始绘制public override void Draw(){//绘制图形foreach (var line in lines){line.Draw();this.Description += $"{line.Name}";}}public void Add(Graphics line){lines.Add(line);}public void Remove(Graphics line){lines.Remove(line);}}
}

二 View

<Window x:Class="设计模式练习.View.组合模式.Combination"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:设计模式练习.View.组合模式"mc:Ignorable="d"Title="Combination" Height="450" Width="800"><Grid><Grid.RowDefinitions><RowDefinition/><RowDefinition/><RowDefinition/><RowDefinition/></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><Label Grid.Row="0" Grid.Column="0" Content="{Binding Res1}"/><Label Grid.Row="1" Grid.Column="0" Content="{Binding Res2}"/><Label Grid.Row="2" Grid.Column="0" Content="{Binding Res3}"/><Label Grid.Row="3" Grid.Column="0" Content="{Binding Res4}"/><Button Grid.Row="0" Grid.Column="2" Content="画点" Command="{Binding add1Command}"/><Button Grid.Row="1" Grid.Column="2" Content="画线" Command="{Binding add2Command}"/><Button Grid.Row="2" Grid.Column="2" Content="画矩形" Command="{Binding add3Command}"/><Button Grid.Row="3" Grid.Column="2" Content="画圆" Command="{Binding Add4Command}"/><Label Grid.Row="0" Grid.Column="1" Visibility="{Binding A1}"><Label.Content><TextBlock Text="." FontSize="100" VerticalAlignment="Center"/></Label.Content></Label><Label Grid.Row="1" Grid.Column="1" Visibility="{Binding A2}" ><Label.Content><Line X1="10" Y1="20" X2="260" Y2="20" Stroke="Red" StrokeThickness="10"/></Label.Content></Label><Rectangle Grid.Row="2" Grid.Column="1" Fill="Red" Width="100" Height="100" StrokeThickness="3" Visibility="{Binding A3}"/><Ellipse Grid.Row="3" Grid.Column="1" Width="100" Height="100" Fill="Blue" Visibility="{Binding A4}"/></Grid>
</Window>

三 ViewModel

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 设计模式练习.Model.组合模式;namespace 设计模式练习.ViewModel.组合模式
{partial class Combination_ViewModel : ObservableObject{[ObservableProperty]private string res1;[ObservableProperty]private string res2;[ObservableProperty]private string res3;[ObservableProperty]private string res4;[ObservableProperty]private string a1;[ObservableProperty]private string a2;[ObservableProperty]private string a3;[ObservableProperty]private string a4;public Combination_ViewModel(){A1 = "Collapsed";A2 = "Collapsed";A3 = "Collapsed";A4 = "Collapsed";}//画点[RelayCommand]private void add1(){Graphics point = new Point("点1");point.Draw();Res1 = point.Description;A1 = "Visible";}//画线[RelayCommand]private void add2(){Graphics point = new Point("点1");Graphics point2 = new Point("点2");Graphics point3 = new Point("点3");Line line = new Line("线");line.Add(point);line.Add(point2);line.Add(point3);line.Draw();Res2 = line.Description;A2 = "Visible";}//画矩形[RelayCommand]private void add3(){Line line = new Line("线");Line line2 = new Line("线2");Line line3 = new Line("线3");Rectangle rectangle = new Rectangle("矩形");rectangle.Add(line);rectangle.Add(line2);rectangle.Add(line3);rectangle.Draw();Res3 = rectangle.Description;A3 = "Visible";}//画圆[RelayCommand]private void Add4(){Rectangle rectangle = new Rectangle("矩形");Rectangle rectangle2 = new Rectangle("矩形2");Circle circle = new Circle("圆");circle.Add(rectangle);circle.Add(rectangle2);circle.Draw();Res4 = circle.Description;A4 = "Visible";}}
}


http://www.ppmy.cn/news/1381383.html

相关文章

每日一面——成员初始化列表、移动构造和拷贝构造

写前声明&#xff1a;参考链接 C面经、面试宝典 等 ✊✊✊每日一面——成员初始化列表、移动构造和拷贝构造 一、类成员初始化方式&#xff1f;构造函数的执行顺序&#xff1f;为什么用成员初始化列表会快一些&#xff1f;二、final和override关键字三、拷贝初始化和直接初始化…

【力扣白嫖日记】1174.即时食物配送II

前言 练习sql语句&#xff0c;所有题目来自于力扣&#xff08;https://leetcode.cn/problemset/database/&#xff09;的免费数据库练习题。 今日题目&#xff1a; 1174.即时食物配送II 表&#xff1a;Person 列名类型delivery_idintcustomer_idintorder_datedatecustomer_…

MyBatis动态语句 -- trim/choose/when/otherwise标签

1. trim标签 使用trim标签控制条件部分两端是否包含某些字符 prefix属性&#xff1a;指定要动态添加的前缀suffix属性&#xff1a;指定要动态添加的后缀prefixOverrides属性&#xff1a;指定要动态去掉的前缀&#xff0c;使用“|”分隔有可能的多个值suffixOverrides属性&…

【AnaConda/MiniConda/Linux】使用sudo python或切换root管理员conda环境被绕过解决方案

写在前面 部分机型修改环境变量存在风险&#xff0c;可能用于被覆盖而出现大量命令无法找到的情况 可以输入这个解决 export PATH/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin往期相关内容 探索Miniconda3&#xff1a;简单、灵活的Python环境和…

基于Springboot影城管理系统设计与实现

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一、研究背景…

Mybatis-plus手写SQL如何使用条件构造器和分页

Mybatis-plus手写SQL如何使用条件构造器和分页插件 前言&#xff1a;在使用mybatis-plus过程中&#xff0c;使用条件构造器和分页插件非常效率的提升开发速度&#xff0c;但有些业务需要使用连表查询&#xff0c;此时还想使用条件构造器和使用分页时应该如何操作呢&#xff1f…

windows下如何编译tengine

前言: 本文的主要宗旨是使用cygwin在windows下编译tengine, 同时使用tongsuo, 使tengine支持国密SSL. 本文的编译环境为win10专业版. 详细步骤如下. 1, 安装cygwin https://cygwin.com/setup-x86_64.exe 安装步骤比较简单, 主要步骤如下: 下一页在选择站点的时候可以填写清华源…

苹果放弃造车计划 或更加专注AI

近日&#xff0c;据有关消息称苹果公司决定放弃投入数十亿美元的造车项目&#xff0c;2000多名员工将逐步转到人工智能项目。特斯拉CEO马斯克、小米创始人雷军、理想汽车CEO李想、小鹏汽车CEO何小鹏等纷纷在社交平台发言感慨。 从2008年开始&#xff0c;苹果就有了造车野心&…