eShopOnWeb 知多少

構(gòu)建現(xiàn)代Web應(yīng)用

1.引言

eShopOnWeb是基于ASP.NET Core構(gòu)建,官方創(chuàng)建這樣一個示例項(xiàng)目的目的籍凝,我想無非以下幾點(diǎn):

  1. 推廣ASP.NET Core
  2. 指導(dǎo)利用ASP.NET Core如何進(jìn)行架構(gòu)設(shè)計
  3. 普及架構(gòu)設(shè)計思想

eShopOnWeb 與另外一個eShopOnContainers互相補(bǔ)充。eShopOnContainers是基于微服務(wù)和容器技術(shù)的應(yīng)用程序架構(gòu)苗缩,支持多重部署。而eShopOnWeb相較于它就簡單的多声诸,其是基于傳統(tǒng)Web應(yīng)用開發(fā)酱讶,僅支持單一部署。

本文就簡單梳理下自己的所學(xué)所得彼乌。

2.MPA Or SPA

eShopOnWeb的示例項(xiàng)目中包含兩個Web項(xiàng)目泻肯,一個是基于MVC創(chuàng)建的MPA多頁面應(yīng)用渊迁,一個是基于Razor創(chuàng)建的SPA單頁面應(yīng)用。在此之間我該如何選擇呢灶挟?

  1. 是否需要豐富的交互行為琉朽?
  2. 是否足夠的前端技術(shù)積累?
  3. 是否主要通過API進(jìn)行交互稚铣?
決策表:Mpa or Spa

3. 架構(gòu)設(shè)計

eShopOnWeb中應(yīng)用了DDD和整潔架構(gòu)的部分思想箱叁,值得了解一下。

3.1 架構(gòu)原則

關(guān)注點(diǎn)分離:簡稱SOP惕医。在分層架構(gòu)設(shè)計中耕漱,關(guān)注點(diǎn)分離是核心設(shè)計思想,每一層獨(dú)自負(fù)責(zé)不同的職責(zé)抬伺。從架構(gòu)上講螟够,可以通過將核心業(yè)務(wù)與基礎(chǔ)設(shè)施和用戶界面邏輯分離來實(shí)現(xiàn)。該原則旨在避免緊耦合峡钓,又可確保各個模塊獨(dú)立發(fā)展妓笙。

封裝:封裝的是什么?是對象的狀態(tài)和行為能岩。外部對象無需關(guān)注其內(nèi)部的實(shí)現(xiàn)機(jī)制寞宫。
在類中,通過使用訪問修飾符來限制外部的訪問來實(shí)現(xiàn)封裝捧灰。 如果外部想要操縱對象的狀態(tài)淆九,它應(yīng)該通過定義良好的函數(shù)(或?qū)傩栽O(shè)置器)來實(shí)現(xiàn),而不是直接訪問對象的私有狀態(tài)毛俏。
而不同模塊之間通過公開定義良好的接口進(jìn)行方法調(diào)用炭庙,來實(shí)現(xiàn)封裝。以隔離內(nèi)部的實(shí)現(xiàn)機(jī)制煌寇。通過封裝來確保應(yīng)用程序間不同部分之間的隔離焕蹄,正確使用封裝有助于在應(yīng)用程序設(shè)計中實(shí)現(xiàn)松耦合和模塊化。

依賴倒置:簡稱DIP阀溶。高層模塊不應(yīng)該依賴低層模塊腻脏,均應(yīng)該依賴與抽象;抽象不應(yīng)該依賴于細(xì)節(jié)银锻;細(xì)節(jié)應(yīng)該依賴于抽象永品。DIP是構(gòu)建松耦合應(yīng)用的關(guān)鍵部分,從而確保應(yīng)用程序模塊化击纬,更易于測試和維護(hù)鼎姐。 通過遵循DIP绊起,可以應(yīng)用依賴注入洁段。

