자체 메소드 또는 다른 클래스를 통해 오브젝트를 저장 하시겠습니까? 보인다 ) Class

객체를 저장하고 검색하려면 처리 할 다른 클래스를 만들어야합니까, 아니면 클래스 자체에서 처리하는 것이 더 낫습니까? 아니면 둘 다 섞을까요?

OOD 패러다임에 따라 권장되는 것은 무엇입니까?

예를 들어

Class Student
{
    public string Name {set; get;}
    ....
    public bool Save()
    {
        SqlConnection con = ...
        // Save the class in the db
    }
    public bool Retrieve()
    {
         // search the db for the student and fill the attributes
    }
    public List<Student> RetrieveAllStudents()
    {
         // this is such a method I have most problem with it
         // that an object returns an array of objects of its own class!
    }
}

대. (나는 다음이 권장된다는 것을 알고 있지만, Student수업 의 응집력에 대해 조금 나아 보인다 )

Class Student { /* */ }
Class DB {
  public bool AddStudent(Student s)
  {

  }
  public Student RetrieveStudent(Criteria)
  {
  }
  public List<Student> RetrieveAllStudents()
  {
  }
}

섞는 건 어때요?

   Class Student
    {
        public string Name {set; get;}
        ....
        public bool Save()
        {
            /// do some business logic!
            db.AddStudent(this);
        }
        public bool Retrieve()
        {
             // build the criteria
             db.RetrieveStudent(criteria);
             // fill the attributes
        }
    }



답변

단일 책임 원칙 , 우려의 분리기능적 응집력 . 이러한 개념을 읽으면 다음과 같은 대답을 얻을 수 있습니다 .

Student“DB”클래스 와 분리하는 (또는 StudentRepository보다 일반적인 규칙을 따르는) 간단한 이유 는 Student지속성에 책임이있는 코드에 영향을주지 않고 클래스에 존재하는 “비즈니스 규칙”을 변경 하고, 반대로.

이러한 종류의 분리는 비즈니스 규칙과 지속성뿐만 아니라 시스템의 많은 관심사 사이에서 매우 중요하여 관련없는 모듈에 미치는 영향을 최소화하면서 변경을 수행 할 수 있습니다 (때로는 피할 수 없기 때문에 최소화해야 함). 지속적인 변경이있을 때 유지 관리가 쉽고 안정적인 시스템을 더욱 강력하게 구축 할 수 있습니다.

첫 번째 예에서와 DB같이 단일 클래스 또는 의 종속성으로 비즈니스 규칙과 지속성을 함께 혼합 Student하면 두 가지 매우 다른 관심사를 결합하게됩니다. 그들은 함께 속해있는 것처럼 보일 수 있습니다. 그들은 동일한 데이터를 사용하기 때문에 응집력이있는 것처럼 보입니다. 그러나 여기에 문제가 있습니다. 응집력은 절차간에 공유되는 데이터만으로는 측정 할 수 없으며, 존재하는 추상화 수준도 고려해야합니다. 실제로 이상적인 응집력 유형은 다음과 같습니다.

기능적 응집력 은 모듈의 일부가 그룹화되어 모듈의 단일 정의 된 작업에 기여하기 때문에 발생합니다.

그리고 일정 Student기간 동안 유효성 검사를 수행해 도 “단일 정의 된 작업”이 형성되지 않습니다. 다시 한 번 비즈니스 규칙과 지속성 메커니즘은 시스템의 두 가지 매우 다른 측면으로, 우수한 객체 지향 디자인의 많은 원칙에 의해 분리되어야합니다.

나는에 대해 읽어 보시기 바랍니다 클린 건축 보고, 단일 책임 원칙에 대한이 이야기 (매우 비슷한 예를 사용), 시청 청소 아키텍처에 대한이 이야기 뿐만 아니라. 이러한 개념은 그러한 분리의 원인을 설명합니다.


답변

