Skip to content

结构型

适配器模式(Adapter)

将一个类的接口转换成客户端希望的另一个接口。符合接口隔离原则依赖倒置原则

  • Java代码演示
java
public interface TFCard {
    String readTF();

    void writeTF(String tf);
}
java
public class TFCardImpl implements TFCard {
    @Override
    public String readTF() {
        return "TFCard read msg: hello world TFCard";
    }

    @Override
    public void writeTF(String tf) {
        System.out.println("TFCard write msg: " + tf);
    }
}
java
public interface SDCard {
    String readSD();

    void writeSD(String sd);
}
java
public class SDCardImpl implements SDCard{
    @Override
    public String readSD() {
        return "SDCard read msg: hello world SDCard";
    }

    @Override
    public void writeSD(String sd) {
        System.out.println("SDCard write msg: " + sd);
    }
}
java
public class SDAdapterTF implements SDCard{
    //声明适配器类
    private TFCard tfCard;

    public SDAdapterTF(TFCard tfCard) {
        this.tfCard = tfCard;
    }

    @Override
    public String readSD() {
        System.out.println("adapter read TFCard");
        return tfCard.readTF();
    }

    @Override
    public void writeSD(String sd) {
        System.out.println("adapter write TFCard");
        tfCard.writeTF(sd);
    }
}
java
public class Computer {
    public String readSD(SDCard sdCard) {
        if (sdCard == null) {throw new NullPointerException("sdCard is null");}
        return sdCard.readSD();
    }
}
java
/**
 * 适配器 对象适配器 比 类适配器更好
 * 符合合成复用原则
 * 注意:还有一个适配器模式是接口适配器模式。当不希望实现一个接口中所有的方法时,
 * 可以创建一个抽象类Adapter ,实现所有方法。而此时我们只需要继承该抽象类即可。

 * 应用场景: 以前开发的 满足 新开发的功能需求 但是接口不一致
 *          使用第三方库 但是接口定义和自己要求的接口不一致
 */
public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer();
        String msg1 = computer.readSD(new SDCardImpl());
        System.out.println(msg1);

        System.out.println("===================");


        String msg2 = computer.readSD(new SDAdapterTF(new TFCardImpl()));
        System.out.println(msg2);
    }
}
  • Cpp代码演示
cpp
#include <iostream>
#include <string>

// TFCard接口
class TFCard {
public:
    virtual std::string readTF() = 0;
    virtual void writeTF(const std::string& tf) = 0;
    virtual ~TFCard() {} // 虚析构函数,确保正确释放派生类对象
};

// TFCard接口实现
class TFCardImpl : public TFCard {
public:
    std::string readTF() override {
        return "TFCard read msg: hello world TFCard";
    }

    void writeTF(const std::string& tf) override {
        std::cout << "TFCard write msg: " << tf << std::endl;
    }
};

// SDCard接口
class SDCard {
public:
    virtual std::string readSD() = 0;
    virtual void writeSD(const std::string& sd) = 0;
    virtual ~SDCard() {} // 虚析构函数,确保正确释放派生类对象
};

// SDCard接口实现
class SDCardImpl : public SDCard {
public:
    std::string readSD() override {
        return "SDCard read msg: hello world SDCard";
    }

    void writeSD(const std::string& sd) override {
        std::cout << "SDCard write msg: " << sd << std::endl;
    }
};

// SDCard适配器,适配TFCard到SDCard
class SDAdapterTF : public SDCard {
private:
    TFCard* tfCard; // 使用指针,避免对象切割

public:
    SDAdapterTF(TFCard* tfCard) : tfCard(tfCard) {}

    std::string readSD() override {
        std::cout << "adapter read TFCard" << std::endl;
        return tfCard->readTF();
    }

    void writeSD(const std::string& sd) override {
        std::cout << "adapter write TFCard" << std::endl;
        tfCard->writeTF(sd);
    }
};

// 电脑类
class Computer {
public:
    std::string readSD(SDCard* sdCard) {
        if (sdCard == nullptr) {
            throw std::runtime_error("sdCard is null");
        }
        return sdCard->readSD();
    }
};