顯式依賴:方法和類應(yīng)明確指定所需的協(xié)作對象(依賴)以確保正常運(yùn)行。簡單來說,對于類而言践美,提供明確的構(gòu)造函數(shù)(即在構(gòu)造函數(shù)參數(shù)中指定該類需要正常工作所需的依賴對象)朗涩,以便調(diào)用者正確傳參以正確實(shí)例化對象愿待。

單一職責(zé):簡稱SRP糠惫。SRP作為面向?qū)ο笤O(shè)計的原則之一,也適用于架構(gòu)原則姊途。其與SOP類似涉瘾。它強(qiáng)調(diào)對象應(yīng)該只有一個責(zé)任,他們只應(yīng)該僅有一個改變的理由吭净。換言之睡汹,對象應(yīng)該改變的唯一情況是它的職責(zé)需要被更新。遵守該原則寂殉,可以編寫松耦合和模塊化的應(yīng)用囚巴。因?yàn)榇罅康男碌男袨槎紤?yīng)該創(chuàng)建新類去實(shí)現(xiàn),而不是添加到已經(jīng)存在的類中友扰。添加新類永遠(yuǎn)比修改一個類安全彤叉,因?yàn)樯袩o代碼依賴于新類。
在復(fù)雜的大型應(yīng)用中村怪,可以將SRP應(yīng)用到分層應(yīng)用的各個層秽浇。展現(xiàn)職責(zé)應(yīng)保留在UI項(xiàng)目中,而數(shù)據(jù)訪問職責(zé)應(yīng)保留在基礎(chǔ)設(shè)施項(xiàng)目中甚负, 業(yè)務(wù)邏輯應(yīng)該保留在應(yīng)用程序核心項(xiàng)目中柬焕。如此,即易于測試又可以獨(dú)立于其他職責(zé)持續(xù)演化梭域。
該原則的更高級應(yīng)用斑举,就是微服務(wù)了。每個微服務(wù)負(fù)責(zé)獨(dú)立的職責(zé)病涨。

摒棄重復(fù):當(dāng)出現(xiàn)重復(fù)時富玷,應(yīng)該實(shí)施重構(gòu)。避免當(dāng)功能改進(jìn)時既穆,需要同時修改多個部分赎懦。

透明持久化:要求可以輕松切換持久化技術(shù),而實(shí)現(xiàn)持久化無感知(透明持久化)幻工。

限界上下文:該概念是DDD戰(zhàn)略設(shè)計的一部分励两,通過限界上下文來劃分領(lǐng)域,作為領(lǐng)域的顯式邊界囊颅,為領(lǐng)域提供上下文語境伐蒋,保證在領(lǐng)域之內(nèi)的一些術(shù)語工三、業(yè)務(wù)相關(guān)對象等(通用語言)有一個確切的含義迁酸,沒有二義性先鱼。

3.2. 傳統(tǒng)分層架構(gòu)和整潔架構(gòu)

傳統(tǒng)的分層架構(gòu)是大家所熟知的三層架構(gòu)。


傳統(tǒng)三層架構(gòu)
三層架構(gòu)示例

這樣的架構(gòu)的缺點(diǎn)是:

  1. 依賴關(guān)系由上至下奸鬓,不易解耦
  2. 不易測試焙畔,需要測試數(shù)據(jù)庫

那如何解決三層架構(gòu)的問題呢,借助【依賴倒置原則】串远。
DDD的分層架構(gòu)思想和整潔架構(gòu)中都是借助【依賴倒置原則】實(shí)現(xiàn)層與層之間強(qiáng)依賴關(guān)系的解耦宏多。我們來看下整潔架構(gòu):

整潔架構(gòu)——洋蔥視圖

從該洋蔥視圖中我們可以看到:

  1. 依賴關(guān)系由外而內(nèi)。
  2. 處于核心的是實(shí)體和接口澡罚,不依賴任何其他項(xiàng)伸但。其次是領(lǐng)域服務(wù),僅依賴實(shí)體和接口留搔,也相對獨(dú)立更胖。它們統(tǒng)稱為應(yīng)用程序內(nèi)核
  3. 應(yīng)用程序內(nèi)核之外是基礎(chǔ)架構(gòu)層和展現(xiàn)層隔显,彼此也不一定依賴却妨。

