@senspond

>

개발기>App 개발기

사주 만세력 JAVA 백엔드 개발 - 1 - 음양과 오행, 천간과 지지 조회 API 개발

등록일시 : 2023-09-05 (화) 10:50
업데이트 : 2024-01-28 (일) 08:30
오늘 조회수 : 10
총 조회수 : 2461

    사주명리학 이론을 바탕으로 음양오행, 천간과 지지를 JAVA 프로그래밍으로 표현해본 내용입니다.

    프롤로그

    개발자가 되기전에 잠시 사주명리학을 공부 했었던 적이 있다. 개발자가 되고 나서 언제 한번 코딩으로 구현해 서비스를 만들어 보고 싶다는 생각을 했다.


    음양 오행이란?


    동양철학에서는 태초에 무극이 있었고 무극에서 음과 양이 나왔다고 설명한다. 무극은 어떠한 개념이나 형태가 존재하고 상이 존재하지 않는 상태를 말한다.

    우주에서 음()과 양()이 만들어지며 유극의 상태가 되면 어떠한 물리법칙의 영향을 받아 일정한 규칙으로 변화하기 시작한다

    음양오행설은 음양설과 오행설을 함께 묶어 부르는 말로, 우주나 인간의 모든 현상이 음과 양의 쌍으로 나타나고, 음과 양이 변화함에 따라 다섯 가지 원소인 수, 화, 목, 금, 토가 생성하고 소멸하게 된다는 철학적 사상이다.


    개발환경

    우선 먼저 웹 형태로 구현을 해보고 최종목표는 안드로이드 앱 형태이다.

    먼저 자바(Java) 기반으로 웹 사이트 부터 만들어본다. 개발 환경은 다음과 같다.


    백엔드 - JDK 17 / Spring Boot 3.0.1

    프론트엔드 - TypesScript / React18 / Next13


    공통인터페이스 추상화

    객체지향의 장점을 살려 자바 언어로 개발을 할 때는 공통화 시킬 수 있는 부분에 대해 추상화를 하여 인터페이스를 잘 설계하는 것이 중요하다고 생각한다.


    • BaseLang

    public interface BaseEnumAbstract {
        String getKorean();
    
        String getChinese();
    
        static <E extends BaseEnumAbstract> List<E> list(Class<E> enumClass){
            return Stream.of(enumClass.getEnumConstants()).collect(Collectors.toList());
        }
    
        static <E extends BaseEnumAbstract> Map<String,E> koreanKeyMap(Class<E> enumClass){
            return Stream.of(enumClass.getEnumConstants()).collect(toMap(E::getKorean, v -> v));
        }
    
        static <E extends BaseEnumAbstract> Map<String,E> chineseKeyMap(Class<E> enumClass){
            return Stream.of(enumClass.getEnumConstants()).collect(toMap(E::getChinese, v -> v));
        }
    
        static <E extends BaseEnumAbstract> Map<String,E> responseMap(Class<E> enumClass){
            return koreanKeyMap(enumClass);
        }
    
        /**
         * 만세력 DB 에 저장된 문자키로 enum 타입으로 변환할때
         */
        static <E extends BaseEnumAbstract> E from(Class<E> enumClass, String language){
            Map<String, E> map = chineseKeyMap(enumClass); // 한자맵에서 꺼내옴
            if(map == null) return null;
            return map.get(language);
        }
        // korean(chinese) 출력하기 위한 
        static <E extends BaseEnumAbstract> String getMultiLang(E item, boolean useHighlight){
            return useHighlight ? String.format("\u001B[36m%s\u001B[31m(%s)\u001B[0m", item.getKorean(), item.getChinese())
                                : String.format("%s(%s)", item.getKorean(), item.getChinese());
        }
    }


    • Atom

    public interface Atom extends BaseEnumAbstract{
        YinYang getYinYang();
    }

    음양, 오행, 천간, 지지, 지장간 등을 Enum 클래스로 설계할 계획인데 모든 조상이 될 원자(Atom) 인터페이스이다. 용어를 표현하기 위한 한국어와 중국어, 음양이 포함되어 있다.


    • GanJi

    public interface GanJi extends BaseEnumAbstract {
        WuXing getWuXing();
    }

    Atom 인터페이스를 상속받은 간지(GanJi) 인터페이스이다. 천간과 지지 Enum 클래스를 구현할때 사용하기 위한 용도이다. 간지난다~


    public enum RequestType {
        normal,
        hash;
        public static final String NORMAL = "normal";
        public static final String HASH = "hash";
    }


    음양오행

    음양(, YinYang)

    최종적으로 DB를 구조적으로 설계해서 정리할 예정이지만 우선은 간단하게 이런 데이터는 자바 클래스로 정의를 했다.


    @Getter
    @AllArgsConstructor
    @JsonFormat(shape = JsonFormat.Shape.OBJECT)
    public enum YinYang implements BaseEnumAbstract {(1, "양", "陽"),(-1,"음","陰");
    
        @JsonIgnore
        private final int value;
        private final String korean;
        private final String chinese;
    }

    오행(五行, WuXing)

    @ToString
    @AllArgsConstructor
    @Getter
    @JsonFormat(shape = JsonFormat.Shape.OBJECT)
    public enum WuXing implements Atom {("목", "木", "#4CAF50"),("화", "火", "#F44336"),("토", "土", "#FFD600"),("금", "金", "#E0E0E0"),("수", "水", "#039BE5");
    
        private final String korean;
        private final String chinese;
        private final String color;
        @JsonIgnore
        private final YinYang yinYang = null;   // 오행은 음양이 없음
    }

    서비스(Service)

    import static com.rgbitcode.fortune.base.abstracts.BaseEnumAbstract.*;
    import com.rgbitcode.fortune.base.constrants.*;
    
    @Slf4j
    @Service
    @RequiredArgsConstructor
    public class MansesService {
    
        public YingYangAndXuXing.Dto findAllYingYangAndXuXing(RequestType type) {
            return RequestType.hash.equals(type)
                    ? new YingYangAndXuXing.Hash(responseMap(YinYang.class), responseMap(WuXing.class))
                    : new YingYangAndXuXing.Normal(list(YinYang.class), list(WuXing.class));
        }
    }


    DTO (Data Transfer Object)

    public class YingYangAndXuXing {
        public static class Dto{}
    
        @EqualsAndHashCode(callSuper = false)
        @Getter
        @NoArgsConstructor
        @AllArgsConstructor
        @ToString
        public static class Normal extends YingYangAndXuXing.Dto {
            private List<YinYang> yinYangs;
            private List<WuXing> xuXings;
        }
    
        @EqualsAndHashCode(callSuper = false)
        @Getter
        @NoArgsConstructor
        @AllArgsConstructor
        @ToString
        public static class Hash extends YingYangAndXuXing.Dto {
            private Map<String, YinYang> yinYangs;
            private Map<String, WuXing> xuXings;
        }
    }

    컨트롤러(Controller)

    @RestController
    @RequiredArgsConstructor
    public class MansesController {
    
        @GetMapping("/v1/manses/base")
        public ResponseEntity<?> findAllYingYangAndXuXing(
                @RequestParam(value = "type", defaultValue = RequestType.NORMAL) RequestType type
        ){
            return ResponseEntity.ok(mansesService.findAllYingYangAndXuXing(type));
        }
    }

    API 호출 응답 확인


    /v1/manses/base

    /v1/manses/base?type=normal

    {
        "yinYangs": [
            {
                "korean": "양",
                "chinese": "陽"
            },
            {
                "korean": "음",
                "chinese": "陰"
            }
        ],
        "xuXings": [
            {
                "korean": "목",
                "chinese": "木",
                "color": "#4CAF50"
            },
            {
                "korean": "화",
                "chinese": "火",
                "color": "#F44336"
            },
            {
                "korean": "토",
                "chinese": "土",
                "color": "#FFD600"
            },
            {
                "korean": "금",
                "chinese": "金",
                "color": "#E0E0E0"
            },
            {
                "korean": "수",
                "chinese": "水",
                "color": "#039BE5"
            }
        ]
    }


    /v1/manses/base?type=hash

    {
        "yinYangs": {
            "양": {
                "korean": "양",
                "chinese": "陽"
            },
            "음": {
                "korean": "음",
                "chinese": "陰"
            }
        },
        "xuXings": {
            "토": {
                "korean": "토",
                "chinese": "土",
                "color": "#FFD600"
            },
            "화": {
                "korean": "화",
                "chinese": "火",
                "color": "#F44336"
            },
            "금": {
                "korean": "금",
                "chinese": "金",
                "color": "#E0E0E0"
            },
            "수": {
                "korean": "수",
                "chinese": "水",
                "color": "#039BE5"
            },
            "목": {
                "korean": "목",
                "chinese": "木",
                "color": "#4CAF50"
            }
        }
    }


    천간과 지지 (간지)

    천간

    갑, 을, 병, 정, 무, 기, 경, 신, 임, 계 를 말한다.

    @AllArgsConstructor
    @Getter
    @ToString
    @JsonFormat(shape = JsonFormat.Shape.OBJECT)
    public enum Sky implements GanJi {(1,"갑", "甲", WuXing., YinYang.),(2,"을", "乙", WuXing., YinYang.),(3,"병", "丙", WuXing., YinYang.),(4,"정", "丁", WuXing., YinYang.),(5,"무", "戊", WuXing., YinYang.),(6,"기", "己", WuXing., YinYang.),(7,"경", "庚", WuXing., YinYang.),(8,"신", "辛", WuXing., YinYang.),(9,"임", "壬", WuXing., YinYang.),(10,"계", "癸", WuXing.,YinYang.);
    
        private final int idx;
        private final String korean;
        private final String chinese;
    
        //@JsonFormat(shape = JsonFormat.Shape.STRING)
        private final WuXing wuXing;
    
        //@JsonFormat(shape = JsonFormat.Shape.STRING)
        private final YinYang yinYang;
    
    }

    지지

    지지는 천간과 다르게 한가지 더 알아야하는 명리이론이 있다.

    각 지지에 천간의 기를 숨기고 있다는 것이다. 예를 들어 진(辰) 토의 경우 천간의 을 계 무 의 기를 담고 있다.


    각 지지가 속에 품고 있는 기를 여기(餘氣), 중기(中氣), 정기(正氣)라고 부른다.


    @Data
    @AllArgsConstructor
    @ToString
    public class JiJangGan {
        private Item first;
        private Item second;
        private Item third;
    
        @Data
        public static class Item {
            private double rate;
            private String korean;
            private String chinese;
            //@JsonFormat(shape = JsonFormat.Shape.STRING)
            private WuXing wuXing;
    
            public Item(Sky sky, double rate){
                this.rate = rate;
                this.korean = sky.getKorean();
                this.chinese = sky.getChinese();
                this.wuXing = sky.getWuXing();
            }
        }
    
    }


    지장간은 삼신기로 구성!

    지장간의 원소는 천간의 기(氣) 를 가지고 있다. 얼마나 많은 기(氣) 를 담고 있는지는 rate 로 표현

    일만 고려한다면 10, 20 이런식으로 쓸수가 있다

    @AllArgsConstructor
    @Getter
    @ToString
    @JsonFormat(shape = JsonFormat.Shape.OBJECT)
    public enum Ground implements GanJi {(1 ,"자", "子", YinYang., WuXing.,
                new JiJangGan(new Item(Sky., 10.1), null, new Item(Sky., 20.2))),(2 ,"축", "丑", YinYang., WuXing.,
                new JiJangGan(new Item(Sky., 9.3), new Item(Sky., 3.1), new Item(Sky., 18.6))),(3 ,"인", "寅", YinYang., WuXing.,
                new JiJangGan(new Item(Sky., 7.2), new Item(Sky., 7.2), new Item(Sky., 16.5))),
    
    	(... 중략 ...)
    
        private final int idx;
        private final String korean;
        private final String chinese;
        //@JsonFormat(shape = JsonFormat.Shape.STRING)
        private final YinYang yinYang;
        //@JsonFormat(shape = JsonFormat.Shape.STRING)
        private final WuXing wuXing;
        private final JiJangGan jiJangGan;
    }


    음양오행 API 처럼 DTO, service, controller를 구성했다.


    Object 전부를 보여주고 싶지 않고 간단하게 보여주고 싶다면

    @JsonFormat(shape = JsonFormat.Shape.STRING)

    어노테이션을 달아주면 된다.

    senspond

    안녕하세요. Red, Green, Blue 가 만나 새로운 세상을 만들어 나가겠다는 이상을 가진 개발자의 개인공간입니다.

    댓글 ( 0 )

    카테고리내 관련 게시글

    현재글에서 작성자가 발행한 같은 카테고리내 이전, 다음 글들을 보여줍니다

    @senspond

    >

    개발기>App 개발기

    • [현재글] 사주 만세력 JAVA 백엔드 개발 - 1 - 음양과 오행, 천간과 지지 조회 API 개발

      사주명리학 이론을 바탕으로 음양오행, 천간과 지지를 JAVA 프로그래밍으로 표현해본 내용입니다.
        2023-09-05 (화) 10:50
      1. 사주 만세력 JAVA 백엔드 개발 - 2 - 오행의 상생/상극 관계를 표현, 천간지지 상극관계, 육친관계 분석

        JAVA 프로그래밍으로 사주명리학의 오행의 상생/상극 관계를 표현하고 천간과 지지 간의 상극 관계, 육친관계를 분석할 수 있도록 구현해 본 글입니다.
          2023-09-06 (수) 01:10
        1. 사주 만세력 JAVA 백엔드 개발 - 3 - 만세력 DB 구축하기, 24절기, 절입조정, 서머타임, 야자시/조자시 개념

          프로그램 개발을 위한 만세력 DB 구축하기, 24절기, 절입조정, 서머타임, 야자시/조자시 개념을 정리해본 글입니다.
            2024-01-28 (일) 10:22