int main() {
    Computer computer;
    std::string msg1 = computer.readSD(new SDCardImpl());
    std::cout << msg1 << std::endl;

    std::cout << "===================" << std::endl;

    std::string msg2 = computer.readSD(new SDAdapterTF(new TFCardImpl()));
    std::cout << msg2 << std::endl;

    // 记得释放动态分配的对象,防止内存泄漏
    delete new SDCardImpl();
    delete new TFCardImpl();
    delete new SDAdapterTF(new TFCardImpl());

    return 0;
}

桥接模式(Bridge)

将抽象部分与实现部分分离,使它们可以独立变化。符合开放封闭原则

  • Java代码演示
java
public interface VideoFile {
    void  decode(String filename);
}
java
public class RmvbFile implements VideoFile {
    @Override
    public void decode(String filename) {
        System.out.println("rmvb file decoded" + filename);
    }
}
java
public class AviFile implements VideoFile {
    @Override
    public void decode(String filename) {
        System.out.println("avi file decoded" + filename);
    }
}
java
public abstract class OperatingSystem {
    protected VideoFile videoFile;

    public OperatingSystem(VideoFile videoFile) {
        this.videoFile = videoFile;
    }

    public abstract void play(String fileName);
}
java
public class Mac extends OperatingSystem{
    public Mac(VideoFile videoFile) {
        super(videoFile);
    }

    @Override
    public void play(String fileName) {
        videoFile.decode(fileName);
    }
}
java
public class Windows extends OperatingSystem{
    public Windows(VideoFile videoFile) {
        super(videoFile);
    }

    @Override
    public void play(String fileName) {
        videoFile.decode(fileName);
    }
}
java
//桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统
//如:如果现在还有一种视频文件类型wmv,
// 我们只需要再定义一个类实现VideoFile接口即可,其他类不需要发生变化。

//实现细节对客户透明
public class Client {
    public static void main(String[] args) {
        OperatingSystem system1 = new Mac(new AviFile());

        system1.play("地球online");
    }
}
  • Cpp代码演示
cpp
#ifndef VIDEOFILE_H
#define VIDEOFILE_H
#include <string>


class VideoFile {
public:
    virtual ~VideoFile() = default;
    virtual void decode(const std::string& fileName) = 0;
};
cpp
#include "VideoFile.h"
#include <iostream>

class RmvbFile : public VideoFile {
public:
    void decode(const std::string& fileName) override {
        std::cout << "rmvb file decoded " << fileName << std::endl;
    }
};

class AviFile : public VideoFile {
public:
    void decode(const std::string& fileName) override {
        std::cout << "avi file decoded " << fileName << std::endl;
    }
};
cpp
#ifndef OPERATINGSYSTEM_H
#define OPERATINGSYSTEM_H



#include <memory>
#include "VideoFile.h"

class OperatingSystem {
protected:
    std::unique_ptr<VideoFile> videoFile;

public:
    OperatingSystem(std::unique_ptr<VideoFile> video_file) : videoFile(std::move(video_file)) {}
    virtual ~OperatingSystem() = default; // 重要的虚析构函数

    virtual void play(const std::string& fileName) = 0;
};


#endif //OPERATINGSYSTEM_H
cpp
#include "OperatingSystem.h"
class Windows : public OperatingSystem {
public:
    Windows(std::unique_ptr<VideoFile> video_file) : OperatingSystem(std::move(video_file)) {}

    void play(const std::string& fileName) override {
        videoFile->decode(fileName);
    }
};

class Mac : public OperatingSystem {
public:
    Mac(std::unique_ptr<VideoFile> video_file) : OperatingSystem(std::move(video_file)) {}

    void play(const std::string& fileName) override {
        videoFile->decode(fileName);
    }
};
cpp
#include "OperatingSystem.cpp"
#include "VideoFile.cpp"
int main() {
    std::unique_ptr<VideoFile> aviFile = std::make_unique<AviFile>();
    Mac mac(std::move(aviFile)); // 使用 std::move 转移所有权

    mac.play("test");

    std::unique_ptr<VideoFile> rmvbFile = std::make_unique<RmvbFile>();
    Windows windows(std::move(rmvbFile));
    windows.play("test2");

    return 0;
}