由于應(yīng)用程序內(nèi)核不依賴于基礎(chǔ)設(shè)施層,所以可以很容易編寫單元測試括眠。


單元測試位置

由于UI層也不直接依賴于基礎(chǔ)設(shè)施層彪标,所以我們可以輕松置換基礎(chǔ)設(shè)施層的實(shí)現(xiàn)(比如使用內(nèi)存數(shù)據(jù)庫),以進(jìn)行集成測試掷豺。


集成測試位置
整潔架構(gòu)——水平視圖

下面我們就來看看eShopOnWeb是如何應(yīng)用整潔架構(gòu)的捞烟。

4. 項(xiàng)目結(jié)構(gòu)

首先我們看下模板架構(gòu)的項(xiàng)目結(jié)構(gòu)。


eShopOnWeb Solution

從上圖來看其項(xiàng)目結(jié)構(gòu)十分簡單当船,簡單的三層题画,加上三個測試項(xiàng)目。
三層對應(yīng):

  1. ApplicationCore:領(lǐng)域?qū)?/li>
  2. Infrastructure:基礎(chǔ)設(shè)施層
  3. Web/WebRazorPages:展現(xiàn)層
DDD使用的傳統(tǒng)分層架構(gòu)

其實(shí)該項(xiàng)目架構(gòu)是DDD經(jīng)典四層架構(gòu)生年,只不過其將應(yīng)用層集成到展現(xiàn)層中去了婴程。


Web應(yīng)用服務(wù)

4.1 基礎(chǔ)設(shè)施層

主要提供通用的基礎(chǔ)服務(wù)和持久化。


Infrastructure

從上圖的代碼結(jié)構(gòu)我們可以看出:

  1. 在Data文件夾下定義了用于持久化的商品目錄數(shù)據(jù)庫上下文CatalogContext和泛型倉儲EfRepository抱婉。
  2. Identity文件夾下定義了身份數(shù)據(jù)庫上下文的档叔。
  3. Logging文件夾定義了一個日志適配器。
  4. Services定義了一個通用的郵件發(fā)送基礎(chǔ)服務(wù)蒸绩。

4.2. 領(lǐng)域?qū)?/h2>

領(lǐng)域?qū)邮且粋€項(xiàng)目的核心衙四,用來定義業(yè)務(wù)規(guī)則并實(shí)現(xiàn)。其主要用來實(shí)體患亿、值對象传蹈、聚合押逼、倉儲、領(lǐng)域服務(wù)和領(lǐng)域事件等惦界。


ApplicationCore

從上圖來看:

  1. Entities文件夾下定義了三個聚合根和相關(guān)的實(shí)體及值對象挑格。
  2. Exceptions文件夾定義了公共的異常。
  3. Interfaces文件夾定義了系列接口沾歪。
  4. Services文件夾定義了兩個領(lǐng)域服務(wù)漂彤。
  5. Specifications文件夾下是實(shí)現(xiàn)的規(guī)約模式。

4.2.1. 聚合根的相關(guān)實(shí)現(xiàn)

這里我們來看下聚合根的相關(guān)定義和實(shí)現(xiàn)灾搏。

///抽象的聚合根空接口
public interface IAggregateRoot
    { }
//所有的實(shí)體基類
public class BaseEntity
    {
        public int Id { get; set; }
    }

//購物車聚會根
public class Basket : BaseEntity, IAggregateRoot
{
    public string BuyerId { get; set; }
    private readonly List<BasketItem> _items = new List<BasketItem>();
    public IReadOnlyCollection<BasketItem> Items => _items.AsReadOnly();

