第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

DDD - 復(fù)合聚合序列化 - 設(shè)計問題

DDD - 復(fù)合聚合序列化 - 設(shè)計問題

互換的青春 2023-08-16 10:00:13
我正在嘗試將 DDD 應(yīng)用于一個 Java 項目。這是我偶然發(fā)現(xiàn)的問題:在域中,我有一個使用復(fù)合 OOP 模式實現(xiàn)的聚合。該聚合上的方法會生成一些需要序列化并通過線路發(fā)送的域?qū)ο?。這些是我想到的選項:在我的域的應(yīng)用程序服務(wù)部分中,我正在聚合,調(diào)用它的方法,并嘗試將結(jié)果序列化到 DTO。為了將其序列化為 DTO,我必須instanceof檢查當(dāng)前節(jié)點是復(fù)合節(jié)點還是子節(jié)點,然后繼續(xù)序列化。由于instanceof代碼味道(正如我讀到的,它違反了打開/關(guān)閉原則等),我決定嘗試使用訪問者模式。為了應(yīng)用訪問者模式,我的復(fù)合聚合必須實現(xiàn)訪問者,它將返回 DTO,然后 DTO 成為域?qū)拥囊徊糠?- 這也不是一個好的設(shè)計(因為域應(yīng)該只包含域概念,而 DTO 不屬于其中) 。DTO 序列化只是技術(shù)細(xì)節(jié),不應(yīng)該進(jìn)入領(lǐng)域?qū)?。還有其他不違背這些設(shè)計原則的解決方案嗎?有沒有辦法在java中模擬重載方法的動態(tài)綁定(除了instanceof- 因為這可以解決我使用選項1的問題)?
查看完整描述

3 回答

?
小怪獸愛吃肉

TA貢獻(xiàn)1852條經(jīng)驗 獲得超1個贊

如果訪問者具有通用返回類型,則訪問的類不會與該類型耦合。


public interface Node {

    <T> T accept(NodeVisitor<T> visitor);

}


public class ANode implements Node {

    @Override

    public <T> T accept(NodeVisitor<T> visitor) {

        return visitor.visit(this);

    }

}


public class BNode implements Node {

    @Override

    public <T> T accept(NodeVisitor<T> visitor) {

        return visitor.visit(this);

    }

}


public interface NodeVisitor<T> {

    T visit(ANode aNode);

    T visit(BNode bNode);

}


public class DtoNodeVisitor implements NodeVisitor<DTO> {

    @Override

    public DTO visit(ANode aNode) {

        return new DTO(); //use ANode to build this.

    }

    @Override

    public DTO visit(BNode bNode) {

        return new DTO(); //use BNode to build.

    }

}

ANode并且BNode對這里一無所知DTO。


查看完整回答
反對 回復(fù) 2023-08-16
?
九州編程

TA貢獻(xiàn)1785條經(jīng)驗 獲得超4個贊

首先,在第 2 點中我不明白:


我的復(fù)合聚合必須實現(xiàn)訪客


我想到的第一個問題是,為什么?您不能將訪問者聲明為接口,并將實現(xiàn)作為聚合的輸入?yún)?shù)傳遞嗎?


有沒有辦法在java中模擬重載方法的動態(tài)綁定(除了instanceof - 因為這可以解決我使用選項1的問題)?


是的,您可以使用反射來做到這一點,但真正的問題是,您想使用它們嗎?


我認(rèn)為答案取決于您需要管理多少案例以及它們發(fā)生變化的頻率?


如果您有“可管理”數(shù)量的不同案例,則解決方案instanceof可以是一個很好的交易:


public Something myMethod(Entity entity){

    if (entity instanceof AnEntity){

         //do stuffs

    else if (entity instanceof AnotherEntity){

         //do something else

    ...

    else {

         throw new RuntimeException("Not managed " + entity.getClass().getName());

    }

}

否則,當(dāng)您有更多情況并希望將代碼拆分為自己的方法時,您可以使用 Java 來完成MethodHandle,讓我發(fā)布一個用法示例:


package virtualmethods;


import java.lang.invoke.MethodHandles;

import java.lang.invoke.MethodType;


public class MyObject {


    public String doStuffs(Object i) throws Throwable {

        try {

            final MethodType type = MethodType.methodType(String.class, i.getClass());

            return (String) MethodHandles.lookup()

                .findVirtual(getClass(), "doStuffs", type)

                .invoke(this, i);

        } catch (NoSuchMethodException e) {

            throw new RuntimeException("Not managed " + i.getClass().getName(), e);

        }

    }


    private String doStuffs(Integer i) {

        return "You choose " + i;

    }

    private String doStuffs(Boolean b) {

        return "You choose boolean " + b;

    }

}

然后使用它:


package virtualmethods;


public class Main {


    public static void main(String[] args) throws Throwable {


        MyObject object = new MyObject();


        System.out.println("Integer => " + object.doStuffs(5));

        System.out.println("Boolean => " + object.doStuffs(true));

        try {

            System.out.println("String => " + object.doStuffs("something"));

        }

        catch (Throwable e) {

            System.out.println("KABOOM");

            e.printStackTrace();

        }

    }


}

獲取an 的公共方法將查找以結(jié)果命名的方法并作為類中的輸入(更多信息請參見此處)。 使用這種方式,您可以在運行時分派方法(使用重載是在編譯時靜態(tài)鏈接)。但這兩種方法都存在一個問題,即您無法確定您將管理第一種情況和/或第二種情況中擴(kuò)展/實現(xiàn)的所有類型,兩種解決方案都有一個或一個來檢查何時傳遞非托管類型到方法。MyObjectObjectdoStuffsStringi.getClass()MyObject

EntityObjectelsecatch

百分百確定您正在管理所有類型只能使用@jaco0646提出的解決方案來實現(xiàn),據(jù)我所知,它強(qiáng)制您管理所有類型,否則它將無法編譯??紤]到它需要的樣板數(shù)量,我只會在拋出會RuntimeException導(dǎo)致業(yè)務(wù)問題時使用,并且我不能保證它不會使用適當(dāng)?shù)臏y試來拋出(除此之外,我發(fā)現(xiàn)它非常有趣)。


查看完整回答
反對 回復(fù) 2023-08-16
?
一只名叫tom的貓

TA貢獻(xiàn)1906條經(jīng)驗 獲得超3個贊

聽起來你把它過于復(fù)雜化了。如果您需要,typeof那么您的聚合不會返回有效的域?qū)ο?。它返回的域?qū)ο筇ㄓ谩榱私鉀Q這個問題,您可以將聚合方法分為兩種方法;一個返回 Child,另一個返回 Composite。然后,您的應(yīng)用程序服務(wù)決定調(diào)用哪一個(如果可能)。

如果由于某種原因您需要聚合返回通用對象,我會重新考慮您選擇的設(shè)計。

另一個“黑客”是簡單地在域?qū)ο笊戏胖靡粋€屬性來指示它是復(fù)合對象還是子對象。我假設(shè)聚合會知道它是否是并且能夠準(zhǔn)確地填充該屬性。


查看完整回答
反對 回復(fù) 2023-08-16
  • 3 回答
  • 0 關(guān)注
  • 209 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號