组合模式(Composite)

将对象组合成树形结构以表示部分-整体层次结构。符合合成复用原则开放封闭原则

  • Java代码演示
java
public abstract class MenuComponent {
    protected String name;
    protected int level;

    //添加子菜单
    public void add(MenuComponent component) {
        throw new UnsupportedOperationException();
    }

    public void remove(MenuComponent component) {
        throw new UnsupportedOperationException();
    }

    public MenuComponent getChild(int level) {
        throw new UnsupportedOperationException();
    }

    public String getName() {
        return name;
    }

    public abstract void print();
}
java
public class MenuItem extends MenuComponent{
    public MenuItem(String name,int level) {
        this.level = level;
        this.name = name;
    }

    @Override
    public void print() {
        for (int i = 0; i < level; i++) {
            System.out.print("--");
        }
        System.out.println(name);
    }
}
java
public class Menu extends MenuComponent {
    private List<MenuComponent> menuComponents = new ArrayList<MenuComponent>();

    public Menu(String name, int Level) {
        this.name = name;
        this.level = Level;
    }

    @Override
    public void print() {
        for (int i = 0; i < level; i++) {
            System.out.print("--");
        }

        System.out.println(name);
        for (MenuComponent menuComponent : menuComponents) {
            menuComponent.print();
        }
    }

    @Override
    public void remove(MenuComponent component) {
        menuComponents.remove(component);
    }

    @Override
    public void add(MenuComponent component) {
        menuComponents.add(component);
    }

    @Override
    public MenuComponent getChild(int level) {
        return menuComponents.get(level);
    }
}
java
public class Client {
    public static void main(String[] args) {
        MenuComponent menu1 = new Menu("菜单管理",2);
        menu1.add(new MenuItem("页面访问",3));
        menu1.add(new MenuItem("展开菜单",3));
        menu1.add(new MenuItem("编辑菜单",3));


        MenuComponent menu2 = new Menu("权限管理",2);
        menu2.add(new MenuItem("页面访问",3));
        menu2.add(new MenuItem("展开菜单",3));
        menu2.add(new MenuItem("编辑菜单",3));

        MenuComponent menu3 = new Menu("角色管理",2);
        menu3.add(new MenuItem("页面访问",3));
        menu3.add(new MenuItem("展开菜单",3));
        menu3.add(new MenuItem("编辑菜单",3));

        MenuComponent menu = new Menu("系统管理", 1);
        menu.add(menu1);
        menu.add(menu2);
        menu.add(menu3);

        menu.print();
    }
}

优点 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码。 在组合模式中增加新的树枝节点和叶子节点都很方便,无须对现有类库进行任何修改,符合开闭原则。 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子节点和树枝节点的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。

使用场景 组合模式正是应树形结构而生,所以组合模式的使用场景就是出现树形结构的地方。比如:文件目录显示,多级目录呈现等树形结构数据的操作。

透明组合模式

透明组合模式中,抽象根节点角色中声明了所有用于管理成员对象的方法,比如在示例中 MenuComponent 声明了 add、remove 、getChild 方法,这样做的好处是确保所有的构件类都有相同的接口。透明组合模式也是组合模式的标准形式。

透明组合模式的缺点是不够安全,因为叶子对象和容器对象在本质上是有区别的,叶子对象不可能有下一个层次的对象,即不可能包含成员对象,因此为其提供 add()、remove() 等方法是没有意义的,这在编译阶段不会出错,但在运行阶段如果调用这些方法可能会出错(如果没有提供相应的错误处理代码)

安全组合模式

在安全组合模式中,在抽象构件角色中没有声明任何用于管理成员对象的方法,而是在树枝节点 Menu 类中声明并实现这些方法。安全组合模式的缺点是不够透明,因为叶子构件和容器构件具有不同的方法,且容器构件中那些用于管理成员对象的方法没有在抽象构件类中定义,因此客户端不能完全针对抽象编程,必须有区别地对待叶子构件和容器构件。

  • Cpp代码演示
