우리가 소프트웨어 개발자가 되기 위해선 소프트웨어 디자인 패턴에 대한 이해가 필요하다. 그렇기 때문에 많은 기업에서 소프트웨어 디자인 패턴에 대한 이해가 있거나 직접 설계, 적용해본 경험이 있는 사람을 원하고 있다.
아키텍처 패턴을 적용해야 하는 이유
- 시행착오를 줄여 개발 시간을 단축 시키고, 고품질의 소프트웨어를 생산할 수 있습니다.
- 검증된 구조로 개발하기 때문에 안정적인 개발이 가능합니다.
- 이해관계자들이 공통된 아키텍처를 공유할 수 있어 의사소통이 간편해집니다.
- 시스템의 구조를 이해하는 것이 쉬워 개발에 참여하지 않은 사람도 손쉽게 유지보수를 수행할 수 있습니다.
- 시스템의 특성을 개발 전에 예측하는 것이 가능해집니다.
MVC (Model - View - Controller)
MVC Pattern은 가장 많이 사용되는 Pattern이다. 사용자가 Controller를 통해 Model을 변화시키면 View가 업데이트 된다.
MVC는 응용 프로그램을 세 가지의 구성요소로 나눈다.
- Model - Model은 데이터일 뿐이며 애플리케이션의 데이터, 논리 및 규칙을 직접 관리한다. 즉 Model은 앱의 데이터 관리를 담당한다.
- View - MVC에서 View는 UI 디자인일 뿐이며, USER 화면에 데이터를 표시하는 방법이다. View는 특정 방식으로 데이터를 표시하는 것을 의미한다.
- Controller - Controller는 일반적으로 MVC의 Controller에서 발생하는 이벤트 처리, 탐색, Model과 View 간 통신과 같이 사용자가 수행하는 모든 작업 / 이벤트를 제어하는 부분이다. Controller는 입력을 수신하고 유효성을 검사한 후 검사한 입력을 모델에 전달한다.
장점 | 단점 |
|
|
MVP (Model - View - Presenter)
MVP 패턴은 MVC에서 파생된 패턴이다. 역할은 대부분 비슷한데 MVC 패턴의 Controller에 해당하는 부분이 Presenter가 되며 MVC 패턴에서는 View에서 Model로 직접 데이터가 전달되어 의존관계를 갖는다는 단점을 Presenter를 통해 해결한다는 점이 특징이다.
MVP는 응용 프로그램을 세 가지의 구성요소로 나눈다.
- Model - Model은 사용자 인터페이스에 표시되거나 실행될 데이터를 정의하는 인터페이스이다.
- View - View는 데이터를 표시하고 사용자 명령 이벤트를 Presenter에게 전달하여 해당 데이터에 따라 작동하도록 하는 수동 인터페이스이다.
- Presenter- Presenter는 Model과 View에 따라 작동하며, Model에서 데이터를 검색하고 View에 표시하기 위해 형식을 지정한다. Presenter와 View는 1:1 관계를 갖는다.
장점 | 단점 |
|
|
MVP (Model - View - Presenter) 구현
Android Studio에 Kotlin을 이용해서 MVP Pattern으로 아주 간단한 로그인 기능을 구현 해보도록 하겠다(여기서는 고객의 Email과 Password를 받아서 유효성 검사를 마친 후 Toast메시지를 보내주는 기능까지 구현 할 예정이다). 우리는 android project에 3개의 package를 생성할 것이다.
Model 구현
MVP를 구현할 때 가장 먼저 해야할 것은 Model을 구현하는 것이다. 이번에 만들 로그인 기능은 email, password만 입력받을것이다. 그리고 데이터 유효성 검사를 진행한다. 각 데이터 유효성 검사에 따른 결과를 Int값으로 Presenter로 반환하여 Presenter에서 이벤트를 처리하게 된다.
interface IUser {
fun getEmail(): String?
fun getPassword(): String?
fun isValid(): Int
}
class User(
private val email: String?,
private val password: String?
) : IUser {
override fun getEmail(): String? {
return email
}
override fun getPassword(): String? {
return password
}
override fun isValid(): Int {
return if(TextUtils.isEmpty(getEmail()))
0
else if(!Patterns.EMAIL_ADDRESS.matcher(getEmail()!!).matches())
1
else if(TextUtils.isEmpty(getPassword()))
2
else if(getPassword()?.length!! <=6)
3
else
-1;
}
}
Presenter 구현
Presenter는 사용자가 로그인을 하기 위한 작업을 하는 장소이다. 사용자가 View를 통한 Presenter 작업을 하고 Presenter에서는 입력을 수신하고 모델에서 유효성을 검사한 후 Presenter가 View에 메시지를 띄우게 된다.
interface IPresenter {
fun OnLogin(email: String?, password: String?)
}
class Presenter(
private val loginView: IView
):IPresenter {
override fun OnLogin(email: String?, password: String?) {
val user = User(email, password)
when (user.isValid()) {
0 -> {
loginView.OnLoginError("Please enter Email");
}
1 -> {
loginView.OnLoginError("Please enter A valid Email");
}
2 -> {
loginView.OnLoginError("Please enter Password");
}
3 -> {
loginView.OnLoginError("Please enter Password greater the 6 char");
}
else -> {
loginView.OnLoginSuccess("login Successful");
}
}
}
}
View 구현
View는 User가 데이터를 입력하는 UI 부분이다. 이 화면에서 작업한 내용을 Presenter가 작업할 수 있도록 데이터를 전달한다. 그리고 작업한 결과물을 User에게 다시 보여준다.
interface IView {
fun OnLoginSuccess(message: String?)
fun OnLoginError(message: String?)
}
class MainActivity : AppCompatActivity(), IView {
private var mBinding: ActivityMainBinding? = null
private val binding get() = mBinding!!
var email: EditText? = null
var password: EditText? = null
var loginb: Button? = null
var loginPresenter: IPresenter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
email = findViewById(R.id.edtUserName)
password = findViewById(R.id.edtPassword)
loginb = findViewById(R.id.mButtonLogin)
loginPresenter = Presenter(this)
loginb?.setOnClickListener {
(loginPresenter as Presenter).OnLogin(
email?.text.toString(),
password?.text.toString().trim()
)
}
}
override fun OnLoginSuccess(message: String?) {
Toast.makeText(this,message, Toast.LENGTH_LONG).show()
}
override fun OnLoginError(message: String?) {
Toast.makeText(this,message, Toast.LENGTH_LONG).show()
}
}
MVP 패턴의 전체 코드는 아래의 Github에 있습니다.
Reference