目录
一、前言
二、结构型设计模式
1、组合模式
1.1、基本组成
1.2、适用场景
1.3、示例
1.3.1、Component接口
1.3.2、Leaf类表示文件
1.3.3、Composite类表示文件夹
1.3.4、客户端
2、享元模式
2.1、基本组成
2.2、示例
2.2.1、享元接口 Flyweight
2.2.2、享元类 ConcreteFlyweight
2.2.3、享元工厂 FlyweightFactory
2.2.4、客户端
三、总结
本文将介绍结构型设计模式中的组合模式、享元模式。
组合模式是一种设计模式,它允许我们将对象组织成树状结构,从而能够以统一的方式处理单个对象和组合对象。这个模式是一种结构型设计模式,它特别适用于处理具有层次结构的对象,例如树形结构、文件系统、菜单系统等。
组合模式的核心思想是将对象构建成树形结构,使得单个对象和组合对象都能够通过相同的接口进行操作。这个模式包含以下主要角色:
Component(组件):是组合模式中所有对象的抽象基类或接口,它声明了一些公共方法,这些方法可以被叶子对象和组合对象共享。
Leaf(叶子):是组合中的叶子节点,它实现了Component接口并代表了树的最底层结构,叶子对象没有子节点。
Composite(组合):是组合中的组合节点,它也实现了Component接口,但它可以包含其他Component对象,形成了树状结构。
组合模式在以下情况下特别有用:
当你需要表示对象的层次结构,其中对象可以是单个对象或组合对象,且客户端代码需要统一地处理它们时,组合模式就派上用场了。
当你希望客户端代码无需区分单个对象和组合对象,而是统一地对待它们时,组合模式可以简化代码。
当你希望能够以递归的方式遍历整个树形结构时,组合模式非常适用。
假设我们要构建一个文件系统的模型,其中有文件和文件夹,我们可以使用组合模式来表示它。
public interface FileSystemComponent {
void printName();
}
public class File implements FileSystemComponent {
private String name;
public File(String name) {
this.name = name;
}
@Override
public void printName() {
System.out.println("File: " + name);
}
}
import java.util.ArrayList;
import java.util.List;
public class Folder implements FileSystemComponent {
private String name;
private List children = new ArrayList<>();
public Folder(String name) {
this.name = name;
}
public void addComponent(FileSystemComponent component) {
children.add(component);
}
@Override
public void printName() {
System.out.println("Folder: " + name);
for (FileSystemComponent component : children) {
component.printName();
}
}
}
public class Main {
public static void main(String[] args) {
Folder root = new Folder("Root");
Folder documents = new Folder("Documents");
Folder pictures = new Folder("Pictures");
File file1 = new File("Document1.txt");
File file2 = new File("Picture1.jpg");
documents.addComponent(file1);
pictures.addComponent(file2);
root.addComponent(documents);
root.addComponent(pictures);
root.printName();
}
}
享元模式(Flyweight Pattern)是一种结构型设计模式,其主要目的是通过共享对象来减小内存或计算开销,特别适用于大量相似对象的场景。享元模式通过共享尽可能多的相似对象来减少内存使用,提高性能。
享元(Flyweight)代表共享的对象。享元对象包含内部状态(intrinsic state)和外部状态(extrinsic state)。内部状态是对象的不变部分,它可以被多个对象共享。外部状态是对象的可变部分,它在对象创建后可以被修改。
享元工厂(Flyweight Factory):负责创建和管理享元对象。它维护一个享元池(Flyweight Pool)来存储已经创建的享元对象,以确保相同的享元对象可以被多次共享。
下面我们通过一个简单的Java代码示例来演示享元模式的实现。假设我们要创建一个文字编辑器,需要大量的字符对象,但字符的外部状态(例如字体、大小、颜色)可能会变化,而字符的内部状态(例如字符的Unicode码)是不变的,我们可以使用享元模式来优化内存的使用。
Flyweight
public interface Flyweight {
void print(String fontName, int fontSize, String color);
}
2.2.2、
享元类 ConcreteFlyweight
public class ConcreteFlyweight implements Flyweight {
private char character; // 内部状态,字符的Unicode码
public ConcreteFlyweight(char character) {
this.character = character;
}
@Override
public void print(String fontName, int fontSize, String color) {
// 处理外部状态并打印字符
System.out.println("Character: " + character +
", Font: " + fontName +
", Size: " + fontSize +
", Color: " + color);
}
}
2.2.3、
享元工厂 FlyweightFactory
import java.util.HashMap;
import java.util.Map;
public class FlyweightFactory {
private Map flyweights = new HashMap<>();
public Flyweight getFlyweight(char character) {
if (!flyweights.containsKey(character)) {
flyweights.put(character, new ConcreteFlyweight(character));
}
return flyweights.get(character);
}
}
2.2.4、客户端
public class Main {
public static void main(String[] args) {
FlyweightFactory factory = new FlyweightFactory();
Flyweight charA = factory.getFlyweight('A');
Flyweight charB = factory.getFlyweight('B');
Flyweight charC = factory.getFlyweight('C');
charA.print("Arial", 12, "Red");
charB.print("Times New Roman", 14, "Blue");
charC.print("Arial", 12, "Red");
}
}
组合模式和享元模式都是结构型设计模式,用于管理对象之间的关系和提高系统的灵活性和性能。
组合模式主要关注构建具有层次结构的对象,使得客户端可以以一致的方式处理单个对象和组合对象。
享元模式主要关注减小内存开销,通过共享内部状态来避免重复创建相似对象,从而提高性能。
组合模式适用于需要构建树状结构的场景,而享元模式适用于需要大量相似对象的场景。
两者的关键差异在于目标:组合模式关注对象的结构,而享元模式关注对象的共享。根据应用需求,选择合适的模式可以提高代码的可维护性和性能。