어플 개발에서 드모르간 법칙

앱을 만들다 보면 조건이 늘 “좋은 형태”로만 들어오지 않습니다. 서버는 실패 상태를 부정 플래그로 내려주고, OS 권한은 기본적으로 거부/미결정 상태가 섞여 있으며, 외부 SDK는 isInvalid처럼 부정형 상태를 그대로 제공합니다. 이런 상태에서 조건식을 억지로 긍정 논리로만 유지하려고 하면 NOT NOT 같은 이중 부정이 늘고 괄호가 복잡해지면서, 작은 실수 하나가 화면 진입 오류나 권한 우회 같은 문제로 이어질 수 있습니다. 드모르간의 법칙은 이런 복잡한 조건을 “동치인 형태로 안전하게 변환”해 주기 때문에, 실패 조건을 먼저 걸러내는 구조와 잘 맞고 코드 가독성과 안정성을 동시에 끌어올립니다.

드모르간의 법칙

드모르간의 핵심은 NOT이 괄호 바깥에서 전체 조건을 덮을 때, AND와 OR이 서로 바뀌고 각 항목에 NOT이 분배된다는 점입니다.

NOT(A AND B)는 (NOT A) OR (NOT B)와 같습니다.

NOT(A OR B)는 (NOT A) AND (NOT B)와 같습니다.

이 규칙을 알고 있으면 “성공 조건”을 “실패 조건”으로 바꾸거나, 이미 존재하는 부정형 플래그를 그대로 살려서 조건식을 정리할 때 매우 유용합니다.

로그인과 권한 체크

화면 진입 조건은 대개 “로그인 상태이고 권한이 유효할 때만 통과”입니다. 하지만 구현 방식은 보통 그 반대로 가는 경우가 많습니다. 즉, 통과 조건을 길게 나열하기보다 실패 조건을 먼저 감지해 즉시 리턴하는 방식이 안전하고 읽기 쉽기 때문입니다.

이때 자주 등장하는 형태가 NOT(로그인 AND 권한유효)입니다. 드모르간을 적용하면 (NOT 로그인) OR (NOT 권한유효)로 바뀌고, 자연어로도 “로그인이 아니거나 권한이 없으면 막는다”가 되어 의도가 바로 보입니다. 이 구조는 에러 처리 분기에도 바로 연결돼서, 로그인 문제면 로그인 화면으로 보내고 권한 문제면 권한 요청 UX를 보여주는 식의 설계가 깔끔해집니다.

네트워크 동기화는 실패 조건

동기화 로직은 “네트워크 연결됨 AND 서버 정상”일 때만 수행하는 것이 원칙입니다. 그런데 실제로 중요한 건 성공이 아니라 실패를 어떻게 다루느냐입니다. 오프라인이면 로컬 캐시를 쓰고, 서버 장애면 재시도 큐에 적재하고, 타임아웃이면 백오프를 걸어야 하는 등 실패 정책이 훨씬 다양합니다.

그래서 조건을 NOT(연결됨 AND 서버정상) 형태로 먼저 잡고, 드모르간으로 “연결이 끊겼거나 서버가 비정상이면 동기화 스킵”으로 풀어 쓰면, 실패 정책을 붙이기가 훨씬 쉬워집니다. 특히 백그라운드 동기화처럼 사용자가 직접 보지 않는 영역일수록 이 방식이 안정적입니다.

푸시 알림은 토글과 OS 권한이 엇갈릴 때 문제

푸시 알림은 앱 내부 토글과 OS 권한이 둘 다 맞아야 실제로 동작합니다. 사용자는 앱에서 알림을 켰는데 OS에서 권한을 꺼둔 상태가 흔하고, 반대로 OS는 허용인데 앱 토글이 꺼진 상태도 자주 생깁니다.

이런 경우 “토글 ON AND 권한 허용”만으로는 부족하고, 실제로는 “불가능한 상태를 먼저 감지”하는 것이 UX가 좋습니다. NOT(토글ON AND 권한허용)을 드모르간으로 풀면 “토글이 꺼져 있거나 권한이 없으면 설정 유도”로 정리되고, 어떤 상태에서 어떤 안내를 해야 하는지 명확해집니다. 플랫폼마다 권한 상태가 세분화되어 있어도(미결정/거부/제한 등) 실패 조건 중심으로 두면 분기가 안정적으로 유지됩니다.

결제/구독

인앱결제나 구독은 “구매 가능 조건”을 늘리는 것보다 “구매 불가 조건”을 놓치지 않는 것이 더 중요합니다. 스토어 연결, 상품 정보 로딩, 국가/연령 제한, 계정 상태, 네트워크 등 변수가 많기 때문입니다.

