@senspond
>
사주명리학 이론을 바탕으로 음양오행, 천간과 지지를 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";
}
최종적으로 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;
}
@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; // 오행은 음양이 없음
}
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));
}
}
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;
}
}
@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));
}
}
/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)
어노테이션을 달아주면 된다.
안녕하세요. Red, Green, Blue 가 만나 새로운 세상을 만들어 나가겠다는 이상을 가진 개발자의 개인공간입니다.
현재글에서 작성자가 발행한 같은 카테고리내 이전, 다음 글들을 보여줍니다
@senspond
>