cpp
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <stdexcept>

class MenuComponent {
protected:
    std::string name;
    int level;

public:
    MenuComponent(const std::string& name, int level) : name(name), level(level) {}
    virtual ~MenuComponent() = default; // 重要的虚析构函数

    virtual void add(std::shared_ptr<MenuComponent> component) {
        throw std::runtime_error("UnsupportedOperationException");
    }

    virtual void remove(std::shared_ptr<MenuComponent> component) {
        throw std::runtime_error("UnsupportedOperationException");
    }

    virtual std::shared_ptr<MenuComponent> getChild(int index) {
        throw std::runtime_error("UnsupportedOperationException");
    }

    std::string getName() const {
        return name;
    }

    virtual void print() = 0;
};

class MenuItem : public MenuComponent {
public:
    MenuItem(const std::string& name, int level) : MenuComponent(name, level) {}

    void print() override {
        for (int i = 0; i < level; i++) {
            std::cout << "--";
        }
        std::cout << name << std::endl;
    }
};

class Menu : public MenuComponent {
private:
    std::vector<std::shared_ptr<MenuComponent>> menuComponents;

public:
    Menu(const std::string& name, int level) : MenuComponent(name, level) {}

    void print() override {
        for (int i = 0; i < level; i++) {
            std::cout << "--";
        }
        std::cout << name << std::endl;
        for (const auto& menuComponent : menuComponents) {
            menuComponent->print();
        }
    }

    void remove(std::shared_ptr<MenuComponent> component) override {
        for (auto it = menuComponents.begin(); it != menuComponents.end(); ++it) {
            if (*it == component) {
                menuComponents.erase(it);
                return; // Important: Exit after removing the element
            }
        }
    }


    void add(std::shared_ptr<MenuComponent> component) override {
        menuComponents.push_back(component);
    }

    std::shared_ptr<MenuComponent> getChild(int index) override {
        if (index >= 0 && index < menuComponents.size()) {
            return menuComponents[index];
        }
        return nullptr; // Or throw an exception for out-of-bounds access
    }
};

int main() {
    auto menu1 = std::make_shared<Menu>("菜单管理", 2);
    menu1->add(std::make_shared<MenuItem>("页面访问", 3));
    menu1->add(std::make_shared<MenuItem>("展开菜单", 3));
    menu1->add(std::make_shared<MenuItem>("编辑菜单", 3));

    auto menu2 = std::make_shared<Menu>("权限管理", 2);
    menu2->add(std::make_shared<MenuItem>("页面访问", 3));
    menu2->add(std::make_shared<MenuItem>("展开菜单", 3));
    menu2->add(std::make_shared<MenuItem>("编辑菜单", 3));

    auto menu3 = std::make_shared<Menu>("角色管理", 2);
    menu3->add(std::make_shared<MenuItem>("页面访问", 3));
    menu3->add(std::make_shared<MenuItem>("展开菜单", 3));
    menu3->add(std::make_shared<MenuItem>("编辑菜单", 3));

    auto menu = std::make_shared<Menu>("系统管理", 1);
    menu->add(menu1);
    menu->add(menu2);
    menu->add(menu3);

    menu->print();

    return 0;
}

装饰器模式(Decorator)

动态地给一个对象添加一些额外的职责。符合开放封闭原则

动态附加责任 vs. 静态附加责任(继承)

  • 动态附加责任(装饰器模式): 装饰器模式允许在运行时动态地组合不同的装饰器,从而灵活地添加或删除功能。 就像上面的例子,你可以随意添加培根和鸡蛋,顺序和数量都可以改变。 这种组合是动态的,在程序运行时决定的。

  • 静态附加责任(继承): 继承是在编译时确定的,一旦定义了一个子类,它就继承了父类的所有属性和方法,并且无法在运行时改变。 如果你使用继承来实现类似的功能,你需要创建很多子类,例如 FiredNoodlesWithEggAndBaconFiredNoodlesWithBaconFiredRiceWithEgg 等。 每种组合都需要一个单独的类,这会导致类的数量爆炸式增长,而且不够灵活。

  • Java代码演示

