안녕하세요, Artem입니다.
질문이 있습니다:
코드에서 객체 유형을 읽습니다.
//--- 개체 유형 읽기 this.m_element_type=(ENUM_OBJECT_TYPE)::FileReadInteger(file_handle,INT_VALUE);
하지만 SB에서와 같이 확인하지 않습니다.
bool CList::Load(const int file_handle) { uint i,num; CObject *node; bool result=true; //--- 확인 if(file_handle==INVALID_HANDLE) return(false); //--- 시작 마커 읽기 및 확인 - 0xFFFFFFFFFFFFFFFFFFF if(FileReadLong(file_handle)!=-1) return(false); //--- 유형 읽기 및 확인 if(FileReadInteger(file_handle,INT_VALUE)!=Type()) return(false); //--- 읽기 목록 크기 num=FileReadInteger(file_handle,INT_VALUE); //--- Load() 메서드 호출을 사용하여 목록 항목을 순차적으로 생성합니다. Clear(); for(i=0;i<num;i++) { node=CreateElement(); if(node==NULL) return(false); Add(node); result&=node.Load(file_handle); } //--- 성공 return(result); }
보시다시피 Type() 메서드는 단순히 값을 반환합니다.
virtual int Type(void) const { return(0x7779); }
SB에서 이러한 검사의 필요성은 무엇인가요? 유형을 읽고 해당 유형의 요소를 만드는 것으로 충분할까요?
유형이 읽혀지지 않으면 다음은 어떻게 될까요?
다음은 코드입니다:
//--- 노드 객체의 Load() 메서드를 호출하여 목록 항목을 순차적으로 다시 생성합니다. this.Clear(); for(uint i=0; i<num; i++) { //--- 오브젝트 데이터 시작 마커 읽기 및 확인 - 0xFFFFFFFFFFFFFFFFFFFFF if(::FileReadLong(file_handle)!=MARKER_START_DATA) return false; //--- 개체 유형 읽기 this.m_element_type=(ENUM_OBJECT_TYPE)::FileReadInteger(file_handle,INT_VALUE); node=this.CreateElement(); if(node==NULL) return false; this.Add(node); //--- 이제 파일 포인터가 객체 마커의 시작 부분을 기준으로 12바이트(8 - 마커, 4 - 유형) 오프셋됩니다. //--- 객체 데이터의 시작 부분에 포인터를 놓고 노드 요소의 Load() 메서드를 사용하여 파일에서 객체 속성을 로드해 보겠습니다. if(!::FileSeek(file_handle,-12,SEEK_CUR)) return false; result &=node.Load(file_handle); } //--- 결과 return result; } //+------------------------------------------------------------------+ //| 목록 항목 생성 방법| //+------------------------------------------------------------------+ CObject *CListObj::CreateElement(void) { //--- m_element_type의 객체 유형에 따라 새 객체를 생성합니다. switch(this.m_element_type) { case OBJECT_TYPE_TABLE_CELL : return new CTableCell(); case OBJECT_TYPE_TABLE_ROW : return new CTableRow(); case OBJECT_TYPE_TABLE_MODEL : return new CTableModel(); default : return NULL; } }
객체의 타입을 변수로 읽습니다. 그런 다음 CreateElement()에서 이 객체를 생성하려고 시도합니다. 생성 중인 객체의 유형을 파일에서 읽지 못하면 이 메서드는 무엇을 반환할까요?
유형이 읽히지 않으면 다음 단계는 무엇인가요?
다음은 코드입니다:
객체의 타입을 변수로 읽습니다. 그런 다음 CreateElement()에서 이 객체를 생성하려고 시도합니다. 생성하려는 객체의 유형을 파일에서 읽을 수 없는 경우 이 메서드는 무엇을 반환할까요?
아르템, 제가 말하는 것은 그 문제가 아닙니다. SB에 타입 체크가 있다는 사실에 대해 이야기하고 있습니다. 바로 그 검사요.
//--- 유형 읽기 및 확인 if(FileReadInteger(file_handle,INT_VALUE)!= Type()) return(false);
파일에서 읽은 유형이 Type()읽기 및 유형검사 메서드의 유형과 일치합니까? 그렇게 번역되나요?
그리고 유형을 확인하지 않고 그냥 읽습니다.
그렇다면 이 검사의 깊은 의미는 무엇일까요?
이 검사의 깊은 의미는 무엇일까요?
바로 이 일부 오브젝트의 Load() 메서드를 호출하여 파일에서 일부 오브젝트의 클래스를 로드할 때, "내가 정말 파일에서 나 자신을 읽었나?"(질문하신 내용)를 확인합니다. 그렇지 않다면 뭔가 잘못되었다는 뜻이므로 더 이상 로드할 필요가 없습니다.
여기에는 파일에서 객체 유형을 읽는 리스트(CListObj)가 있습니다. 이 목록은 파일에 무엇이 있는지(어떤 객체인지) 알지 못합니다. 하지만 CreateElement() 메서드에서 객체 유형을 생성하려면 이 객체 유형을 알고 있어야 합니다. 그렇기 때문에 파일에서 로드된 객체의 유형을 확인하지 않습니다. 결국 이 메서드에서는 객체가 아닌 목록의 유형을 반환하는 Type()과 비교하게 됩니다.
바로 이 일부 오브젝트의 Load() 메서드를 호출하여 파일에서 일부 오브젝트의 클래스를 로드하면 "내가 정말 파일에서 나 자신을 읽었나?"를 확인합니다(질문하신 내용입니다). 그렇지 않다면 뭔가 잘못되었다는 뜻이므로 더 이상 로드할 필요가 없습니다.
여기에는 파일에서 객체 유형을 읽는 LIST(CListObj)가 있습니다. 이 목록은 파일에 무엇이 있는지(어떤 객체인지) 알지 못합니다. 하지만 CreateElement() 메서드에서 객체 유형을 생성하려면 이 객체 유형을 알고 있어야 합니다. 그렇기 때문에 파일에서 로드된 객체의 유형을 확인하지 않습니다. 결국 이 메서드에서는 객체가 아닌 목록의 유형을 반환하는 Type()과 비교하게 됩니다.
고마워요, 이제 알겠습니다.
읽고 또 읽었습니다.
는 MVC에서 "모델"이 아닌 다른 것입니다. 예를 들어 일부 ListStorage는
새로운 기고글 MQL5에서 테이블 모델 구현: MVC 개념 적용 가 게재되었습니다:
프로그래밍에서 애플리케이션 아키텍처는 안정성, 확장성, 지원 용이성을 보장하는 데 중요한 역할을 합니다. 이러한 목표를 달성하는 데 도움이 되는 접근 방식 중 하나는 MVC(모델-뷰-컨트롤러) 라는 아키텍처 패턴을 활용하는 것입니다.
MVC 개념을 사용하면 애플리케이션을 세 가지의 상호 연관된 구성 요소, 즉 모델 (데이터 및 로직 관리), 뷰 (데이터 표시), 컨트롤러 (사용자 작업 처리)로 나눌 수 있습니다. 이러한 분리를 통해 코드 개발, 테스트, 유지관리가 간소화되어 코드가 더욱 체계적이고 유연 해집니다.
이 글에서는 MQL5 언어로 테이블 모델을 구현하기 위해 MVC 원칙을 적용하는 방법을 살펴보겠습니다. 테이블은 데이터를 저장, 처리, 표시하는 데 중요한 도구이며 테이블을 올바르게 구성하면 정보를 처리하는 작업이 훨씬 쉬워질 수 있습니다. 테이블 작업을 위해 테이블 셀, 행, 테이블 모델 등의 클래스를 만들겠습니다. 테이블 모델 내의 행과 행 내에 셀을 저장하기 위해 MQL5 표준 라이브러리의 linked list(연결 목록) 클래스를 사용합니다. 이 클래스를 사용하면 데이터를 효율적으로 저장하고 사용할 수 있습니다.
작성자: Artyom Trishkin