두 가지 접근법 모두 단일 책임 원칙을 위반합니다. 첫 번째 버전은 Student클래스에게 많은 책임을 부여하고 특정 DB 액세스 기술에 연결합니다. 두 번째는 DB학생뿐만 아니라 프로그램의 다른 종류의 데이터 객체에 대한 책임이 있는 거대한 수업으로 이어집니다 . 편집 : 세 번째 접근 방식은 DB 클래스와 클래스 사이에 주기적 종속성을 생성하기 때문에 최악 Student입니다.

장난감 프로그램을 쓰지 않으려면 아무 것도 사용하지 마십시오. 대신 StudentRepository로드 및 저장을위한 API를 제공하기 위해 와 같은 다른 클래스를 사용 하십시오. CRUD 코드를 직접 구현한다고 가정하십시오. ORM 프레임 워크 사용을 고려할 수도 있습니다.이 프레임 워크는 어려운 작업을 수행 할 수 있습니다 (그리고 프레임 워크는 일반적으로로드 및 저장 조작이 필요한 위치에 일부 결정을 시행합니다).


답변

데이터 지속성에 사용할 수있는 패턴이 꽤 있습니다. 이 작업 단위 패턴이있다, 저장소 와에 따라서 원격 외관처럼 사용 될 수있는 몇 가지 추가 패턴이있다, 패턴.

대부분의 팬과 비평가가 있습니다. 종종 응용 프로그램에 가장 적합한 것으로 고르고 응용 프로그램을 고수합니다 (모든 장점과 단점이 있습니다. 즉, 두 패턴을 동시에 사용하지 않는 경우 … 정확히 확신하지 않는 한).

참고로, 예제에서 RetrieveStudent, AddStudent는 정적 메소드 여야합니다 (인스턴스 종속적이지 않기 때문에).

클래스 내 저장 /로드 메소드를 사용하는 다른 방법은 다음과 같습니다.

class Animal{
    public string Name {get; set;}
    public void Save(){...}
    public static Animal Load(string name){....}
    public static string[] GetAllNames(){...} // if you just want to list them
    public static Animal[] GetAllAnimals(){...} // if you actually need to retrieve them all
}

개인적으로 나는 그러한 접근 방식을 상당히 작은 응용 프로그램, 개인적 용도를위한 도구 또는 객체를 저장하거나로드하는 것보다 더 복잡한 사용 사례가 없을 것이라고 안정적으로 예측할 수있는 곳에서만 사용합니다.

또한 개인적으로 작업 단위 패턴을 참조하십시오. 당신이 그것을 알게되면, 그것은 작은 경우와 큰 경우에 정말 좋습니다. 그리고 많은 프레임 워크 / API에서 EntityFramework 또는 RavenDB라는 이름을 지원합니다.


답변

객체가 데이터 스토어에 연결되어 있고 비자에 대한 연결이 매우 간단한 앱인 경우 (즉, 데이터 스토어의 속성으로 생각할 수있는 경우) 해당 클래스에 대해 .save () 메서드를 사용하는 것이 좋습니다.

그러나 나는 그것이 매우 예외적이라고 생각합니다.

오히려 일반적으로 클래스가 데이터와 기능 (좋은 OO 시민과 같은)을 관리하게하고 지속 메커니즘을 다른 클래스 또는 클래스 세트로 외부화하는 것이 좋습니다.

다른 옵션은 주석과 같이 선언적으로 지속성을 정의하는 지속성 프레임 워크를 사용하는 것이지만 여전히 지속성을 외부화하고 있습니다.


답변

  • 해당 클래스에서 객체를 직렬화하는 메소드를 정의하고 데이터베이스 또는 파일 또는 기타에 넣을 수있는 바이트 시퀀스를 리턴합니다.
  • 입력과 같은 바이트 시퀀스를 취하는 해당 객체의 생성자를 갖습니다.

RetrieveAllStudents()방법에 관해서는 , 당신의 느낌이 맞습니다. 여러분의 독특한 학생들 목록이있을 수 있기 때문에 실제로 잘못되었을 수 있습니다. 왜 단순히 목록을 Student클래스 외부에 유지하지 않습니까?


답변