따라서 구매 버튼을 활성화하는 것보다, 먼저 NOT(스토어정상 AND 상품로딩완료 AND 제한통과)를 체크해 비활성화하고 사유를 보여주는 설계를 자주 사용합니다. 드모르간으로 풀면 “스토어가 불안정하거나 상품 로딩이 덜 됐거나 제한에 걸리면 비활성화”가 되어, 비활성화 이유를 사용자에게 명확히 안내하는 UX까지 자연스럽게 연결됩니다.

폼 검증에서 NOT이 섞이면 버그

회원가입, 결제 정보, 주소 입력 같은 폼에서는 “모든 항목이 유효할 때만 제출 가능”이 기본입니다. 그런데 항목이 늘어나고, 특정 항목은 선택이고, 특정 항목은 조건부 필수로 바뀌면 조건식이 빠르게 복잡해집니다.

이때 NOT(모든 항목 유효)을 그대로 두면, 괄호와 NOT이 뒤엉켜서 한 항목을 빠뜨리거나 AND/OR 하나를 잘못 넣는 실수가 흔해집니다. 드모르간으로 “어떤 항목이든 유효하지 않으면 비활성화”로 바꾸면, 각 검증 함수를 OR로 연결하는 방식으로 구조가 단순해지고 변경에도 강해집니다. “첫 번째 오류 항목으로 스크롤/포커스 이동” 같은 기능도 실패 조건이 명확할수록 구현이 쉬워집니다.

로딩/빈 상태 화면 분기에서 흰 화면

앱에서 사용자 불만이 큰 문제 중 하나가 로딩이 끝난 것처럼 보이는데 아무것도 안 나오는 상태입니다. 보통 “데이터 있음 OR 로딩 중” 같은 조건이 어색하게 섞일 때 이런 문제가 생깁니다.

UI 분기는 상호배타적으로 설계하는 것이 좋고, 빈 상태 화면은 “보이면 안 되는 조건”이 더 중요할 때가 많습니다. 예를 들어 빈 상태를 숨겨야 하는 조건을 NOT 형태로 묶어 두었다면, 드모르간으로 “로딩 중이거나 데이터가 있으면 빈 상태 숨김”처럼 풀어 쓰면 충돌이 줄어듭니다. 재현이 어렵고 사용자 환경에서만 터지는 문제일수록 조건식의 명료함이 곧 품질입니다.

Feature Flag/A-B 테스트

A/B 테스트는 보통 “플래그 ON AND 대상자”일 때만 노출되어야 합니다. 그런데 대상자 조건은 국가, OS, 앱 버전, 계정 유형, 신규/기존 여부 등으로 계속 늘어납니다.

이때 노출 조건을 복잡하게 유지하기보다, 노출하지 말아야 하는 조건을 NOT(플래그ON AND 대상자)로 두고 드모르간으로 “플래그가 꺼져 있거나 대상자가 아니면 숨김”으로 만들면, 기본값이 숨김이 되어 위험이 줄어듭니다. AND 하나를 OR로 잘못 넣어 전 사용자에게 노출되는 사고도 이 구조에서 줄어드는 편입니다.

부정형 플래그

현업 코드에는 isInvalid, isDisabled, noPermission, notAvailable 같은 부정형 네이밍이 이미 널리 퍼져 있는 경우가 많습니다. 이를 전부 긍정형으로 바꾸는 것은 리스크가 큰 작업이 될 수 있습니다.

드모르간은 이런 상황에서 “부정형 플래그를 억지로 뒤집지 않고”도 조건식을 읽기 쉽게 바꿀 수 있게 해줍니다. 실패 조건을 부정 플래그 중심으로 OR로 묶으면, 로깅과 에러 메시지 매핑도 쉬워지고, 무엇 때문에 실패했는지가 구조적으로 드러납니다.

결론

드모르간의 법칙은 앱 개발에서 복잡해지는 조건식을 안전하게 정리하는 핵심 규칙입니다. 특히 실패 조건을 먼저 걸러내는 흐름, 권한과 네트워크 같은 상태 분기, 부정형 플래그가 이미 존재하는 코드 구조에서 논리의 의미를 유지한 채 가독성과 안정성을 동시에 높여줍니다. NOT이 전체 조건을 덮는 범위를 먼저 확정한 뒤 AND와 OR을 뒤집어 분해하면, 괄호 실수와 이중 부정으로 생기는 버그 가능성이 줄고, 에러 처리와 UX 분기까지 일관되게 설계할 수 있습니다. 결국 드모르간은 “성공 조건을 늘어놓는 방식”보다 “실패 조건을 명확히 정의하는 방식”에 힘을 실어주며, 화면 진입부터 폼 검증, 결제, 동기화, A/B 테스트까지 앱 전 영역에서 유지보수 가능한 조건문을 만드는 데 직접적인 도움이 됩니다.

