문제

내가 찾고서 차이 POCO 및 DTO (나타나는 POCO 의 dto 의 행동(는 방법?))가 이 문서 Martin Fowler 에 anaemic 도메인 모델입니다.

을 통해 이해가 부족,나는 내가 만들어 이들 중 하나 anaemic 도메인 모델입니다.

중 하나에서의 내용 내업체 도메인에 정의된'dto'dll.그들은 많은 특성을 getter 및 세터 및 다른 많은 수 없습니다.내 비즈니스 논리 코드(채우고,계산은)다른'bll'dll,내 데이터에 액세스 코드에서는'dal'dll.'최상의 방법'나는 생각했다.

그래서 일반적으로 만들 dto 그래서 다음과 같:

dto.BusinessObject bo = new dto.BusinessObject(...)

고 그것을 전달하 bll 레이어는 다음과 같이

bll.BusinessObject.Populate(bo);

서 수행하는 논리를 전달합 dal 레이어는 다음과 같이

dal.BusinessObject.Populate(bo);

에서 나의 이해,내 dto 로 POCO 의 필요 비즈니스 로직과 동작(방법)의 일부 개체입니다.그래서 위의 코드 대신 그것은 더 많은 다음과 같:

poco.BusinessObject bo = new poco.BusinessObject(...)
bo.Populate();

ie.나는 메소드를 호출에 개체보다는 전달하는 개체하는 방법입니다.

나의 질문은 이렇게 하려면 어떻게 해야 합니까 아직도 유지할'최고의 연습'레이어링의 문제(별도의 dll 등...).지 않는 메소드를 호출에 객체를 의미하는 방법에 정의되어야 합 object?

도와주세요 나 혼란이 있습니다.

도움이 되었습니까?

해결책

일반적으로 도메인 객체에 지속성을 소개하고 싶지 않습니다. 비즈니스 모델의 일부가 아니기 때문에 (비행기는 자체를 구성하지 않으며, 승객/화물을 한 위치에서 다른 위치로 날아갑니다). 당신은 사용해야합니다 저장소 패턴, an ORM 프레임 워크, 또는 객체의 지속적인 스토리지 및 retreival을 관리하기위한 다른 데이터 액세스 패턴 상태.

빈혈 도메인 모델이 시작되는 곳은 다음과 같은 일을 할 때입니다.

IAirplaneService service = ...;
Airplane plane = ...;
service.FlyAirplaneToAirport(plane, "IAD");

이 경우 비행기의 관리 (비행 중, 어디에 있는지, 출발 시간/공항, 도착 시간/공항, 비행 계획 등)의 관리가 비행기 외부의 무언가로 위임됩니다. . 비행기 서비스 인스턴스.

이것을 구현하는 poco 방법은 인터페이스를 이런 식으로 설계하는 것입니다.

Airplane plane = ...;
plane.FlyToAirport("IAD");

개발자들은 비행기를 비행 할 곳을 알고 있기 때문에 (비행기에 말하면) 이것은 더 발견 할 수 있습니다. 또한 상태가 있는지 확인할 수 있습니다 내부적으로 관리. 그런 다음 현재 위치를 읽기 전용으로 만들고 한 곳에서만 변경되도록 할 수 있습니다. 빈혈 도메인 객체를 사용하면 상태가 외부로 설정되어 있으므로 도메인의 규모가 증가함에 따라 상태가 변경되는 위치를 발견하는 것이 점점 어려워집니다.

다른 팁

이것을 명확히하는 가장 좋은 방법은 정의에 따라 다음과 같습니다.

DTO : 데이터 전송 개체 :

그들은 일반적으로 프리젠 테이션 계층과 서비스 계층 사이에 데이터 전송에만 사용됩니다. 그 이상은 없습니다. 일반적으로 Gets and Sets가있는 클래스로 구현됩니다.

public class ClientDTO
{
    public long Id {get;set;}
    public string Name {get;set;}
}

BO : 비즈니스 개체 :

비즈니스 객체는 비즈니스 요소를 나타내며 당연히 모범 사례는 비즈니스 논리도 포함해야한다고 말합니다. Michael Meadows의 말했듯이,이 개체에서 데이터 액세스를 분리하는 것이 좋습니다.

