领域驱动设计:软件核心复杂性应对之道

(未学完后面会继续)

消化知识

在这里插入图片描述

提取一个隐藏的概念

在这里插入图片描述

交流与语言的使用

在这里插入图片描述

解释性模型

在这里插入图片描述

模式:MODEL-DRIVEN DESIGN

如果整个程序设计或者其核心部分没有与领域模型相对应,那么这个模型就是没有价值的,软件的正确性也值得怀疑。同时,模型和设计功能之间过于复杂的对应关系也是难于理解的,在实际项目中,当设计改变时也无法维护这种关系。若分析与和设计之间产生严重分歧,那么在分析和设计活动中所获得的知识就无法彼此共享。
软件系统各个部分的设计应该忠实地反映领域模型,以便体现出这二者之间的明确对应关系。我们应该反复检查并修改模型,以便软件可以更加自然地实现模型,即使想让模型反映出更深层次的领域概念时也应如此。我们需要的模型不但应该满足这两种需求,还应该能够支持健壮
的UBIQUITOUS LANGUAGE(通用语言)。
从模型中获取用于程序设计和基本职责分配的术语。让程序代码成为模型的表达,代码的改变可能会是模型的改变。而其影响势必要波及接下来相应的项目活动。 完全依赖模型的实现通常需要支持建模范式的软件开发工具和语言,比如面向对象的编程。

从过程设计到MODEL-DRIVEN DESIGN

在这里插入图片描述

下面代码还没调试过

#include <cassert>
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>

class LayoutRule {
public:
    int type;
    int value;
    LayoutRule() {}
    LayoutRule(int type, int value) : type(type), value(value) {}

    bool operator<(const LayoutRule& other) const { return type < other.type; }

    bool operator==(const LayoutRule& other) const {
        return type == other.type && value == other.value;
    }
};
class Net;
class Bus {
private:
    std::string name;            // 总线的名称
    std::set<LayoutRule> rules;  // 假设 Bus 内部也有规则集合
    std::set<std::shared_ptr<Net>> nets;

public:
    Bus() {}
    Bus(const std::string& name) : name(name) {}
    void addNet(const std::shared_ptr<Net>& net) {
        nets.insert(net);
        // net->setBus(std::make_shared<Bus>(*this));
    }
    std::set<LayoutRule> assignedRules() const {
        // 返回分配给 Bus 的规则集合
        return rules;
    }

    void assignRule(const LayoutRule& rule) {
        // 为 Bus 分配规则
        rules.insert(rule);
    }
    const std::string& getName() const { return name; }
};

class AbstractNet {
protected:
    std::string name;  // Net 的名称
    std::set<LayoutRule> rules;

public:
    AbstractNet(const std::string& name) : name(name) {}
    void assignRule(const LayoutRule& rule) { rules.insert(rule); }

    std::set<LayoutRule> assignedRules() const { return rules; }
    const std::string& getName() const { return name; }
};

class Net : public AbstractNet {
public:
    Net(const std::string& name) : AbstractNet(name) {}
    std::set<LayoutRule> assignedRules() const {
        std::set<LayoutRule> result = AbstractNet::assignedRules();
        return result;
    }

    // void assignRuleToBus(const LayoutRule& rule) { bus.assignRule(rule); }
    const std::string& getName() const { return name; }
};

// 假设 Collection 是一个容器类,如 std::vector
using CollectionNet = std::vector<std::shared_ptr<Net>>;
using CollectionBus = std::vector<std::shared_ptr<Bus>>;

class NetListImportService {
public:
    static CollectionNet read(const std::string& aFile) {
        CollectionNet nets;
        std::ifstream file(aFile);
        if (!file.is_open()) {
            std::cerr << "无法打开文件: " << aFile << std::endl;
            return nets;
        }

        std::string line;
        std::map<std::string, Bus> busMap;  // 存储已创建的 Bus 对象
        while (std::getline(file, line)) {
            std::istringstream iss(line);
            std::string netName;
            std::string componentPin;

            // 解析行,假设格式为 "NetName Component.Pin"
            if (!(iss >> netName >> componentPin)) {
                continue;  // 跳过格式不正确的行
            }

            // 推断总线名称
            std::string busName = inferBusName(netName);
            Bus& bus = busMap[busName];  // 如果不存在则创建新的 Bus
            if (bus.getName().empty()) {
                bus = Bus(busName);
            }

            // 创建 Net 对象并分配给 Bus
            auto net = std::make_shared<Net>(netName);
            LayoutRule rule;
            net->assignRule(rule);
            // net->assignRuleToBus(rule);

            nets.push_back(net);
        }

        file.close();
        return nets;
    }

private:
    static std::string inferBusName(const std::string& netName) {
        // 根据名称推断总线名称,这里假设总线名称为 netName 的前缀
        auto pos = netName.find('_');
        if (pos != std::string::npos) {
            return netName.substr(0, pos);
        }
        return netName;
    }
};

