11.组合模式设计思想
目录介绍
- 01.组合模式基础
- 1.1 组合模式由来
- 1.2 组合模式定义
- 1.3 组合模式场景
- 1.4 组合模式思考
- 1.5 解决的问题
- 02.组合模式实现
- 2.1 罗列一个场景
- 2.2 组合结构
- 2.3 组合基本实现
- 2.4 有哪些注意点
- 03.组合实例演示
- 3.1 需求分析
- 3.2 代码案例实现
- 3.3 是否可以优化
- 3.4 组合设计
- 3.5 演变代码案例
- 04.组合实现方式
- 4.1 组合模式分类
- 4.2 案例分析
- 4.3 透明式组合
- 4.4 安全式组合
- 05.组合模式分析
- 5.1 组合模式优点
- 5.2 组合模式缺点
- 5.3 适用环境
- 5.4 模式拓展
- 5.5 使用建议说明
- 06.外观代理总结
- 6.1 总结一下学习
- 6.2 更多内容推荐
推荐一个好玩网站
一个最纯粹的技术分享网站,打造精品技术编程专栏!编程进阶网
01.组合模式基础
1.0 本博客AI摘要
1.1 组合模式由来
客户代码过多地依赖于对象容器复杂的内部实现结构,对象容器内部实现结构(而非抽象接口)的变化将引起客户代码的频繁变化,带来了代码的维护性、扩展性等弊端。
如何将“客户代码与复杂的对象容器结构”解耦?让对象容器自己来实现自身的复杂结构,从而使得客户代码就像处理简单对象一样来处理复杂的对象容器?
1.2 组合模式定义
定义:将对象以树形结构组织起来,以达成“部分-整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
1.3 组合模式场景
使用场景
- 当需要表示对象的层次结构时,如文件系统或组织结构。更多内容
- 当希望客户端代码能够以一致的方式处理树形结构中的所有对象时。
1.4 组合模式思考
当我们思考组合模式时,以下几个方面值得考虑:
- 对象的层次结构:组合模式适用于具有层次结构的对象集合。我们需要思考对象之间的关系,确定哪些对象可以作为容器对象,哪些对象可以作为叶子对象,以及它们之间的组合方式。
- 统一的接口:组合模式通过定义统一的接口,使得容器对象和叶子对象可以被一致地对待。我们需要思考如何设计这个接口,以便能够在不同层次的对象上进行统一的操作。
- 递归结构:组合模式通常使用递归结构来处理对象的层次关系。我们需要思考如何在递归中遍历和操作对象集合,以实现统一的操作和处理。
- 叶子对象的特殊处理:组合模式中的叶子对象可能需要特殊处理,因为它们没有子对象。我们需要思考如何处理这些叶子对象,以确保它们能够正确地参与到组合结构中。
1.5 解决的问题
主要解决的问题
- 简化树形结构中对象的处理,无论它们是单个对象还是组合对象。
- 解耦客户端代码与复杂元素的内部结构,使得客户端可以统一处理所有类型的节点。更多内容
02.组合模式实现
2.1 罗列一个场景
假设我们有一个文件系统,其中有两种类型的文件:文本文件和文件夹。文本文件是叶子节点,文件夹是组合节点,可以包含其他文件。我们想要使用组合模式来实现文件系统的层次结构,并且提供一个打印文件路径的方法。
2.2 组合结构
组合模式包含如下角色:更多内容
- 组件(Component): 定义了组合中所有对象的通用接口,可以是抽象类或接口。它声明了用于访问和管理子组件的方法,包括添加、删除、获取子组件等。
- 叶子节点(Leaf): 表示组合中的叶子节点对象,叶子节点没有子节点。它实现了组件接口的方法,但通常不包含子组件。
- 复合节点(Composite): 表示组合中的复合对象,复合节点可以包含子节点,可以是叶子节点,也可以是其他复合节点。它实现了组件接口的方法,包括管理子组件的方法。
- 客户端(Client): 通过组件接口与组合结构进行交互,客户端不需要区分叶子节点和复合节点,可以一致地对待整体和部分。
2.3 组合基本实现
定义抽象组件(Component)
public interface File {
// 获取文件名称
String getName();
// 添加子文件
void add(File file);
// 删除子文件
void remove(File file);
// 获取子文件
List<File> getChildren();
// 打印文件路径
void printPath(int space);
}
定义叶子节点(Leaf)
public class TextFile implements File {
private String name;
public TextFile(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public void add(File file) {
throw new UnsupportedOperationException("Text file cannot add child file");
}
@Override
public void remove(File file) {
throw new UnsupportedOperationException("Text file cannot remove child file");
}
@Override
public List<File> getChildren() {
throw new UnsupportedOperationException("Text file has no child file");
}
@Override
public void printPath(int space) {
StringBuilder sp = new StringBuilder();
for (int i = 0; i < space; i++) {
sp.append(" ");
}
System.out.println(sp + name);
}
}
定义组合节点
public class Folder implements File {
private String name;
private List<File> children;
public Folder(String name) {
this.name = name;
children = new ArrayList<>();
}
@Override
public String getName() {
return name;
}
@Override
public void add(File file) {
children.add(file);
}
@Override
public void remove(File file) {
children.remove(file);
}
@Override
public List<File> getChildren() {
return children;
}
@Override
public void printPath(int space) {
StringBuilder sp = new StringBuilder();
for (int i = 0; i < space; i++) {
sp.append(" ");
}
System.out.println(sp + name);
space += 2;
for (File child : children) {
child.printPath(space);
}
}
}
客户端代码
private void test() {
// 创建一个根文件夹,并添加两个文本文件和一个子文件夹
File root = new Folder("root");
root.add(new TextFile("a.txt"));
root.add(new TextFile("b.txt"));
File subFolder = new Folder("subFolder");
root.add(subFolder);
// 在子文件夹中添加两个文本文件
subFolder.add(new TextFile("c.txt"));
subFolder.add(new TextFile("d.txt"));
// 打印根文件夹的路径
root.printPath(0);
}
打印结果如下所示:
root
a.txt
b.txt
subFolder
c.txt
d.txt
2.4 有哪些注意点
在使用组合模式时,有几个注意点需要考虑:
- 抽象构件的一致性:组合模式中,抽象构件定义了组合对象和叶子对象的共同接口。确保所有的组件都遵循相同的接口和行为,以保持一致性。
- 添加和删除子节点的限制:在组合模式中,组合对象可以包含其他组合对象或叶子对象作为子节点。但是,有时可能需要限制添加或删除子节点的操作,以确保组合对象的结构和约束条件得到维护。
- 叶子对象的操作限制:叶子对象是组合模式中的最小单位,它没有子节点。因此,对于叶子对象的操作可能需要进行限制或者抛出异常,以避免不必要的操作。
- 透明性和安全性的权衡:组合模式可以采用透明性或安全性的实现方式。在选择实现方式时,需要权衡透明性和安全性之间的需求。
03.组合实例演示
3.1 需求分析
假设这样的场景:
在电脑E盘有个文件夹,该文件夹下面有很多文件,有视频文件,有音频文件,有图像文件,还有包含视频、音频及图像的文件夹,十分杂乱,现希望将这些杂乱的文件展示出来。更多内容
3.2 代码案例实现
不使用组合模式。注:当然可以一个循环遍历就搞定了,因为这里用的是文件的形式,如果是别的形式呢?所以不要太较真了,只是举例。
private void test() {
MusicFile m1 = new MusicFile("尽头.mp3");
MusicFile m2 = new MusicFile("飘洋过海来看你.mp3");
MusicFile m3 = new MusicFile("曾经的你.mp3");
MusicFile m4 = new MusicFile("take me to your heart.mp3");
VideoFile v1 = new VideoFile("战狼2.mp4");
VideoFile v2 = new VideoFile("理想.avi");
VideoFile v3 = new VideoFile("琅琊榜.avi");
ImageFile i1 = new ImageFile("敦煌.png");
ImageFile i2 = new ImageFile("baby.jpg");
ImageFile i3 = new ImageFile("girl.jpg");
Folder aa = new Folder("aa");
aa.addImage(i3);
Folder bb = new Folder("bb");
bb.addMusic(m4);
bb.addVideo(v3);
Folder top = new Folder("top");
top.addFolder(aa);
top.addFolder(bb);
top.addMusic(m1);
top.addMusic(m2);
top.addMusic(m3);
top.addVideo(v1);
top.addVideo(v2);
top.addImage(i1);
top.addImage(i2);
top.print();
}
public class MusicFile {
private String name;
public MusicFile(String name){
this.name = name;
}
public void print(){
System.out.println(name);
}
}
public class VideoFile {
private String name;
public VideoFile(String name){
this.name = name;
}
public void print(){
System.out.println(name);
}
}
public class ImageFile {
private String name;
public ImageFile(String name){
this.name = name;
}
public void print(){
System.out.println(name);
}
}
public class Folder {
private String name;
//音乐
private List<MusicFile> musicList = new ArrayList<MusicFile>();
//视频
private List<VideoFile> videoList = new ArrayList<VideoFile>();
//图片
private List<ImageFile> imageList = new ArrayList<ImageFile>();
//文件夹
private List<Folder> folderList = new ArrayList<Folder>();
public Folder(String name){
this.name = name;
}
public void addFolder(Folder folder){
folderList.add(folder);
}
public void addImage(ImageFile image){
imageList.add(image);
}
public void addVideo(VideoFile video){
videoList.add(video);
}
public void addMusic(MusicFile music){
musicList.add(music);
}
public void print(){
for (MusicFile music : musicList){
music.print();
}
for (VideoFile video : videoList){
video.print();
}
for(ImageFile image : imageList){
image.print();
}
for (Folder folder : folderList){
folder.print();
}
}
}
3.3 是否可以优化
如果采用上述的形式,有几个缺点:
- 文件夹类Folder的设计和实现都非常复杂,需要定义多个集合存储不同类型的成员,而且需要针对不同的成员提供增加、删除和获取等管理和访问成员的方法,存在大量的冗余代码,系统维护较为困难;
- 由于系统没有提供抽象层,客户端代码必须有区别地对待充当容器的文件夹Folder和充当叶子的MusicFile、ImageFile和VideoFile,无法统一对它们进行处理;
- 系统的灵活性和可扩展性差,如果增加了新的类型的叶子和容器都需要对原有代码进行修改,例如如果需要在系统中增加一种新类型的文本文件TextFile,则必须修改Folder类的源代码,否则无法在文件夹中添加文本文件。
3.4 组合设计
为了让系统具有更好的灵活性和可扩展性,客户端可以一致地对待文件和文件夹,定义一个抽象构件AbstractFile,Folder充当容器构件,MusicFile、VideoFile和ImageFile充当叶子构件。更多内容
3.5 演变代码案例
抽象构件AbstractFile(Component)
public abstract class AbstractFile {
public void add(AbstractFile file) {
throw new UnsupportedOperationException();
}
public void remove(AbstractFile file) {
throw new UnsupportedOperationException();
}
public AbstractFile getChild(int i) {
throw new UnsupportedOperationException();
}
public void print() {
throw new UnsupportedOperationException();
}
}
叶子构件(Leaf)
public class MusicFile extends AbstractFile {
private String name;
public MusicFile(String name) {
this.name = name;
}
public void print() {
System.out.println(name);
}
}
public class VideoFile extends AbstractFile {
private String name;
public VideoFile(String name) {
this.name = name;
}
public void print() {
System.out.println(name);
}
}
public class ImageFile extends AbstractFile {
private String name;
public ImageFile(String name) {
this.name = name;
}
public void print() {
System.out.println(name);
}
}
容器构件(Composite)
public class Folder extends AbstractFile {
private String name;
private List<AbstractFile> files = new ArrayList<AbstractFile>();
public Folder(String name) {
this.name = name;
}
@Override
public void add(AbstractFile file) {
files.add(file);
}
@Override
public void remove(AbstractFile file) {
files.remove(file);
}
@Override
public AbstractFile getChild(int i) {
return files.get(i);
}
@Override
public void print() {
for (AbstractFile file : files) {
file.print();
}
}
}
客户端测试:
private void test() {
AbstractFile m1 = new MusicFile("尽头.mp3");
AbstractFile m2 = new MusicFile("飘洋过海来看你.mp3");
AbstractFile m3 = new MusicFile("曾经的你.mp3");
AbstractFile m4 = new MusicFile("take me to your heart.mp3");
AbstractFile v1 = new VideoFile("战狼2.mp4");
AbstractFile v2 = new VideoFile("理想.avi");
AbstractFile v3 = new VideoFile("琅琊榜.avi");
AbstractFile i1 = new ImageFile("敦煌.png");
AbstractFile i2 = new ImageFile("baby.jpg");
AbstractFile i3 = new ImageFile("girl.jpg");
AbstractFile aa = new Folder("aa");
aa.add(i3);
AbstractFile bb = new Folder("bb");
bb.add(m4);
bb.add(v3);
AbstractFile top = new Folder("top");
top.add(aa);
top.add(bb);
top.add(m1);
top.add(m2);
top.add(m3);
top.add(v1);
top.add(v2);
top.add(i1);
top.add(i2);
top.print();
}
用组合模式提供一个抽象构件后,客户端可以一致对待容器构件和叶子构件,进行统一处理,并且大量减少了冗余,扩展性也很好,新增TextFile无需修改Folder源码,只需修改客户端即可。
当然,这里似乎有点违法“迭代器模式”中讲的“单一职责原则”,的确是,抽象构件不但要管理层次结构,还要执行一些业务操作。
04.组合实现方式
4.1 组合模式分类
组合模式分为透明式的组合模式和安全式的组合模式。这两种类型的主要区别在于抽象构件(Component)角色上的差别。
- 透明式的组合模式:在透明式的组合模式中,由于抽象构件声明了所有子类中的全部方法,所以客户端无须区别树叶对象和树枝对象,对客户端来说是透明的。
- 安全式的组合模式:在安全式的组合模式中,将管理子构件的方法移到树枝构件中,抽象构件只定义树枝构件和树叶构件所共同的方法。避免了透明式的组合模式的空实现或抛异常问题。
4.2 案例分析
案例:用组合模式实现在超市购物后,显示并计算所选商品信息与总价。更多内容
案例说明:张三在超市购物,购物清单如下
- 1号小袋子装了2 包芒果干(单价15.8元),1包薯片(单价9.8元)
- 2号小袋子装了3 包山楂(单价7.8元),2包牛肉脯(单价19.8元)
- 中型袋子装了1号小袋子,1盒巧克力(单价39.8元)
- 大型袋子装了中型袋子,2号小袋子,1箱牛奶(单价79.8元)
大袋子的东西如下:
{
1箱牛奶(单价79.8元)
2号小袋子{
3 包山楂(单价7.8元
2包牛肉脯(单价19.8元)
}
中型袋子:{
1盒巧克力(单价39.8元)
1号小袋子:{
2 包芒果干(单价15.8元)
1包薯片(单价9.8元)
}
}
}
4.3 透明式组合
透明式的组合模式中抽象构件还声明访问和管理子类的接口
组件(Component): 抽象构建角色。定义一个接口用于计算价格,显示商品,并且可以添加子节点。
public interface Article {
/**
* 树枝构件特有的方法: 访问和管理子类的接口 大袋子装小袋子
*/
void add(Article article);
/**
* 计算价格
*/
Double calculation();
/**
* 显示商品
*/
void show();
}
叶子节点(Leaf): 叶子节点对象,叶子节点没有子节点。创建一个商品类,继承抽象角色。
public class Goods implements Article {
/**
* 商品名称
*/
private String name;
/**
* 购买数量
*/
private Integer quantity;
/**
* 商品单价
*/
private Double unitPrice;
public Goods(String name, Integer quantity, Double unitPrice) {
this.name = name;
this.quantity = quantity;
this.unitPrice = unitPrice;
}
/**
* 树枝构件特有的方法
* 在树叶构件中是能空实现或者抛异常
*/
@Override
public void add(Article article) {
}
@Override
public Double calculation() {
return this.unitPrice * this.quantity;
}
@Override
public void show() {
System.out.println(name + ": (数量:" + quantity + ",单价:" + unitPrice + "元)," +
"合计:" + this.unitPrice * this.quantity + "元");
}
}
复合节点(Composite): 创建袋子
/**
* 树枝构件: 袋子
*/
public class Bag implements Article {
/**
* 袋子名字
*/
private String name;
public Bag(String name) {
this.name = name;
}
/**
* 袋子中的商品
*/
private List<Article> bags = new ArrayList<Article>();
/**
* 往袋子中添加袋子或者商品
*/
@Override
public void add(Article article) {
bags.add(article);
}
@Override
public Double calculation() {
AtomicReference<Double> sum = new AtomicReference<>(0.0);
bags.forEach(e -> {
sum.updateAndGet(v -> v + e.calculation());
});
return sum.get();
}
@Override
public void show() {
bags.forEach(Article::show);
}
}
客户端(Client): 通过组件接口与组合结构进行交互。
private void test() {
Article smallOneBag = new Bag("1号小袋子");
smallOneBag.add(new Goods("芒果干", 2, 15.8));
smallOneBag.add(new Goods("薯片", 1, 9.8));
Article smallTwoBag = new Bag("2号小袋子");
smallTwoBag.add(new Goods("山楂", 3, 7.8));
smallTwoBag.add(new Goods("牛肉脯", 2, 19.8));
Article mediumBag = new Bag("中袋子");
mediumBag.add(new Goods("巧克力", 1, 39.8));
mediumBag.add(smallOneBag);
Article BigBag = new Bag("大袋子");
BigBag.add(new Goods("牛奶", 1, 79.8));
BigBag.add(mediumBag);
BigBag.add(smallTwoBag);
System.out.println("打工充选购的商品有:");
BigBag.show();
Double sum = BigBag.calculation();
System.out.println("要支付的总价是:" + sum + "元");
}
以上客户端代码中 new Bag(),new Goods()的引用都是Article,无须区别树叶对象和树枝对象,对客户端来说是透明的,此时Article调用add()是空实现或抛异常的(案例是空实现)。更多内容
4.4 安全式组合
安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成,只定义一些通用的方法。
抽象构件(Component)角色。这里创建定义一个接口用于计算价格,显示商品。
public interface Article {
/**
* 计算价格
*/
Double calculation();
/**
* 显示商品
*/
void show();
}
树叶构件(Leaf)角色
public class Goods implements Article {
/**
* 商品名称
*/
private String name;
/**
* 购买数量
*/
private Integer quantity;
/**
* 商品单价
*/
private Double unitPrice;
public Goods(String name, Integer quantity, Double unitPrice) {
this.name = name;
this.quantity = quantity;
this.unitPrice = unitPrice;
}
@Override
public Double calculation() {
return this.unitPrice * this.quantity;
}
@Override
public void show() {
System.out.println(name + ": (数量:" + quantity + ",单价:" + unitPrice + "元)," +
"合计:" + this.unitPrice * this.quantity + "元");
}
}
树枝构件(Composite)角色 / 中间构件
/**
* 树枝构件: 袋子
*/
public class Bag implements Article {
/**
* 袋子名字
*/
private String name;
public Bag(String name) {
this.name = name;
}
/**
* 袋子中的商品
*/
private List<Article> bags = new ArrayList<Article>();
/**
* 树枝构件特有的方法: 访问和管理子类的接口 大袋子装小袋子
* 往袋子中添加袋子或者商品
*/
public void add(Article article) {
bags.add(article);
}
@Override
public Double calculation() {
AtomicReference<Double> sum = new AtomicReference<>(0.0);
bags.forEach(e -> {
sum.updateAndGet(v -> v + e.calculation());
});
return sum.get();
}
@Override
public void show() {
bags.forEach(Article::show);
}
}
客户端(Client): 通过组件接口与组合结构进行交互。
private void test() {
Bag smallOneBag = new Bag("1号小袋子");
smallOneBag.add(new Goods("芒果干", 2, 15.8));
smallOneBag.add(new Goods("薯片", 1, 9.8));
Bag smallTwoBag = new Bag("2号小袋子");
smallTwoBag.add(new Goods("山楂", 3, 7.8));
smallTwoBag.add(new Goods("牛肉脯", 2, 19.8));
Bag mediumBag = new Bag("中袋子");
mediumBag.add(new Goods("巧克力", 1, 39.8));
mediumBag.add(smallOneBag);
Bag BigBag = new Bag("大袋子");
BigBag.add(new Goods("牛奶", 1, 79.8));
BigBag.add(mediumBag);
BigBag.add(smallTwoBag);
System.out.println("打工充选购的商品有:");
BigBag.show();
Double sum = BigBag.calculation();
System.out.println("要支付的总价是:" + sum + "元");
}
以上客户端代码中 new Bag(),new Goods()的引用都是Bag,Goods,客户端在调用时要知道树叶对象和树枝对象的存在。此时只有Bag才能调用add()。
05.组合模式分析
5.1 组合模式优点
- 使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关系自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。
- 更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。更多内容
5.2 组合模式缺点
- 设计较复杂,需要明确类之间的层次关系;
- 不容易限制容器中的构件;
- 不容易用继承的方法来增加构件的新功能;
5.3 适用环境
在以下情况下可以考虑使用组合模式:
- 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们。
- 在一个使用面向对象语言开发的系统中需要处理一个树形结构。
- 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。
5.4 模式拓展
在实际开发过程中,可以对树叶节点和树枝节点分别进行抽象,通过继承的方式让不同的树叶节点和树枝节点子类来实现行为。
5.5 使用建议说明
在设计时,优先使用接口而非具体类,以提高系统的灵活性和可维护性。更多内容
适用于需要处理复杂树形结构的场景,如文件系统、组织结构等。
06.外观代理总结
6.1 总结一下学习
01.组合模式基础
组合模式定义 :将对象以树形结构组织起来,以达成“部分-整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
主要解决的问题 :1.简化树形结构中对象的处理,无论它们是单个对象还是组合对象。2.解耦客户端代码与复杂元素的内部结构,使得客户端可以统一处理所有类型的节点。
02.组合模式实现
组合模式包含如下角色:
- 组件(Component): 定义了组合中所有对象的通用接口,可以是抽象类或接口。它声明了用于访问和管理子组件的方法,包括添加、删除、获取子组件等。
- 叶子节点(Leaf): 表示组合中的叶子节点对象,叶子节点没有子节点。它实现了组件接口的方法,但通常不包含子组件。
- 复合节点(Composite): 表示组合中的复合对象,复合节点可以包含子节点,可以是叶子节点,也可以是其他复合节点。它实现了组件接口的方法,包括管理子组件的方法。
- 客户端(Client): 通过组件接口与组合结构进行交互,客户端不需要区分叶子节点和复合节点,可以一致地对待整体和部分。
04.组合实现方式
组合模式分为透明式的组合模式和安全式的组合模式。这两种类型的主要区别在于抽象构件(Component)角色上的差别。
- 透明式的组合模式:在透明式的组合模式中,由于抽象构件声明了所有子类中的全部方法,所以客户端无须区别树叶对象和树枝对象,对客户端来说是透明的。
- 安全式的组合模式:在安全式的组合模式中,将管理子构件的方法移到树枝构件中,抽象构件只定义树枝构件和树叶构件所共同的方法。避免了透明式的组合模式的空实现或抛异常问题。
6.2 更多内容推荐
模块 | 描述 | 备注 |
---|---|---|
GitHub | 多个YC系列开源项目,包含Android组件库,以及多个案例 | GitHub |
博客汇总 | 汇聚Java,Android,C/C++,网络协议,算法,编程总结等 | YCBlogs |
设计模式 | 六大设计原则,23种设计模式,设计模式案例,面向对象思想 | 设计模式 |
Java进阶 | 数据设计和原理,面向对象核心思想,IO,异常,线程和并发,JVM | Java高级 |
网络协议 | 网络实际案例,网络原理和分层,Https,网络请求,故障排查 | 网络协议 |
计算机原理 | 计算机组成结构,框架,存储器,CPU设计,内存设计,指令编程原理,异常处理机制,IO操作和原理 | 计算机基础 |
学习C编程 | C语言入门级别系统全面的学习教程,学习三到四个综合案例 | C编程 |
C++编程 | C++语言入门级别系统全面的教学教程,并发编程,核心原理 | C++编程 |
算法实践 | 专栏,数组,链表,栈,队列,树,哈希,递归,查找,排序等 | Leetcode |
Android | 基础入门,开源库解读,性能优化,Framework,方案设计 | Android |
23种设计模式
23种设计模式 & 描述 & 核心作用 | 包括 |
---|---|
创建型模式 提供创建对象用例。能够将软件模块中对象的创建和对象的使用分离 |
工厂模式(Factory Pattern) 抽象工厂模式(Abstract Factory Pattern) 单例模式(Singleton Pattern) 建造者模式(Builder Pattern) 原型模式(Prototype Pattern) |
结构型模式 关注类和对象的组合。描述如何将类或者对象结合在一起形成更大的结构 |
适配器模式(Adapter Pattern) 桥接模式(Bridge Pattern) 过滤器模式(Filter、Criteria Pattern) 组合模式(Composite Pattern) 装饰器模式(Decorator Pattern) 外观模式(Facade Pattern) 享元模式(Flyweight Pattern) 代理模式(Proxy Pattern) |
行为型模式 特别关注对象之间的通信。主要解决的就是“类或对象之间的交互”问题 |
责任链模式(Chain of Responsibility Pattern) 命令模式(Command Pattern) 解释器模式(Interpreter Pattern) 迭代器模式(Iterator Pattern) 中介者模式(Mediator Pattern) 备忘录模式(Memento Pattern) 观察者模式(Observer Pattern) 状态模式(State Pattern) 空对象模式(Null Object Pattern) 策略模式(Strategy Pattern) 模板模式(Template Pattern) 访问者模式(Visitor Pattern) |
6.3 更多内容
- GitHub:https://github.com/yangchong211
- 我的编程网站:https://yccoding.com
- 博客汇总:https://github.com/yangchong211/YCBlogs
- 设计模式专栏:https://github.com/yangchong211/YCDesignBlog
- Java高级进阶专栏:https://github.com/yangchong211/YCJavaBlog
- 网络协议专栏:https://github.com/yangchong211/YCNetwork
- 计算机基础原理专栏:https://github.com/yangchong211/YCComputerBlog