public class Client
{
    private long _id;
    public long Id 
    { 
        get { return _id; }
        protected set { _id = value; } 
    }
    protected Client() { }
    public Client(string name)
    {
        this.Name = name;    
    }
    private string _name;
    public string Name
    {
        get { return _name; }
        set 
        {   // Notice that there is business logic inside (name existence checking)
            // Persistence is isolated through the IClientDAO interface and a factory
            IClientDAO clientDAO = DAOFactory.Instance.Get<IClientDAO>();
            if (clientDAO.ExistsClientByName(value))
            {
                throw new ApplicationException("Another client with same name exists.");
            }
            _name = value;
        }
    }
    public void CheckIfCanBeRemoved()
    {
        // Check if there are sales associated to client
        if ( DAOFactory.Instance.GetDAO<ISaleDAO>().ExistsSalesFor(this) )
        {
            string msg = "Client can not be removed, there are sales associated to him/her.";
            throw new ApplicationException(msg);
        }
    }
}

서비스 또는 신청 수업이 클래스는 사용자와 시스템 간의 상호 작용을 나타내며 ClientDTO와 클라이언트를 모두 사용합니다.

public class ClientRegistration
{
    public void Insert(ClientDTO dto)
    {
        Client client = new Client(dto.Id,dto.Name); /// <-- Business logic inside the constructor
        DAOFactory.Instance.Save(client);        
    }
    public void Modify(ClientDTO dto)
    {
        Client client = DAOFactory.Instance.Get<Client>(dto.Id);
        client.Name = dto.Name;  // <--- Business logic inside the Name property
        DAOFactory.Instance.Save(client);
    }
    public void Remove(ClientDTO dto)
    {
        Client client = DAOFactory.Instance.Get<Client>(dto.Id);
        client.CheckIfCanBeRemoved() // <--- Business logic here
        DAOFactory.Instance.Remove(client);
    }
    public ClientDTO Retrieve(string name)
    {
        Client client = DAOFactory.Instance.Get<IClientDAO>().FindByName(name);
        if (client == null) { throw new ApplicationException("Client not found."); }
        ClientDTO dto = new ClientDTO()
        {
            Id = client.Id,
            Name = client.Name
        }
    }
}

개인적으로 난 사람들을 찾아 Anaemic 도메인 모델은 그렇게 나쁜;내가 정말 좋아하는 아이디어의 도메인을 나타내는 개체에만 데이터,지 않습니다.나는 생각한 주요 단점은 이 방법으로는 검색 기능의 코드당신은 알 필요가 있는 사용할 수 있는 작업을 사용합니다.을 얻을 수있는 방법 중 하나 주는 여전히 계속 동작 코드에서 분리되어 모델을 소개하는 인터페이스에 대한 행동:

interface ISomeDomainObjectBehaviour
{
    SomeDomainObject Get(int Id);
    void Save(SomeDomainObject data);
    void Delete(int Id);
}

class SomeDomainObjectSqlBehaviour : ISomeDomainObjectBehaviour
{
    SomeDomainObject ISomeDomainObjectBehaviour.Get(int Id)
    {
        // code to get object from database
    }

    void ISomeDomainObjectBehaviour.Save(SomeDomainObject data)
    {
        // code to store object in database
    }

    void ISomeDomainObjectBehaviour.Delete(int Id)
    {
        // code to remove object from database
    }
}
class SomeDomainObject
{
    private ISomeDomainObjectBehaviour _behaviour = null;
    public SomeDomainObject(ISomeDomainObjectBehaviour behaviour)
    {

    }

    public int Id { get; set; }
    public string Name { get; set; }
    public int Size { get; set; }


    public void Save()
    {
        if (_behaviour != null)
        {
            _behaviour.Save(this);
        }
    }

    // add methods for getting, deleting, ...

}

는 방법으로 유지할 수 있습니다 행동을 구현하에서 분리된 모델입니다.의 사용은 인터페이스 구현을 주입 하는 모델로도 코드를 테스트할 수 있기 때문에 쉽게 모니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top