class NetRepository {
    std::map<std::string, std::shared_ptr<Net>> nets;
    // 通过名称访问 Net 的接口
public:
    void addAll(const CollectionNet& netsCollection) {
        for (const auto& net : netsCollection) {
            nets[net->getName()] = net;
        }
    }
    std::shared_ptr<Net> getByName(const std::string& name) const {
        return nets.at(name);
    }
};

class InferredBusFactory {
public:
    static CollectionBus groupIntoBuses(const CollectionNet& nets) {
        std::map<std::string, std::shared_ptr<Bus>> busMap;

        // 遍历所有 Net,基于命名约定推断 Bus
        for (const auto& net : nets) {
            std::string busName = inferBusName(net->getName());
            if (busMap.find(busName) == busMap.end()) {
                busMap[busName] = std::make_shared<Bus>(busName);
            }
            busMap[busName]->assignRule(*net->assignedRules().begin());
        }

        CollectionBus buses;
        for (const auto& pair : busMap) {
            buses.push_back(pair.second);
        }
        return buses;
    }

private:
    static std::string inferBusName(const std::string& netName) {
        // 根据名称推断总线名称,这里假设总线名称为 netName 的前缀
        auto pos = netName.find('_');
        if (pos != std::string::npos) {
            return netName.substr(0, pos);
        }
        return netName;
    }
};

class BusRepository {
    std::map<std::string, std::shared_ptr<Bus>>
        buses;  // 通过名称访问 Bus 的接口
public:
    void addAll(const CollectionBus& busesCollection) {
        for (const auto& bus : busesCollection) {
            buses[bus->getName()] = bus;
        }
    }
    void addBus(const std::shared_ptr<Bus>& bus) {
        buses[bus->getName()] = bus;
    }
    std::shared_ptr<Bus> getByName(const std::string& name) const {
        return buses.at(name);
    }
};

void testBusRuleAssignment() {
    auto a0 = std::make_shared<Net>("a0");
    auto a1 = std::make_shared<Net>("a1");
    auto a = std::make_shared<Bus>("a");

    a->addNet(a0);
    a->addNet(a1);

    LayoutRule minWidth4(1, 4);
    // Using 1 as the type for MIN_WIDTH
    a->assignRule(minWidth4);

    assert(a0->assignedRules().count(minWidth4) > 0);
    assert(a1->assignedRules().count(minWidth4) > 0);
    std::cout << "Test passed!" << std::endl;
}

class BusFacade {
private:
    BusRepository& busRepository;

public:
    BusFacade(BusRepository& busRepo) : busRepository(busRepo) {}
    void assignBusRule(const std::string& busName, int ruleType,
                       double parameter) {
        auto bus = busRepository.getByName(busName);
        if (bus) {
            LayoutRule rule(ruleType, parameter);
            bus->assignRule(rule);
        }
    }
};

void test() {
    // Example usage
    BusRepository busRepository;
    BusFacade busFacade(busRepository);

    auto bus1 = std::make_shared<Bus>("Bus1");
    busRepository.addBus(bus1);

    // Assign a rule to Bus1
    busFacade.assignBusRule("Bus1", 1, 10.5);
}

int main() {
    NetListImportService NetListImportService;
    InferredBusFactory InferredBusFactory;
    NetRepository NetRepository;
    BusRepository BusRepository;
    std::string aFile = "nets.txt";
    CollectionNet nets = NetListImportService.read(aFile);
    NetRepository.addAll(nets);
    CollectionBus buses = InferredBusFactory.groupIntoBuses(nets);
    BusRepository.addAll(buses);
    return 0;
}

第二部分 模型驱动设计的构造块

在这里插入图片描述
在这里插入图片描述

分 离 领 域

在这里插入图片描述

软件中所表示的模型

在这里插入图片描述

模式:ENTITY(又称为REFERENCE OBJECT)

在这里插入图片描述

ENTITY建模

在这里插入图片描述

设计标识操作

在这里插入图片描述

模式:VALUE OBJECT

在这里插入图片描述

模式:SERVICE

在这里插入图片描述

SERVICE与孤立的领域层

在这里插入图片描述

领域对象的生命周期

在这里插入图片描述

模式:AGGREGATE

在这里插入图片描述

采购订单的完整性 (模式:AGGREGATE 续)

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值