FAQ

드모르간의 법칙은 앱 개발에서 어떤 상황에 가장 많이 쓰이나요?

로그인과 권한 체크, 네트워크 동기화, 푸시 권한, 결제/구독 버튼 활성화, 폼 검증, 로딩/빈 상태 화면 분기, Feature Flag와 A/B 테스트처럼 조건이 여러 개 겹치는 곳에서 가장 자주 쓰입니다. 공통점은 성공 조건보다 실패 조건을 먼저 처리하는 흐름이 필요하다는 점이며, 드모르간은 이 실패 조건을 직관적으로 바꿔주는 역할을 합니다.

조건문을 리팩토링할 때 드모르간을 적용하는 순서가 있나요?

먼저 NOT이 덮는 범위를 괄호로 명확히 고정한 뒤, 괄호 안에서 AND와 OR을 뒤집고 각 항목에 NOT을 분배하는 순서로 진행하는 것이 안전합니다. 이 과정을 거치면 논리 의미를 유지하면서도 복잡한 조건이 읽기 쉬운 형태로 정리됩니다.

부정형 플래그가 많은 코드에서 드모르간이 왜 유리한가요?

isInvalid, isDisabled, noPermission처럼 부정형 값이 이미 퍼져 있으면 이를 억지로 긍정형으로 바꾸기 위해 NOT NOT이 늘어나고 조건이 난해해집니다. 드모르간을 사용하면 부정형 플래그를 그대로 활용하면서도 실패 조건을 자연스럽게 OR로 묶어 표현할 수 있어, 코드 가독성과 오류 원인 추적이 쉬워집니다.

early return 패턴과 드모르간은 어떤 관계가 있나요?

early return은 실패 조건을 먼저 감지해 빠르게 종료하는 방식이라, 조건이 NOT(성공조건) 형태로 등장하는 경우가 많습니다. 이때 드모르간으로 NOT(AND/OR 조합)을 풀어주면 “A가 아니거나 B가 아니면 반환” 같은 형태가 되어 읽기 쉬워지고, 실패 사유별 UX 분기도 더 명확하게 구현됩니다.

AND와 OR을 뒤집는 과정에서 가장 흔한 실수는 무엇인가요?

NOT이 전체 조건을 덮지 않는데도 드모르간을 적용하거나, 괄호 범위를 잘못 잡아 일부 조건만 뒤집는 실수가 가장 흔합니다. 특히 NOT이 어디까지 적용되는지 모호한 상태에서 변환하면 의미가 바뀌어 권한 우회, 버튼 오작동, 화면 진입 오류 같은 문제가 발생할 수 있습니다.

폼 검증에서 드모르간을 쓰면 어떤 점이 좋아지나요?

“모든 항목이 유효하면 제출 가능”을 그대로 유지하면 조건이 길어지고 변경에 취약해집니다. 드모르간을 통해 “어떤 항목이든 유효하지 않으면 비활성화”로 바꾸면, 각 검증 결과를 OR로 결합하는 구조가 되어 항목 추가/삭제에 강해지고, 첫 오류 항목 포커싱 같은 UX 기능도 자연스럽게 붙일 수 있습니다.

로딩/빈 상태 화면 분기에서 드모르간이 도움이 되는 이유는 무엇인가요?

UI 분기에서 빈 상태를 언제 숨기고 언제 보여줄지 조건이 섞이면 ‘흰 화면’처럼 보이는 문제가 생기기 쉽습니다. 빈 상태를 숨겨야 하는 조건을 명확히 정의한 뒤 드모르간으로 풀어 “로딩 중이거나 데이터가 있으면 숨김”처럼 정리하면 분기 충돌이 줄고, 상태 전환이 안정적으로 동작합니다.

Feature Flag나 A/B 테스트에서는 어떤 방식으로 적용하는 게 안전한가요?

노출 조건을 복잡하게 늘리기보다, 숨김 조건을 기본값으로 두는 편이 안전합니다. NOT(플래그ON AND 대상자) 형태를 드모르간으로 풀어 “플래그가 꺼져 있거나 대상자가 아니면 숨김”으로 만들면, 실수로 전 사용자에게 노출되는 위험을 줄이고 운영 중 변경에도 더 강해집니다.

댓글 남기기