java
public abstract class FastFood {
    private float price;
    private String desc;

    public FastFood(float price, String desc) {
        this.price = price;
        this.desc = desc;
    }

    public abstract float cost();


    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}
java
public abstract class Garnish extends FastFood{
    private FastFood fastFood;

    public FastFood getFastFood() {
        return fastFood;
    }

    public void setFastFood(FastFood fastFood) {
        this.fastFood = fastFood;
    }

    public Garnish(FastFood fastFood, float price, String desc) {
        super(price, desc);
        this.fastFood = fastFood;
    }
}
java
public class Bacon extends Garnish{

    public Bacon(FastFood fastFood) {
        super(fastFood,2,"培根");
    }

    @Override
    public float cost() {
        return getPrice() + getFastFood().cost();
    }

    @Override
    public String getDesc() {
        return super.getDesc() + getFastFood().getDesc();
    }
}
public class Egg extends Garnish{
    public Egg(FastFood fastFood) {
        super(fastFood,1,"鸡蛋");
    }

    @Override
    public float cost() {
        return getPrice() + getFastFood().cost();
    }


    @Override
    public String getDesc() {
        return super.getDesc() + getFastFood().getDesc();
    }
}
public class FiredNoodles extends FastFood{
    public FiredNoodles() {
        super(10,"炒面");
    }

    @Override
    public float cost() {
        return getPrice();
    }
}
public class FiredRice extends FastFood{
    public FiredRice() {
        super(10, "炒饭");
    }

    @Override
    public float cost() {
        return getPrice();
    }
}
java
//继承是静态的附加责任,装饰者则是动态的附加责任。
//装饰类和被装饰类可以独立发展,不会相互耦合,
// 装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
//当对象的功能要求可以动态地添加,也可以再动态地撤销时

public class Client {
    public static void main(String[] args) {
        FastFood fastFood = new FiredNoodles();

        fastFood = new Egg(fastFood);

        fastFood = new Bacon(fastFood);
        fastFood = new Bacon(fastFood);

        System.out.println(fastFood.getDesc() + " "+ fastFood.cost());
    }
}
  • Cpp代码演示
cpp
#include <iostream>
#include <string>
#include <memory>

// 快餐抽象类
class FastFood {
protected:
    float price;
    std::string desc;

public:
    FastFood(float price, const std::string& desc) : price(price), desc(desc) {}
    virtual ~FastFood() = default; // 虚析构函数

    virtual float cost() = 0;

    float getPrice() const {
        return price;
    }

    void setPrice(float price) {
        this->price = price;
    }

    std::string getDesc() const {
        return desc;
    }

    void setDesc(const std::string& desc) {
        this->desc = desc;
    }
};

// 装饰器抽象类
class Garnish : public FastFood {
protected:
    std::shared_ptr<FastFood> fastFood;

public:
    Garnish(std::shared_ptr<FastFood> fastFood, float price, const std::string& desc)
        : FastFood(price, desc), fastFood(fastFood) {}

    std::shared_ptr<FastFood> getFastFood() const {
        return fastFood;
    }

    void setFastFood(std::shared_ptr<FastFood> fastFood) {
        this->fastFood = fastFood;
    }
};

// 培根装饰器
class Bacon : public Garnish {
public:
    Bacon(std::shared_ptr<FastFood> fastFood) : Garnish(fastFood, 2.0f, "培根") {}

    float cost() override {
        return getPrice() + fastFood->cost();
    }

    std::string getDesc() override {
        return desc + " " + fastFood->getDesc(); // 添加空格,使描述更清晰
    }
};

// 鸡蛋装饰器
class Egg : public Garnish {
public:
    Egg(std::shared_ptr<FastFood> fastFood) : Garnish(fastFood, 1.0f, "鸡蛋") {}

    float cost() override {
        return getPrice() + fastFood->cost();
    }

    std::string getDesc() override {
        return desc + " " + fastFood->getDesc(); // 添加空格,使描述更清晰
    }
};