    public void AddItem(int catalogItemId, decimal unitPrice, int quantity = 1)
    {
        if (!Items.Any(i => i.CatalogItemId == catalogItemId))
        {
            _items.Add(new BasketItem()
            {
                CatalogItemId = catalogItemId,
                Quantity = quantity,
                UnitPrice = unitPrice
            });
            return;
        }
        var existingItem = Items.FirstOrDefault(i => i.CatalogItemId == catalogItemId);
        existingItem.Quantity += quantity;
    }
}

從這個實(shí)現(xiàn)中我們可以學(xué)習(xí)到:

通過定義一個空的接口IAggregateRoot挫望,要求所有的聚會根來實(shí)現(xiàn)它。

這樣做的體現(xiàn)了什么思想:

  1. 面向接口編程
  2. 約定大于配置
  3. 依賴注入

通過定義一個BaseEntity狂窑,要求所有的實(shí)體繼承它媳板。

為什么這樣做?

  1. 因?yàn)閷?shí)體的特征是具有唯一的身份標(biāo)識泉哈,所以通過在父類來定義Id屬性來實(shí)現(xiàn)蛉幸。這也就是層超類型的實(shí)現(xiàn)方式。

這樣做有什么缺點(diǎn)旨巷?
因?yàn)樗袑?shí)體的主鍵類型不一定都是int類型巨缘,所以這個基類型最好改成泛型。

Basket聚合根中將Items定位為Readonly采呐,是為了封裝集合若锁,避免子項(xiàng)被其他地方更改。

4.2.2. 倉儲的相關(guān)實(shí)現(xiàn)

倉儲是用來透明持久化領(lǐng)域?qū)ο蟮摹?/p>

public interface IRepository<T> where T : BaseEntity
{
    T GetById(int id);
    T GetSingleBySpec(ISpecification<T> spec);
    IEnumerable<T> ListAll();
    IEnumerable<T> List(ISpecification<T> spec);
    T Add(T entity);
    void Update(T entity);
    void Delete(T entity);
}
public interface IAsyncRepository<T> where T : BaseEntity
{
    Task<T> GetByIdAsync(int id);
    Task<List<T>> ListAllAsync();
    Task<List<T>> ListAsync(ISpecification<T> spec);
    Task<T> AddAsync(T entity);
    Task UpdateAsync(T entity);
    Task DeleteAsync(T entity);
}

從以上代碼我們可以學(xué)到兩點(diǎn):

  1. 面向接口編程
  2. 職責(zé)分離斧吐,同步異步接口分離又固。

4.2.3. 領(lǐng)域服務(wù)相關(guān)實(shí)現(xiàn)

領(lǐng)域服務(wù)用來實(shí)現(xiàn)業(yè)務(wù)邏輯的。

public interface IOrderService
{
    Task CreateOrderAsync(int basketId, Address shippingAddress);
}
public class OrderService : IOrderService
{
    private readonly IAsyncRepository<Order> _orderRepository;
    private readonly IAsyncRepository<Basket> _basketRepository;
    private readonly IAsyncRepository<CatalogItem> _itemRepository;
    public OrderService(IAsyncRepository<Basket> basketRepository,
        IAsyncRepository<CatalogItem> itemRepository,
        IAsyncRepository<Order> orderRepository)
    {
        _orderRepository = orderRepository;
        _basketRepository = basketRepository;
        _itemRepository = itemRepository;
    }
    public async Task CreateOrderAsync(int basketId, Address shippingAddress)
    {
        var basket = await _basketRepository.GetByIdAsync(basketId);
        Guard.Against.NullBasket(basketId, basket);
        var items = new List<OrderItem>();
        foreach (var item in basket.Items)
        {
            var catalogItem = await _itemRepository.GetByIdAsync(item.CatalogItemId);
            var itemOrdered = new CatalogItemOrdered(catalogItem.Id, catalogItem.Name, catalogItem.PictureUri);
            var orderItem = new OrderItem(itemOrdered, item.UnitPrice, item.Quantity);
            items.Add(orderItem);
        }
        var order = new Order(basket.BuyerId, shippingAddress, items);
        await _orderRepository.AddAsync(order);
    }

從以上代碼我們可以學(xué)習(xí)到:

  1. 依賴注入
  2. 領(lǐng)域服務(wù)負(fù)責(zé)實(shí)現(xiàn)真正的業(yè)務(wù)邏輯

4.3. 應(yīng)用層和展現(xiàn)層

如上面所闡述煤率,在示例項(xiàng)目中應(yīng)用層和展現(xiàn)層合二為一仰冠。應(yīng)用層負(fù)責(zé)展現(xiàn)層與領(lǐng)域?qū)又g的協(xié)調(diào),協(xié)調(diào)業(yè)務(wù)對象來執(zhí)行特定的應(yīng)用程序蝶糯。

5. 面向切面編程(AOP)

eShopOnWeb中也提到了AOP洋只,介紹了在ASP.NET Core中如何應(yīng)用過濾器來進(jìn)行AOP,比如:身份驗(yàn)證昼捍、模型驗(yàn)證识虚、輸出緩存和錯誤處理等。


通過過濾器和請求管道執(zhí)行
執(zhí)行順序

5. 簡明DDD

在eShopOnWeb中妒茬,也對DDD的概念担锤,是否使用,何時使用乍钻,何時不用肛循,都略有介紹铭腕。這里就摘錄一二,當(dāng)然也可以參考我之前的寫的DDD理論學(xué)習(xí)系列多糠。

結(jié)論

  1. DDD首先是一個方法論累舷,其注重于領(lǐng)域的合理建模,分為戰(zhàn)略建模和戰(zhàn)術(shù)建模熬丧。
  2. 如果你不知道你需要它笋粟,那么你可能不需要它。
  3. 如果你不知道到DDD用于解決什么問題析蝴,那么你可能沒有遇到這些問題。
  4. DDD倡導(dǎo)者也經(jīng)常指出其僅適用于大型項(xiàng)目 (>6個月)绿淋。

相關(guān)概念

  1. DDD是用來對真實(shí)世界系統(tǒng)或流程的建模闷畸。
  2. 使用DDD時,你需要和領(lǐng)域?qū)<揖o密合作吞滞,領(lǐng)域?qū)<夷軌蚪忉屨鎸?shí)的系統(tǒng)該如何運(yùn)行佑菩。在和領(lǐng)域?qū)<业慕涣髦写_定通用語言,其主要用來描述系統(tǒng)中的一些概念裁赠。而之所以是通用殿漠,是因?yàn)椴还苁情_發(fā)人員還是領(lǐng)域?qū)<叶紤?yīng)能夠讀懂。而通用語言描述的概念將構(gòu)成面向?qū)ο笤O(shè)計的基礎(chǔ)佩捞。其體現(xiàn)在代碼中的理想狀態(tài)是代碼即設(shè)計绞幌。

戰(zhàn)術(shù)

  1. 值對象:不可變。
  2. 實(shí)體:具有唯一標(biāo)識符可變一忱。
  3. 聚會根:在DDD中莲蜘,用來表示整體與部分的關(guān)系,聚合是將相關(guān)聯(lián)的領(lǐng)域?qū)ο筮M(jìn)行顯式分組帘营,來表達(dá)整體的概念(也可以是單一的領(lǐng)域?qū)ο螅┢鼻1热鐚⒈硎居唵闻c訂單項(xiàng)的領(lǐng)域?qū)ο筮M(jìn)行組合,來表達(dá)領(lǐng)域中訂單這個整體概念芬迄。
  4. 倉儲:一種持久化的模式问顷,用于隔離具體持久化措施,實(shí)現(xiàn)透明持久化禀梳。
  5. 工廠:用于對象的創(chuàng)建杜窄。
  6. 服務(wù):應(yīng)用服務(wù)和領(lǐng)域服務(wù)。領(lǐng)域服務(wù)負(fù)責(zé)業(yè)務(wù)邏輯出皇,應(yīng)用服務(wù)用于表達(dá)業(yè)務(wù)用例和用戶故事羞芍。

