추상화의 장점
- 인터페이스와 추상화는 개발 시 전체적인 규격을 만들어 줌
- 추상화를 하지 않을 경우 중복코드가 발생하기 때문에 번거로움을 감소시키기 위해 추상화 사용
- 인터페이스와 추상화를 활용하면 모듈 간의 결합도(coupling)를 감소시킴(면접질문*)
- 규격이 있으면 서로 다른 것들끼리 충돌없이 사용 할 수 있음 ex) C타입 충전기
- 결합도 : 서로 다른 모듈 간에 상호의존하는 정도/연관된 관계
변형을 줄 때 주변에 손상을 미치는 정도(분리했을 때 리스크가 큰 것을 결합도가 높다고 함)
ex) 결합도가 높은 것(신체) VS 결합도가 낮은 것(로봇) - 응집도 : 결합도에 대응 / 응집도는 한 모듈 내부의 처리요소들이 서로 관련되어 있는 정도
- 응고결저 : 응집도는 높고 결합도는 낮은 것이 좋음
- 결합도 : 서로 다른 모듈 간에 상호의존하는 정도/연관된 관계
- Vingsu<<interface>>
- jdk 1.8미만에서는 default 매서드가 지원되지 않기 때문에 추상클래스를 사용하는 것이 적합
package kr.co.web.model;
public interface Vingsu {
public default void iceFlake() {
System.out.println("갈아둔 얼음을 넣는다");
}
public default void milk() {
System.out.println("멸균우유를 넣는다");
}
public default void redBean() {
System.out.println("팥을 넣는다");
}
public default void jelly() {
System.out.println("젤리를 넣는다");
}
public void etc();
}
- RedBeanVingsu
package kr.co.web.model;
public class RedBeanVingsu implements Vingsu {
@Override
public void etc() {
System.out.println("추가 첨가 없음");
}
}
- ChocoVingsu
package kr.co.web.model;
public class ChocoVingsu implements Vingsu {
@Override
public void etc() {
System.out.println("초코시럽을 넣는다");
}
}
- CookieVingsu
package kr.co.web.model;
public class CookieVingsu implements Vingsu {
@Override
public void etc() {
System.out.println("쿠키를 넣는다");
}
}
- FruitVingsu
package kr.co.web.model;
public class FruitVingsu implements Vingsu {
@Override
public void etc() {
System.out.println("과일을 넣는다");
}
}
- VingsuMachine
- 인터페이스를 구현받은 클래스는 인터페이스 데이터타입의 변수에 들어갈 수 있다(다형성)
- 객체화 할 때 변수에 담에서 넣어줄 수도 있지만 매개변수 위치에 바로 넣어줄 수 있음(그릇없이)
package kr.co.web.model;
public class VingsuMachine {
String name;
public VingsuMachine(String name) {
this.name = name;
}
//매개변수 자리에서 바로 객체화 해버림
//Vingsu 타입에 ChocoVingsu, CookieVingsu, RedBeanVingsu, FruitVingsu가 들어갈 수 있다
public String makeVingsu(Vingsu vingsu) {
vingsu.iceFlake();
vingsu.milk();
vingsu.redBean();
vingsu.jelly();
vingsu.etc();
return name + "가 완성되었습니다.";
}
}
- index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<style></style>
</head>
<body>
<form action="make" method="post">
<select name="vingsu">
<option value="팥빙수">팥빙수</option>
<option value="초코빙수">초코빙수</option>
<option value="쿠키빙수">쿠키빙수</option>
<option value="과일빙수">과일빙수</option>
</select>
<input type="submit" value="주문"/>
</form>
<h3>${result}</h3>
</body>
<script></script>
</html>
- VingsuController
package kr.co.web.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.co.web.model.ChocoVingsu;
import kr.co.web.model.CookieVingsu;
import kr.co.web.model.FruitVingsu;
import kr.co.web.model.RedBeanVingsu;
import kr.co.web.model.Vingsu;
import kr.co.web.model.VingsuMachine;
@WebServlet("/make")
public class VingsuController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String vingsu = req.getParameter("vingsu");
System.out.println(vingsu);
VingsuMachine vm = new VingsuMachine(vingsu);
Vingsu vs = null; //Vingsu vs = new Vingsu(); / vs = null;
String result = "";
switch (vingsu) {
case "팥빙수":
vs = new RedBeanVingsu();
result = vm.makeVingsu(vs);
break;
case "초코빙수":
vs = new ChocoVingsu();
result = vm.makeVingsu(vs);
break;
case "쿠키빙수":
vs = new CookieVingsu();
result = vm.makeVingsu(vs);
break;
case "과일빙수":
vs = new FruitVingsu();
result = vm.makeVingsu(vs);
break;
}
req.setAttribute("result", result);
RequestDispatcher dis = req.getRequestDispatcher("index.jsp");
dis.forward(req, resp);
}
}
다형성(Polymorphism)
- OOP의 주요 특징 중 하나임
- 부모가 같은 class는 동일한 Type으로 들어 갈 수 있음
- 특정 Interface를 구현받은 class가 해당 Interface형태로 들어갈 수도 있음
- Fire
package kr.co.web.model;
public class Fire extends Spell{
@Override
public String casting() {
return "화염 " + super.casting();
}
}
- Ice
package kr.co.web.model;
public class Ice extends Spell{
@Override
public String casting() {
return "얼음 " + super.casting();
}
}
- Light
package kr.co.web.model;
public class Light extends Spell{
@Override
public String casting() {
return "번개 " + super.casting();
}
}
- Spell
package kr.co.web.model;
public class Spell {
public String casting() {
return "속성 마법 사용";
}
}
- index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<style></style>
</head>
<body>
<form action="cast">
<select name="element">
<option value="fire">불속성</option>
<option value="ice">얼음속성</option>
<option value="light">번개속성</option>
</select>
<input type="submit" value="마법사용"/>
</form>
<h3>${msg}</h3>
</body>
<script></script>
</html>
- MageController
- 부모클래스인 Spell클래스를 객체화하여 변수에 자식클래스 객체를 넣음
package kr.co.web.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.co.web.model.Fire;
import kr.co.web.model.Ice;
import kr.co.web.model.Light;
import kr.co.web.model.Spell;
@WebServlet("/cast")
public class MageController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String param = req.getParameter("element");
System.out.println(param);
String msg = "";
Spell spell = null;
switch (param) {
case "fire":
spell = new Fire();
break;
case "ice":
spell = new Ice();
break;
case "light":
spell = new Light();
break;
}
msg = spell.casting();
System.out.println(msg);
req.setAttribute("msg", msg);
RequestDispatcher dis = req.getRequestDispatcher("index.jsp");
dis.forward(req, resp);
}
}
Polymorphism(다형성)의 장점
- 부모를 상속받는 객체들을 담을 변수를 여러개 만들지 않아도 됨(부모클래스or인터페이스를 객체화하여 사용)
- 부모객체 형태로 매개변수를 받아 들어오는 변수의 폭을 넓힐 수 있음(부모객체로 자식객체를 다 받을 수 있음)
- 다형성은 상속관계 뿐 아니라 구현 관계에서도 동작
- Car(부모)
package kr.co.web.model;
public class Car {
public String run() {
return " 자동차를 운전합니다.";
}
}
- Benz(자식)
package kr.co.web.model;
public class Benz extends Car {
@Override
public String run() {
return this.getClass().getSimpleName() + super.run();
}
}
- BMW(자식)
package kr.co.web.model;
public class BMW extends Car {
@Override
public String run() {
return this.getClass().getSimpleName() + super.run();
}
}
- Audi(자식)
package kr.co.web.model;
public class Audi extends Car {
@Override
public String run() {
return this.getClass().getSimpleName() + super.run();
}
}
- Ferrari(자식)
package kr.co.web.model;
public class Ferrari extends Car {
@Override
public String run() {
return this.getClass().getSimpleName() + super.run();
}
}
- Racer(Car를 매개변수로 받음)
- Car를 상속받는 객체면 다 들어올 수 있음
- 사용할 차량을 추가하고 싶다면 Car를 상속받는 객체만 추가하면 됨
package kr.co.web.model;
public class Racer {
//레이서 클래스에 드라이브 메서드를 선언하여 매개변수로 Car타입의 변수를 받도록 했습니다.
//매개변수로 올 수 있는 Car타입의 변수는 Car타입을 상속받는 자식객체인 benz,bmw,audi,ferrari입니다.
public String drive(Car car) {
return car.run();
}
//Car 클래스를 이용하여 규격화하지 않고 각각의 차량 클래스를 구현할 경우
//차량이 추가될 때 마다 메서드를 추가해 오버로딩해주어야 해서 번거로움이 있기 때문에
//대형 프로젝트를 진행할 경우에는 하나의 타입으로 자식 객체들을 불러올 수 있기 때문에 다형성을 이용하는 것이 유용합니다.
}
- index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<style></style>
</head>
<body>
//form태그의 action속성을 통해 데이터를 전달할 서버를 "drive"로 지정해주었습니다.
<form action="drive">
<select name="car">
<option value="benz">BENZ</option>
<option value="bmw">BMW</option>
<option value="audi">AUDI</option>
<option value="ferrari">FERRARI</option>
</select>
<input type="submit" value="운전"/>
</form>
<h3>${msg}</h3>
</body>
<script></script>
</html>
- CarController
package kr.co.web.Carcontroller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.co.web.model.Audi;
import kr.co.web.model.BMW;
import kr.co.web.model.Benz;
import kr.co.web.model.Ferrari;
import kr.co.web.model.Racer;
//어노테이션 웹서블릿으로 url패턴을 드라이브로 매핑해주었습니다.
@WebServlet("/drive")
public class CarController extends HttpServlet {
//이 클래스는 HttpServlet을 상속받았고
//파라매터 값을 get방식으로 받기 때문에 doget메서드를 오버라이드 해주었습니다.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//인덱스에서 넘어오는 car라는 이름의 파라매터 값을 car변수를 선언해 담아주었습니다.
String car = req.getParameter("car");
//System.out.println(car);
//레이서 클래스를 객체화하여 racer 변수에 담아주었고
Racer racer = new Racer();
//인덱스로 보내 줄 값을 담기 위해 result 변수를 선언해주었습니다.
String result = null;
//car변수에 들어온 값이 문자열 benz와 동일할 경우
//racer객체의 드라이브 메서드에 car객체를 상속받는 benz를 객체화하여 매개변수로 넣어 실행시켜준 후
//반환값을 result 변수에 담아주었습니다.
if(car.equals("benz")) {
result = racer.drive(new Benz());
}else if(car.equals("bmw")) {
result = racer.drive(new BMW());
}else if(car.equals("audi")){
result = racer.drive(new Audi());
}else {
result = racer.drive(new Ferrari());
}
//ystem.out.println(result);
req.setAttribute("msg", result); //request객체에 msg라는 이름으로 result 값을 담아주었고
//dis라는 변수에 request객체의 getRequestDispatcher메서드를 이용하여 이동할 경로를 index.jsp로 지정해주었습니다.
RequestDispatcher dis = req.getRequestDispatcher("index.jsp");
dis.forward(req, resp);
//forward함수를 통해 request 객체와 response 객체를 index.jsp로 보내주었습니다.
}
}
Promotion & Casting
- 묵시적 형변환(Promotion) : 자식 클래스가 부모 클래스 형태로 들어가는 것
- 명시적 형변환(Casting) : 자식의 형태로 되돌아 가는 것
다형성의 단점
- 부모형태의 변수에 들어가면 자식 고유의 기능을 쓸 수 없음
- 고유기능을 사용하고 싶은 경우 casting을 통해 자식 형태로 되돌아 가야함(되돌아 갈 때 원형을 잘 찾아가야함)
- 다형성을 사용하려면 오버라이딩한 메서드만 사용하는 것이 좋음
'코딩도전기 > MVC' 카테고리의 다른 글
CODO Day23_JAVA_MVC(Exception) (0) | 2023.03.06 |
---|---|
CODO Day22_JAVA_MVC(String) (0) | 2023.03.06 |
CODO Day19_JAVA_MVC(Interface 다중 구현/익명객체/Interface 상속) (0) | 2023.02.27 |
CODO Day18_JAVA_MVC(Abstract(추상화)) (0) | 2023.02.24 |
CODO Day17_JAVA_MVC(Model2/상속*) (0) | 2023.02.23 |