// 炒面
class FiredNoodles : public FastFood {
public:
    FiredNoodles() : FastFood(10.0f, "炒面") {}

    float cost() override {
        return getPrice();
    }
};

// 炒饭
class FiredRice : public FastFood {
public:
    FiredRice() : FastFood(10.0f, "炒饭") {}

    float cost() override {
        return getPrice();
    }
};

int main() {
    std::shared_ptr<FastFood> fastFood = std::make_shared<FiredNoodles>();

    fastFood = std::make_shared<Egg>(fastFood);
    fastFood = std::make_shared<Bacon>(fastFood);
    fastFood = std::make_shared<Bacon>(fastFood);

    std::cout << fastFood->getDesc() << " " << fastFood->cost() << std::endl;

    return 0;
}

外观模式(Facade)

为子系统中的一组接口提供一个统一的高层接口,使得子系统更易使用。符合单一职责原则最少知识原则

  • Java代码演示
java
public class AirCondition {
    public void on() {
        System.out.println("AirCondition on");
    }

    public void off() {
        System.out.println("AirCondition off");
    }
}
public class Light {
    public void on() {
        System.out.println("Light on");
    }
    public void off() {
        System.out.println("Light off");
    }
}
public class TV {
    public void on() {
        System.out.println("TV is on");
    }
    public void off() {
        System.out.println("TV is off");
    }
}
java
public class SmartAppliances {
    private Light light;
    private TV tv;
    private AirCondition airCondition;

    public SmartAppliances() {
        light = new Light();
        tv = new TV();
        airCondition = new AirCondition();
    }

    public void say(String message) {
        if(message.contains("on")) {on();}
        else if (message.contains("off")) {off();}
        else {System.out.println("What can i say");}
    }

    public void on() {
        light.on();
        tv.on();
        airCondition.on();
    }

    public void off() {
        light.off();
        tv.off();
        airCondition.off();
    }
}
java
/**
 * 外观模式
 * 优点
 * 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
 * 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
 *
 * 缺点 不符合开闭原则,修改很麻烦
 */
public class Client {
    public static void main(String[] args) {
        SmartAppliances facade = new SmartAppliances();

        facade.say("on all");

        System.out.println("==========");

        facade.say("off all");
    }
}
  • Cpp代码演示
cpp
#include <iostream>
#include <string>

// 空调
class AirCondition {
public:
    void on() {
        std::cout << "AirCondition on" << std::endl;
    }

    void off() {
        std::cout << "AirCondition off" << std::endl;
    }
};

// 灯
class Light {
public:
    void on() {
        std::cout << "Light on" << std::endl;
    }

    void off() {
        std::cout << "Light off" << std::endl;
    }
};

// 电视
class TV {
public:
    void on() {
        std::cout << "TV is on" << std::endl;
    }

    void off() {
        std::cout << "TV is off" << std::endl;
    }
};

// 智能家电外观类
class SmartAppliances {
private:
    Light light;
    TV tv;
    AirCondition airCondition;

public:
    SmartAppliances() : light(), tv(), airCondition() {} // 使用初始化列表

    void say(const std::string& message) {
        if (message.find("on") != std::string::npos) {
            on();
        } else if (message.find("off") != std::string::npos) {
            off();
        } else {
            std::cout << "What can i say" << std::endl;
        }
    }

    void on() {
        light.on();
        tv.on();
        airCondition.on();
    }

    void off() {
        light.off();
        tv.off();
        airCondition.off();
    }
};

int main() {
    SmartAppliances facade;

    facade.say("on all");

    std::cout << "==========" << std::endl;

    facade.say("off all");

    return 0;
}

享元模式(Flyweight)

使用共享对象来有效地支持大量的细粒度对象。符合单一职责原则合成复用原则

  • Java代码演示
java
import java.util.HashMap;
import java.util.Map;

// 享元接口
interface Flyweight {
    void operation(String extrinsicState);
}

// 具体享元类
class ConcreteFlyweight implements Flyweight {
    private String intrinsicState;

    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    @Override
    public void operation(String extrinsicState) {
        System.out.println("Intrinsic State: " + intrinsicState + ", Extrinsic State: " + extrinsicState);
    }
}

