Builder, Adapter, Observer์ ๋ํ์ฌ.
โ
Present time : 2018-06-27-WED
Last updated : 2018-07-05-THURS
- [Design Pattern] (http://chuumong.github.io/android/2017/01/16/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4)
- [Builder] (http://jdm.kr/blog/217)
- [Adapter] (http://jusungpark.tistory.com/22)
- [Observer] (http://flowarc.tistory.com/entry/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-%EC%98%B5%EC%A0%80%EB%B2%84-%ED%8C%A8%ED%84%B4Observer-Pattern)
๋ง์ ์ค๋ฌด ํ๋ก๊ทธ๋๋จธ๋ค์ด ์ธ์ ํ ํจ์จ์ ์ธ ์ฝ๋ฉ ๋ฐฉ๋ฒ ๋๋ ๊ตฌ์กฐ.
-
๋ช ํํ๊ณ ๋จ์ํ ์ฝ๋ฉ
-
class๋ function ๋ฑ์ ํ ๊ฐ์ง ๊ธฐ๋ฅ๋ง ํ๋๋ก ์๊ฒ ์ธ๋ถํ ์ํฌ ์ ์์
-
๋์ ์ฌ์ฌ์ฉ์ฑ
-
์ฌ์ด ์ ์ง๋ณด์
-
๋ฆฌ์์ค์ ๋ญ๋น ์ ๊ฑฐ
โ
โ ๋ง์ฝ, (๊ฐ์ธ ํ๋ก์ ํธ + ๋ณํ์ง ์๋ ์๊ตฌ์ฌํญ) ์ด๋ผ๋ฉด ๋์์ธ ํจํด์ ํ์๊ฐ ์๋ค๊ณ ๋งํ ์๋ ์๊ฒ ๋ค.
-
์์ฑ
๊ฐ์ฒด ์์ฑ์ ๋ํด์ ๋ค๋ฃจ๊ณ ์ํฉ์ ์ ์ ํ ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๊ฒ์ด๋ค.
์์ฑ์ ๊ด๋ จ๋ ํจํด์ ์ฌ์ฉํ๋ฉด ์ฝ๊ณ ๊ฐ๋จํ๊ฒ ๊ฐ์ฒด ์์ฑ์ ํ ์ ์๋ค.
-
๊ตฌ์กฐ
๋ ํฐ ๊ตฌ์กฐ๋ฅผ ํ์ฑํ๊ธฐ ์ํด ์ด๋ป๊ฒ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ํฉ์ฑํ๋์ง์ ๊ด๋ จ๋ ํจํด์ด๋ค.
-
ํ์
- ๊ฐ์ฒด์ ํ์๋ฅผ ์กฐ์ง, ๊ด๋ฆฌ, ์กฐํฉํ๋๋ฐ ์ฌ์ฉํ๋ ํจํด
- ๊ฐ์ฒด๋ค์ด ๋ค๋ฅธ ๊ฐ์ฒด์ ์ํธ์์ฉํ๋ ๋ฐฉ์์ ๊ท์
- ๊ฐ๊ฐ ๋ค๋ฅธ ๊ฐ์ฒด๋ค๊ณผ ํต์ ํ๋ ๋ฐฉ๋ฒ๊ณผ ๊ฐ์ฒด์ ์ฑ ์์ ๊ท์ ํ์ฌ ๋ณต์กํ ํ์๋ค์ ๊ด๋ฆฌ ํ ์ ์๋๋ก ํจ
- ๋ ๊ฐ์ฒด ๊ฐ์ ๊ด๊ณ์์๋ถํฐ ์ฑ์ ์ ์ฒด ์ํคํ ์ฒ์๊น์ง ์ํฅ์ ๋ฏธ์นจ
-
์์ฑ
-
Builder
-
Dependency Injection
-
Singleton
-
๊ตฌ์กฐ
- Adapter
- Facade
-
ํ์
-
Command
-
Observer
-
Model View Controller
-
Model View ViewModel
โ
-
๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ํํ๊ฒ ์ฌ์ฉํ๋ ํจํด.
๋ณต์กํ ์ธ์คํด์ค๋ฅผ ์กฐ๋ฆฝํ์ฌ ๋ง๋๋ ๊ตฌ์กฐ.
์์ฑ์์ ํ๋ผ๋ฏธํฐ๊ฐ ๋ง์ ํด๋์ค์ธ ๊ฒฝ์ฐ ๋น๋ ํจํด์ ์ฌ์ฉํ์ฌ ๊ฐ๋ ์ฑ์ ๋์ผ ์ ์์.
Android์์๋
NotificationCompat.Builder
์AlertDialog.Builder
๊ฐ์ ํด๋์ค๋ฅผ ์ฌ์ฉ ํ ๋Builder
ํจํด์ด ๋ํ๋จ
Notification notification =new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_notification)
.setContentIntent(pendingIntent)
.setTicker(message)
.build();
new AlertDialog.Builder(this)
.setTitle("Builder Dialog")
.setMessage("Builder Dialog Message")
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface dialog, int which) {
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface dialog, int which) {
}
})
.show();
โ ์์ฑ์ ์ธ์๊ฐ ๋ง์ ๋๋ Builder ํจํด ์ ์ฉ์ ๊ณ ๋ คํ๋ผ
public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
public static class Builder {
// Required parameters(ํ์ ์ธ์)
private final int servingSize;
private final int servings;
// Optional parameters - initialized to default values(์ ํ์ ์ธ์๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ด๊ธฐํ)
private int calories = 0;
private int fat = 0;
private int carbohydrate = 0;
private int sodium = 0;
public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(int val) {
calories = val;
return this; // ์ด๋ ๊ฒ ํ๋ฉด . ์ผ๋ก ์ฒด์ธ์ ์ด์ด๊ฐ ์ ์๋ค.
}
public Builder fat(int val) {
fat = val;
return this;
}
public Builder carbohydrate(int val) {
carbohydrate = val;
return this;
}
public Builder sodium(int val) {
sodium = val;
return this;
}
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
}
์์ ๊ฐ์ด ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์๋ค.
NutritionFacts.Builder builder = new NutritionFacts.Builder(240, 8);
builder.calories(100);
builder.sodium(35);
builder.carbohydrate(27);
NutritionFacts cocaCola = builder.build();
๋๋ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์๋ ์๋ค.
// ๊ฐ ์ค๋ง๋ค builder๋ฅผ ํ์ดํํ์ง ์์๋ ๋์ด ํธ๋ฆฌํ๋ค.
NutritionFacts cocaCola = new NutritionFacts
.Builder(240, 8) // ํ์๊ฐ ์
๋ ฅ
.calories(100)
.sodium(35)
.carbohydrate(27)
.build(); // build() ๊ฐ ๊ฐ์ฒด๋ฅผ ์์ฑํด ๋๋ ค์ค๋ค.
2-2-1์ ๋น๋ ํจํด์ด๋ผ๋ฉด ๋กฌ๋ณต์ @Builder
Annotation์ผ๋ก ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
@Builder
public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
}
์ฌ์ฉ์ ๋ค์๊ณผ ๊ฐ์ด ํ ์ ์๋ค.
NutritionFacts.NutritionFactsBuilder builder = NutritionFacts.builder();
builder.calories(230);
builder.fat(10);
NutritionFacts facts = builder.build();
๋ฌผ๋ก .
์ฒด์ธ๋ ๋๋ค.
NutritionFacts facts = NutritionFacts.builder()
.calories(230)
.fat(10)
.build();
-
Eclipse + Window
-
Android Studio + Window
โ
-
๊ฐ ์ธ์๊ฐ ์ด๋ค ์๋ฏธ์ธ์ง ์๊ธฐ ์ฝ๋ค.
-
setter
๋ฉ์๋๊ฐ ์์ผ๋ฏ๋ก ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์๋ค. -
ํ ๋ฒ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฏ๋ก ๊ฐ์ฒด ์ผ๊ด์ฑ์ด ๊นจ์ง์ง ์๋๋ค.
-
build()
ํจ์๊ฐ ์๋ชป๋ ๊ฐ์ด ์ ๋ ฅ๋์๋์ง ๊ฒ์ฆํ๊ฒ ํ ์๋ ์๋ค.โ
๊ธฐ์กด์์คํ ์ ์ฒด์์ ์ ๊ณตํ ํด๋์ค
๊ธฐ์กด์์คํ ์ด๋ํฐ ์ ์ฒด์์ ์ ๊ณตํ ํด๋์ค
Android์์ ๋ํ์ ์ผ๋ก Adapterํจํด์ ๋ณด์ด๋ ํด๋์ค๋
RecyclerView.Adapter
RecyclerView.Adapter
ํด๋์ค๋ ๋น์ง๋์ค ๋ก์ง(Model)๊ณผ RecyclerView๋ฅผ ์ฐ๊ฒฐํ๋ ์ญํ
RecyclerView.Adapter
์ ๋ฐ์ดํฐ ์์ดํ ์ ์ ๊ทผํ๊ณ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํ์ฌ ์์ดํ ์ View๋ฅผ ๊ทธ๋ฆฌ๋ ์ญํ ์ ์ํ
public class SampleAdapter extends RecyclerView.Adapter<SampleViewHolder> {
private List<Test> tests;
public SampleAdapter() {
tests = new ArrayList();
}
@Override
public SampleViewHolder onCreateViewHolder(ViewGroup parent, int position) {
// Create View Holder
}
@Override
public void onBindViewHolder(SampleViewHolder holder) {
// View Bind
}
@Override
public int getItemCount() {
return tests.size();
}
public void add(Test item) {
tests.add(item);
}
}
RecyclerVIew
๋ Test
์ ๋ํด์ ๋ฌด์์ธ์ง ๋ชจ๋ฆ.
SampleAdapter
๊ฐ Test
์ RecyclerView
์ ์ฐ๊ฒฐํ๊ธฐ ๋๋ฌธ์ RecyclerVIew
์ Test
์ ๋ํด์ ์ ํ์๊ฐ ์์.
http://jusungpark.tistory.com/22 ์ฐธ๊ณ
-
ํธํ๋์ง ์๋ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ํด๋ผ์ด์ธํธ๋ฅผ ๊ทธ๋๋ก ํ์ฉํ ์ ์์
-
ํด๋ผ์ด์ธํธ์ ๊ตฌํ๋ ์ธํฐํ์ด์ค๋ฅผ ๋ถ๋ฆฌ์ํฌ์ ์์ผ๋ฉฐ, ํฅํ ์ธํฐํ์ด์ค๊ฐ ๋ฐ๋๋๋ผ๋ ๊ทธ ๋ณ๊ฒฝ ๋ด์ญ
์ ์ด๋ํฐ์ ์บก์ํ ๋๊ธฐ ๋๋ฌธ์ ํด๋ผ์ด์ธํธ๋ ๋ฐ๋ ํ์๊ฐ ์์ด์ง.
observer : ๊ด์ฐฐ์
๊ฐ์ฒด์งํฅ ์ค๊ณ๋ฅผ ํ๋ค๋ณด๋ฉด ๊ฐ์ฒด๋ค ์ฌ์ด์์ ๋ค์ํ ์ฒ๋ฆฌ๋ฅผ ํ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
์ํ๋ฅผ ๊ฐ์ง๊ณ ์๋ ์ฃผ์ฒด ๊ฐ์ฒด์ ์ํ์ ๋ณ๊ฒฝ์ ์์์ผ ํ๋ ๊ด์ฐฐ ๊ฐ์ฒด(Observer Object)๊ฐ ์กด์ฌํ๋ฉฐ ์ด๋ค์ ๊ด๊ณ๋ 1:1์ด ๋ ์๋ ์๊ณ 1:N์ด ๋ ์๊ฐ ์๋ค.
์๋ก์ ์ ๋ณด๋ฅผ ๋๊ธฐ๊ณ ๋ฐ๋ ๊ณผ์ ์์ ์ ๋ณด์ ๋จ์๊ฐ ํด์๋ก, ๊ฐ์ฒด๋ค์ ๊ท๋ชจ๊ฐ ํด์๋ก, ๊ฐ ๊ฐ์ฒด๋ค์ ๊ด๊ณ๊ฐ ๋ณต์กํ ์๋ก ์ ์ ๊ตฌํํ๊ธฐ ์ด๋ ค์์ง๊ณ ๋ณต์ก์ฑ์ด ๋งค์ฐ ์ฆ๊ฐํ ๊ฒ์ด๋ค. ์ด๋ฌํ ๊ธฐ๋ฅ์ ํ ์ ์๋๋ก ๊ฐ์ด๋๋ผ์ธ์ ์ ์ํด์ฃผ๋ ๊ฒ์ด ๋ฐ๋ก Observer Pattern์ด๋ค.
๊ฐ์ฒด์์ ๊ด๊ณ๋ฅผ ๋งบ๊ณ ๋์ผ๋ฉฐ ๊ฐ์ฒด์ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ๊ทธ ์ ๋ณด๋ฅผ Observer(Subscribe, ๊ตฌ๋ ์)์๊ฒ ์๋ ค์ฃผ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์.
apiService.getData(someData)
.observeOn(AndroidSchedulers.mainThread())
.subscribe (/* an Observer */);
- ๊ฐ(์ด๋ฒคํธ)๋ฅผ ๋ฐฉ์ถ ํ Observable ๊ฐ์ฒด๋ฅผ ์ ์
- Observable๋ค์ ํ ๋ฒ ๋๋ ์ฐ์์ ์ผ๋ก ์คํธ๋ฆผ, ๊ฐ, ์ด๋ฒคํธ๋ฅผ ๋ฐฉ์ถํจ
- Subscriber๋ ์ด๋ฌํ ๊ฐ์ ์์ ํ๊ณ ๋์ํ ๋๋ก ์๋ต
- ์๋ฅผ๋ค์ด, API ํธ์ถ์ ์์ฑํ๊ณ ์๋ฒ์์ ์๋ต์ ์ฒ๋ฆฌํ Subscriber๋ฅผ ์ง์ ํ ์ ์์
Java์ Swing์ด๋ Android์ View๋ Button ๋ฑ์ ์์ ฏ์ ๊ฐ์ข ์ด๋ฒคํธ๋ฅผ ๋ฐ์ ๋ ์ฐ์ธ๋ค.
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(...) {
// ACTION
}
})
Button์ ํญ์ Click์ด๋ฒคํธ๊ฐ ์์ผ๋ฉฐ, ์ด ์ด๋ฒคํธ๋ OnClickListener ๋ผ๋ ์ธํฐํ์ด์ค๋ก ๊ตฌ์ฑ๋์ด์๋ค.
์ฆ Button์ด๋ผ๋ ๊ฐ์ฒด๊ฐ Publisher๊ฐ ๋๊ณ , OnClickListener๊ฐ Observer๊ฐ ๋๋ค๊ณ ๋ณผ ์ ์๋ค. Button์์ ์ํ๊ฐ ๋ณ๊ฒฝ(ํด๋ฆญ ๋ ๊ฒฝ์ฐ)๋๋ค๋ฉด OnClickListener๋ก ์๋ ค์ค๋ค.
์์ ์์ ์ ๊ฐ์ด Button์ OnClickListener๋ผ๋ Observer๋ฅผ ๋ฑ๋กํ๋ ๊ฒฝ์ฐ๊ฐ ๋ํ์ ์ธ Observer Pattern์ ์ ์ฉํ ๊ฒ์ด๋ค.
- ๋์จํ ๊ฒฐํฉ์ฑ ์ ์ง