戰(zhàn)略

  1. 限界上下文:來為領(lǐng)域提供上下文語境,保證在領(lǐng)域之內(nèi)的一些術(shù)語郊艘、業(yè)務(wù)相關(guān)對象等(通用語言)有一個確切的含義荷科,沒有二義性唯咬。
  2. 上下文映射圖:限界上下文之間的關(guān)聯(lián)關(guān)系。

6. 應(yīng)用測試

在eShopOnWeb中畏浆,還示例了三個測試項(xiàng)目胆胰,來指導(dǎo)我們合理的進(jìn)行測試。


單元測試刻获、集成測試和功能測試的區(qū)別

7. 總結(jié)

總體而言蜀涨,示例項(xiàng)目簡單容易理解,也主要是為了便于推廣和演示蝎毡。但里面涉及的知識點(diǎn)并沒有想象的那么簡單厚柳,從架構(gòu)原則到設(shè)計和應(yīng)用,每一個環(huán)節(jié)都包含不簡單的知識體系沐兵。

所以等什么呢别垮?結(jié)合示例項(xiàng)目和官方文檔使用 ASP.NET Core 和 Azure 構(gòu)建新式 Web 應(yīng)用程序開始學(xué)習(xí)吧,相信你也會收獲頗豐扎谎。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末碳想,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子毁靶,更是在濱河造成了極大的恐慌胧奔,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件预吆,死亡現(xiàn)場離奇詭異龙填,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)啡浊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門觅够,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人巷嚣,你說我怎么就攤上這事喘先。” “怎么了廷粒?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵窘拯,是天一觀的道長。 經(jīng)常有香客問我坝茎,道長涤姊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任嗤放,我火速辦了婚禮思喊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘次酌。我一直安慰自己恨课,他們只是感情好舆乔,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著剂公,像睡著了一般希俩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纲辽,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天颜武,我揣著相機(jī)與錄音,去河邊找鬼拖吼。 笑死鳞上,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绿贞。 我是一名探鬼主播因块,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼籍铁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起趾断,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤拒名,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后芋酌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體增显,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年脐帝,在試婚紗的時候發(fā)現(xiàn)自己被綠了同云。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡堵腹,死狀恐怖炸站,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情疚顷,我是刑警寧澤旱易,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站腿堤,受9級特大地震影響阀坏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜笆檀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一忌堂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧酗洒,春花似錦士修、人聲如沸枷遂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽登淘。三九已至,卻和暖如春封字,著一層夾襖步出監(jiān)牢的瞬間黔州,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工阔籽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留流妻,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓笆制,卻偏偏與公主長得像绅这,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子在辆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,305評論 25 707
  • 引言 在討論DDD分層架構(gòu)的模式之前证薇,我們先一起回顧一下DDD和分層架構(gòu)的相關(guān)知識。 DDD DDD(Domain...
    _張曉龍_閱讀 160,691評論 15 193
  • 如何和真我――宇宙真實(shí)有效地溝通 真我是宇宙的一部分匆篓,與真我連接浑度,你可以得到你渴望得到的全部 伊朗,美國鸦概,中國人們...
    幸福的姿瑤寶貝閱讀 1,409評論 0 2
  • 其實(shí)婚假休到了本周三箩张,周四才回來上班,本周只上了兩天班窗市,不知為什么卻感到很疲憊先慷,整個人的身體感覺都很累。 休個周末...
    jiaojiao者閱讀 396評論 0 3
  • 每個人的生活中會經(jīng)歷快樂,傷心扎拣,尷尬赴肚,慚愧的那一刻。有的不值一提二蓝,有的使我們銘記深刻誉券。 曾經(jīng)我經(jīng)歷過很...
    2020級1班閱讀 449評論 4 0