// 享元工厂
class FlyweightFactory {
    private Map<String, Flyweight> flyweights = new HashMap<>();

    public Flyweight getFlyweight(String intrinsicState) {
        if (!flyweights.containsKey(intrinsicState)) {
            flyweights.put(intrinsicState, new ConcreteFlyweight(intrinsicState));
        }
        return flyweights.get(intrinsicState);
    }
}

// 客户端代码
public class FlyweightPatternDemo {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();
        
        // 创建享元对象,只有内在状态是共享的
        Flyweight flyweight1 = factory.getFlyweight("A");
        Flyweight flyweight2 = factory.getFlyweight("B");
        Flyweight flyweight3 = factory.getFlyweight("A");

        // 不同的外部状态传递给享元对象
        flyweight1.operation("First call");
        flyweight2.operation("Second call");
        flyweight3.operation("Third call");
        
        // flyweight1 和 flyweight3 共享内在状态 "A"
    }
}
  • Cpp代码演示
cpp
#include <iostream>
#include <unordered_map>
#include <memory>

// 享元接口
class Flyweight {
public:
    virtual void operation(const std::string& extrinsicState) = 0;
    virtual ~Flyweight() = default;
};

// 具体享元类
class ConcreteFlyweight : public Flyweight {
private:
    std::string intrinsicState;

public:
    ConcreteFlyweight(const std::string& state) : intrinsicState(state) {}
    
    void operation(const std::string& extrinsicState) override {
        std::cout << "Intrinsic State: " << intrinsicState 
                  << ", Extrinsic State: " << extrinsicState << std::endl;
    }
};

// 享元工厂
class FlyweightFactory {
private:
    std::unordered_map<std::string, std::shared_ptr<Flyweight>> flyweights;

public:
    std::shared_ptr<Flyweight> getFlyweight(const std::string& intrinsicState) {
        if (flyweights.find(intrinsicState) == flyweights.end()) {
            flyweights[intrinsicState] = std::make_shared<ConcreteFlyweight>(intrinsicState);
        }
        return flyweights[intrinsicState];
    }
};

// 客户端代码
int main() {
    FlyweightFactory factory;

    // 创建享元对象,只有内在状态是共享的
    auto flyweight1 = factory.getFlyweight("A");
    auto flyweight2 = factory.getFlyweight("B");
    auto flyweight3 = factory.getFlyweight("A");

    // 不同的外部状态传递给享元对象
    flyweight1->operation("First call");
    flyweight2->operation("Second call");
    flyweight3->operation("Third call");
    
    // flyweight1 和 flyweight3 共享内在状态 "A"
}

代理模式(Proxy)

为其他对象提供一种代理以控制对这个对象的访问。符合依赖倒置原则

  • Java代码演示
java
// Subject接口
interface Subject {
    void request();
}

// 真实主题类
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Handling request");
    }
}

// 代理类
class Proxy implements Subject {
    private RealSubject realSubject;

    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        System.out.println("Proxy: Forwarding request to RealSubject");
        realSubject.request();
    }
}

// 客户端代码
public class ProxyPatternDemo {
    public static void main(String[] args) {
        Subject proxy = new Proxy();
        proxy.request();
    }
}
  • Cpp代码演示
cpp
#include <iostream>
#include <memory>

// Subject接口
class Subject {
public:
    virtual void request() = 0;
    virtual ~Subject() = default;
};

// 真实主题类
class RealSubject : public Subject {
public:
    void request() override {
        std::cout << "RealSubject: Handling request" << std::endl;
    }
};

// 代理类
class Proxy : public Subject {
private:
    std::shared_ptr<RealSubject> realSubject;

public:
    void request() override {
        if (!realSubject) {
            realSubject = std::make_shared<RealSubject>();
        }
        std::cout << "Proxy: Forwarding request to RealSubject" << std::endl;
        realSubject->request();
    }
};

// 客户端代码
int main() {
    std::shared_ptr<Subject> proxy = std::make_shared<Proxy>();
    proxy->request();
}