ãã®èšäºã§ã¯ã代æ¿ãã«ãã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãæé©åããéçºããã»ã¹ã«å®³ãäžããã«ããããç¶æããæ¹æ³ã瀺ããŸãã
ç§ãã¡ã¯äœãæçããŠããŸããïŒ
ãã«ããã©ãããã©ãŒã ã¢ããªã±ãŒã·ã§ã³ãéçºããå Žåãéçºè ã¯ãã©ãããã©ãŒã ã®1ã€ã§ã®ã¿å®è¡ãããã³ãŒããåŠçã§ããŸãããä»ã®ãã©ãããã©ãŒã ã§èµ·åããå Žåã¯éè·ãšãªããŸãã ãã®ååšã«å ããŠããã®ãããªã³ãŒãã¯ç¢ºãã«ãããžã§ã¯ãã«åãè² æ ãšãã®ãã¹ãŠã®äŸåé¢ä¿ããããããŸãã ããèªäœã¯ããŸãè¯ãããšã§ã¯ãããŸããããAndroidã®éçºã®è©³çŽ°ïŒã65kã®åé¡ããèãããšãããŠã³ããŒãå¯èœãªãã¡ã€ã«ãµã€ãºãã§ããéãå°ããããããšããã¹ããã©ã¯ãã£ã¹ã§ãããã®ã³ãŒãã§ã¯ãå¿ ãäœããããå¿ èŠããããŸãã ãããŠãããããªããifAndroidïŒïŒãŸãã¯ifAmazonïŒïŒãäœåºŠããã§ãã¯ããããšã¯ãããŸããã
ããªããçµéšè±å¯ãªAndroidéçºè ã§ããã°ãããããProductFlavorã®ãããªAndroid Gradleãã©ã°ã€ã³ã®ãªãã·ã§ã³ã«åºããããããšã§ãããã
ãã¬ãŒããŒïŒè±èªïŒ-å³ãéŠã
ãã®ãªãã·ã§ã³ã䜿çšãããšãåéãããã¬ãŒããŒã®ååã«å¿ããŠããã«ãå ã®ç°ãªããã£ã¬ã¯ããªã®ãã¡ã€ã«ãå«ããåããããžã§ã¯ãã®ä»£æ¿ã¢ã»ã³ããªãäœæã§ããŸãã å€ãã®å ŽåãProductFlavorã¯ããããçš®é¡ã®ããã©ã³ãã£ã³ã°ãã¢ããªã±ãŒã·ã§ã³ã«äœ¿çšããããªãœãŒã¹ïŒç»åãããã¹ãããªã³ã¯ïŒã眮ãæããŸãã å¥ã®äžè¬çãªã±ãŒã¹ã¯ãåéããããã¬ãŒããŒã®ååãBuildConfig.FLAVORã¯ã©ã¹ã®ãã£ãŒã«ãã«èªåçã«åé¡ããããããã¢ããªã±ãŒã·ã§ã³ããã¢ããŒãžã§ã³ãšå®å šããŒãžã§ã³ã«åå²ããããšã§ãã ãã®å€ã¯åŸã§ã©ã³ã¿ã€ã ã§ç¢ºèªã§ãããã¢çã§ã¯ã¢ã¯ã·ã§ã³ãå®è¡ã§ããŸããã
ãªãœãŒã¹ã ãã§ãªããã³ãŒãã«ããã¬ãŒããŒã«åããããšãã§ããŸãã ãã ããflavor1ã§äœ¿çšãããã³ãŒãã¯ãflavor2ã®ã³ãŒããšã¯å¯Ÿè©±ã§ããªãããšãç解ããå¿ èŠããããŸãã ãããŠãã¡ã€ã³ã¢ãžã¥ãŒã«ã«ããã³ãŒãã¯ãåžžã«äžåºŠã«1ã€ã®flavor'ovããã®ã¿èŠãããšãã§ããŸãã ããã¯ãããšãã°ããããã¬ãŒããŒã§ãŠãŒãã£ãªãã£ã¡ãœããã®ã»ãããèšè¿°ããå¥ã®ãã¬ãŒããŒã§äœ¿çšã§ããªãããšãæå³ããŸãã 代æ¿ãã«ãã®åãæ¿ããã¡ã€ã³ã¢ãžã¥ãŒã«ã«ãã£ãŠèªèãããªãããã«ãã³ãŒããã§ããéãåé¢ããŠãè³¢æãã€éåžžã«æ éã«åé¢ããå¿ èŠããããŸãã äŸåæ§æ³šå ¥ãã¿ãŒã³ã¯éåžžã«åœ¹ç«ã¡ãŸãã ããã«ç¶ããŠãã¡ã€ã³ã¢ãžã¥ãŒã«ã«ã¯äžè¬çãªã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ãæ®ããç¹å®ã®å®è£ ããã¬ãŒããŒã«å解ããŸãã GitHubã§ãªããžããªãæ€çŽ¢ããããã®ç°¡åãªã¢ããªã±ãŒã·ã§ã³ãäœæããŠãããã»ã¹å šäœãèŠãŠãããŸãã
æå
å¿ èŠãªã®ã¯ïŒ
- å ¥åãã£ãŒã«ãããã¿ã³ãããã³çµæã®ãªã¹ããå«ãç»é¢ïŒ1åïŒã
- Github Web APIãæäœããããã®ã¯ã©ã¹ïŒãã®ã¢ãã¯ãšãã®å®éã®å®è£ ïŒåèš2åïŒã
- æ€çŽ¢çµæããã£ãã·ã¥ããããã®ã¯ã©ã¹ïŒå®éã®å®è£ ãšæš¡æ¬å®è£ ïŒåèš2åïŒã
- ã¢ã€ã³ã³ãããã¹ããããã°ã¬ã¹ããŒ-å³ã«ã
ã¢ããªã±ãŒã·ã§ã³ãã¬ã€ã€ãŒã«åå²ããã¢ãããŒããåãããã¬ãŒã³ããŒã·ã§ã³çšã®.viewãããžãã¹ããžãã¯ã¢ãã«çšã®.modelsãã³ã³ãã³ããããã€ããŒã¯ã©ã¹çšã®.dataã®3ã€ã®ããã±ãŒãžãããã«äœæããŸãã ããŒã¿ããã±ãŒãžã«ã¯ããµãŒãã¹ãšã¹ãã¬ãŒãžã®2ã€ã®ããã±ãŒãžãå¿ èŠã§ãã ãã®çµæãæ§é å šäœã¯æ¬¡ã®ããã«ãªããŸãã
ç§ãã¡ã«ãšã£ãŠå¯äžã®ã¢ãã«ã¯ããªããžããªãã§ãã å¿ èŠãªãã®ã¯äœã§ãä¿åã§ããŸããã説æãååãããã³htmlUrlãå¿ èŠã§ãã
次ã«ãAppServiceãªããžããªãæ€çŽ¢ãããµãŒãã¹ã¯ã©ã¹ã®ã€ã³ã¿ãŒãã§ã€ã¹ãå®çŸ©ããŸãããã
public interface AppService { List<Repository> searchRepositories(String query); }
RepositoryStorageæ€çŽ¢ã®çµæããã£ãã·ã¥ããã¯ã©ã¹ã®ã€ã³ã¿ãŒãã§ã€ã¹ãããã«äœæããŸãã
public interface RepositoryStorage { void saveRepositories(String query, List<Repository> repositoryList); List<Repository> getRepositories(String query); }
Applicationã¯ã©ã¹å ã«ãµãŒãã¹ãšãªããžããªãäœæããŠä¿åããŸãã
public class App extends Application { private AppService appService; private RepositoryStorage repositoryStorage; public AppService getAppService() { return appService; } public RepositoryStorage getRepositoryStorage() { return repositoryStorage; } }
æºå段éã§ã¯ãç»é¢èªäœãäœæããçµæã®åä¿¡ãšè¡šç€ºãæžã蟌ãã ãã§ãã ãã¢ã¢ããªã±ãŒã·ã§ã³ã®äžéšãšããŠãAsyncTaskã¯ããã¯ã°ã©ãŠã³ãã®äœæ¥ãè¡ãã®ã«ååã§ãããã奜ã¿ã®ã¢ãããŒãããã€ã§ã䜿çšã§ããŸãã
public class MainActivity extends AppCompatActivity { @Bind(R.id.actionSearchView) Button actionSearchView; @Bind(R.id.recyclerView) RecyclerView recyclerView; @Bind(R.id.searchQueryView) EditText searchQueryView; @Bind(R.id.progressView) View progressView; private SearchResultsAdapter adapter; private AppService appService; private SearchTask searchTask; private RepositoryStorage repositoryStorage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); appService = ((App) getApplication()).getAppService(); repositoryStorage = ((App) getApplication()).getRepositoryStorage(); recyclerView.setLayoutManager(new LinearLayoutManager(this)); adapter = new SearchResultsAdapter(); recyclerView.setAdapter(adapter); searchQueryView.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { querySearch(searchQueryView.getText().toString()); return true; } }); } @OnClick(R.id.actionSearchView) void onActionSearchClicked() { querySearch(searchQueryView.getText().toString()); } private void querySearch(String query) { if (TextUtils.isEmpty(query)) { return; } if (searchTask != null) { return; } InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(searchQueryView.getWindowToken(), 0); searchTask = new SearchTask(); searchTask.execute(query); showProgress(true); } private void showData(List<Repository> repositories) { searchTask = null; adapter.setData(repositories); } private void showProgress(boolean inProgress) { progressView.setVisibility(inProgress ? View.VISIBLE : View.GONE); actionSearchView.setEnabled(!inProgress); } private void showError(@Nullable ApiException exception) { searchTask = null; new AlertDialog.Builder(this) .setMessage(exception != null ? exception.getMessage() : getString(R.string.unknown_error)) .setTitle(R.string.error_title) .show(); } private class SearchTask extends AsyncTask<String, Void, SearchTaskResult> { @Override protected SearchTaskResult doInBackground(String... params) { String q = params[0]; SearchTaskResult result = new SearchTaskResult(); try { result.repositories = appService.searchRepositories(q); repositoryStorage.saveRepositories(q, result.repositories); } catch (ApiException e) { result.exception = e; //try to show some cached results result.repositories = repositoryStorage.getRepositories(q); } return result; } @Override protected void onPostExecute(SearchTaskResult result) { if (result.exception != null) { showError(result.exception); } showData(result.repositories); showProgress(false); } } private class SearchTaskResult { List<Repository> repositories; ApiException exception; } }
ã¢ããã¿ã®å®è£ ãšãã¢ãããžã§ã¯ãå šäœã¯ã GitHubã§è¡šç€ºã§ããŸãã
ãã®æ®µéã§ã¯ããããžã§ã¯ãã¯ãã§ã«ã³ã³ãã€ã«ããã³èµ·åã§ããŸãããããã¯æå³ããããŸãããAppServiceããã³RepositoryStorageã€ã³ã¿ãŒãã§ãŒã¹ã®å®è£ ãäœãæžããŠããªãã®ã§ããããå®è¡ããæã§ãã
å³ãè¿œå
ãŸãããããžã§ã¯ãã®ã¡ã€ã³ã¢ãžã¥ãŒã«ã§build.gradleãéããããã«ãã¬ãŒããŒãè¿œå ããå¿ èŠããããŸãã ããšãã°ã ãmockãããprodããšåŒã³ãŸããã
productFlavors { mock {} prod {} }
buildTypes {...}ãšåãã¬ãã«ã§ã Androidã»ã¯ã·ã§ã³{...}ã« è¿œå ããå¿ èŠããããŸãã
ãã®åŸãå¿ ã[ãããžã§ã¯ããGradleãã¡ã€ã«ãšåæ]ãã¿ã³ãã¯ãªãã¯ããŠãã ããã
åæãå®äºãããšããã«ã[ããªã¢ã³ãã®ãã«ã]ãŠã£ã³ããŠã«æ°ãããã¬ãŒããŒã衚瀺ãããŸãã
mockDebugãéžæããŸãã
ãããžã§ã¯ãã§è£œåãã¬ãŒããŒãå®çŸ©ãããã mainãšåãã¬ãã«ã§åãååã®ãã£ã¬ã¯ããªãäœæã§ããŸãã äžéšã®ãã¬ãŒããŒã®ã¢ã»ã³ããªäžã«ããããã®ãã£ã¬ã¯ããªãããã¡ã€ã«ãååŸãããŸãã
ã¢ãã¯ãã©ã«ããŒãè¿œå ãããã®äžã®ãµãŒãã¹ãšã¹ãã¬ãŒãžããã±ãŒãžã®æ§é ãç¹°ãè¿ããŸãã
æåŸã«ãã€ã³ã¿ãŒãã§ã€ã¹ã®ã¢ãã¯ãéå§ã§ããŸãã
public class AppServiceImpl implements AppService { @Override public List<Repository> searchRepositories(String query) { if (query.equals("error")) { throw new ApiException("Manual exception"); } List<Repository> results = new ArrayList<>(); for (int i = 1; i <= 10; i++) { results.add(new Repository("Mock description " + i, "Mock Repository " + i, "http://mock-repo-url")); } return results; } } public class MockRepositoryStorage implements RepositoryStorage { @Override public void saveRepositories(String q, List<Repository> repositoryList) {} @Override public List<Repository> getRepositories(String q) { return null; } }
ã芧ã®ãšãããã¢ãã¯ãµãŒãã¹ã¯éåžžã«æçãª10ã®ãªããžããªã¢ãã«ãæäŸããã¢ãã¯ã¹ãã¬ãŒãžã¯ãŸã£ããäœãããŸããã Appã¯ã©ã¹ã§ããããåæåããŸãã
@Override public void onCreate() { super.onCreate(); appService = new AppServiceImpl(); repositoryStorage = new MockRepositoryStorage(); }
ããã§ãã¢ããªã±ãŒã·ã§ã³ãäœæããŠèµ·åããæºåãæŽããŸããã ããã§ãUIã®åäœããã¹ãããã³èª¿æŽã§ããŸãã ããã§ãã€ã³ã¿ãŒãã§ã€ã¹ã®çã®å®è£ ã«é²ãããšãã§ããŸãã
[ããªã¢ã³ãã®ãã«ã]ãŠã£ã³ããŠã§prodDebugãªãã·ã§ã³ãéžæãã ã¢ãã¯ãã©ã«ããŒãšåæ§ã«ãåãããã±ãŒãžãšã¯ã©ã¹ã§prodãã©ã«ããŒãäœæããŸãã
ãããã¯ãŒã¯ãªã¯ãšã¹ãã«ã¯retrofit2ã䜿çšããŸããAppServiceImplã®å®è£ å ã§æ©èœããŸãã
public class AppServiceImpl implements AppService { private final RetroGithubService service; public AppServiceImpl() { service = new Retrofit.Builder() .baseUrl("https://api.github.com/") .addConverterFactory(GsonConverterFactory.create()) .build().create(RetroGithubService.class); } @Override public List<Repository> searchRepositories(String query) { Call<ApiRepositorySearchEntity> call = service.searchRepositories(query); try { Response<ApiRepositorySearchEntity> response = call.execute(); if (response.isSuccess()) { ApiRepositorySearchEntity body = response.body(); List<Repository> results = new ArrayList<>(); RepositoryMapper mapper = new RepositoryMapper(); for (RepositoryEntity entity : body.items) { results.add(mapper.map(entity)); } return results; } else { throw new ApiException(response.message()); } } catch (Exception e) { throw new ApiException(e); } } } public interface RetroGithubService { @GET("search/repositories") Call<ApiRepositorySearchEntity> searchRepositories(@Query("q") String query); }
ã³ãŒããããããããã«ããã«ããŒã¯ã©ã¹ãããã«äœæããŸããã *å¿çã解æããããã®ãšã³ãã£ãã£ãšãå¿çããªããžããªã¢ãã«ã«ãããã³ã°ããããã®RepositoryMapper ã
RepositoryEntityãRepositoryMapperãRetroGithubServiceãªã©ããµãŒããŒãšã®å®éã®äœæ¥ã«é¢é£ãããã¹ãŠã®ã¯ã©ã¹ã¯ããprodããã¬ãŒããŒãã©ã«ããŒã«ããããšã«æ³šæããŠãã ããã ã€ãŸããã¢ãã¯ãªã©ã®ä»ã®ãã¬ãŒããŒãæ§ç¯ããå Žåããããã®ã¯ã©ã¹ã¯çµæã®apkãã¡ã€ã«ã«å ¥ããããŸãã ã
泚ææ·±ãèªè ã¯ããµãŒããŒã§å®éã®äœæ¥ãå®è£ ããã¯ã©ã¹ã®ååãšããã«å¯Ÿå¿ããæš¡æ¬ã®ååãåãã§ããAppServiceImpl.javaã«æ°ä»ããããããŸãã ã ããã¯æå³çã«è¡ããããã®ã§ãããã«ãããã¡ã€ã³ãã©ã«ããŒã«ããã¡ã€ã³ãããžã§ã¯ãã³ãŒãã®ãã¬ãŒããŒãå€æŽããéã«å€æŽããå¿ èŠã¯ãããŸããã ã¢ãã¯ãã¬ãŒããŒãéžæãããšãã¢ããªã±ãŒã·ã§ã³ã¯ã¢ãã¯ãã©ã«ããŒã«ããAppServiceImplã¯ã©ã¹ã衚瀺ãã prodãã©ã«ããŒã«ããã¯ã©ã¹ã衚瀺ããŸããã åæ§ã«ãéžæããããã¬ãŒããŒprodã䜿çšããŸãã
åæ§ã«æ³šææ·±ãèªè ã¯ããã£ãã·ã¥å®è£ ã¯ã©ã¹MockRepositoryStorageãåŒã³åºã ããããå°å°ããå¯èœæ§ãããããšã«æ°ä»ããããããŸããã ãããããããå®è£ ã¯ã©ã¹ã®ç°ãªãååãšãããã®ããããã«ç°ãªãã³ã³ã¹ãã©ã¯ã¿ãŒãæã€ããšãã§ããæ¹æ³ã®ãªãã·ã§ã³ã®1ã€ã瀺ãããšãæå³çã«ããŸããã
ããªãã¯ã¯åºæ¬çã«ç°¡åã§ããç°ãªããã¬ãŒããŒã«å¯ŸããŠåãååã®RepositoryStorageBuilderã¯ã©ã¹ãäœæããŸã ãããã«ããããã¬ãŒããŒã«å¿ããŠãç®çã®å®è£ ãæäŸãããŸãã
productFlavor = prod
public class RepositoryStorageBuilder { private int maxSize; public RepositoryStorageBuilder setMaxSize(int maxSize) { this.maxSize = maxSize; return this; } public RepositoryStorage build() { return new InMemoryRepositoryStorage(maxSize); } }
productFlavor =ã¢ãã¯
public class RepositoryStorageBuilder { public RepositoryStorageBuilder setMaxSize(int maxSize) { return this; } public RepositoryStorage build() { return new MockRepositoryStorage(); } }
ãããŠãã¢ããªã±ãŒã·ã§ã³ã®äž¡æ¹ã®åæåã«å ±éïŒ
@Override public void onCreate() { super.onCreate(); ... repositoryStorage = new RepositoryStorageBuilder() .setMaxSize(5) .build(); }
ããã§ãäœæ¥ã®ãæ£çŽãªãå®è£ ã¯å®äºãããšèŠãªãããšãã§ããŸãããããã§åæ¢ãããšãProductFlavorã®å šæ©èœã䜿çšã§ããªããªããŸãã å®éã«ã¯ã äŸåé¢ä¿ã»ã¯ã·ã§ã³ã§å®£èšãããŠããæ€çŽ¢ã®æ£çŽãªå®è£ ã§äœ¿çšãããã©ã€ãã©ãªã¯ãéžæããããã¬ãŒããŒã«é¢ä¿ãªããã¢ã»ã³ããªã«åé¡ãããŸãã 幞ããªããšã«ãã³ã³ãã€ã«æã«åèªã®åã«ç®çã®ãã¬ãŒããŒåãè¿œå ããããšã§ãäŸåé¢ä¿ããšã«ãã«ãã§ããã衚瀺ãããã©ãããåå¥ã«æå®ã§ããŸãã
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' prodCompile 'com.squareup.retrofit:retrofit:2.0.0-beta2' prodCompile 'com.squareup.retrofit:converter-gson:2.0.0-beta2' prodCompile 'com.google.code.gson:gson:2.5' compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:recyclerview-v7:23.1.1' compile 'com.jakewharton:butterknife:7.0.1' }
ããã«ãããã¢ããªã±ãŒã·ã§ã³ã®ãµã€ãºãå°ãããªãã ãã§ãªããäŸåé¢ä¿ãéåžžã«å€§ããå Žåã¯ãã¢ã»ã³ããªã®é床ãåäžããŸãã
ãªãã§ïŒ
Dagger2ãRoboguiceããããæåã§èšè¿°ã§ããå Žåã§ãããã®ã¢ãããŒããäŸåæ§æ³šå ¥ã«äœ¿çšããã®ã¯ãªãã§ããïŒ
ãã¡ããããã®ã¢ãããŒãã®äž»ãªéãã¯ãå®è£ ã®å®çŸ©ãã³ã³ãã€ã«æ®µéã§è¡ãããå®éã«äœ¿çšãããäŸåé¢ä¿ã®ã¿ããã«ãã«çµã¿èŸŒãŸãããã®åŸã®ãã¹ãŠã®çµæãçããããšã§ãã åæã«ããæ°ã«å ¥ãã®DIãã¬ãŒã ã¯ãŒã¯ãåŒãç¶ã䜿çšããŠãå®è¡æã®äŸåé¢ä¿ãå€æã§ããŸãã
å®è©±
åé ã§è¿°ã¹ãããã«ãAndroidãšAmazon FireOSã®2ã€ã®ãã©ãããã©ãŒã çšã®ãããžã§ã¯ãã®1ã€ãããã«éçºããŠããŸãã ãããã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã¯ã»ãšãã©äºãã«äŒŒãŠããŸãïŒãã¡ããã誰ãšèª°ã䌌ãŠããããç解ããŠããŸã:)ïŒããããã·ã¥éç¥ã®ç¬èªã®å®è£ ãšã¢ããªå è³Œå ¥ã®ããã®ç¬èªã®ã¡ã«ããºã ããããŸãã ãããããã³ãã®ä»ã®ãã©ãããã©ãŒã ã®éãã«ã€ããŠã¯ããã¢ãããžã§ã¯ããšåæ§ã«ãã¡ã€ã³ã¢ãžã¥ãŒã«ã«ã¯å ±éã®ã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ãæ®ããŸããïŒããã·ã¥ã¡ãã»ãŒãžãµãŒããŒã§ã®åãããã€ã¹ç»é²ãåããµãã¹ã¯ãªãã·ã§ã³è³Œå ¥ããã»ã¹ãããã³ç¹å®ã®ãã©ãããã©ãŒã äŸåã®å®è£ ã察å¿ãããã¬ãŒããŒã«æ ŒçŽããŸãã
ç§ãã¡ã¯é·ãéãã®ã¢ãããŒãã䜿çšããŠããã次ã®ãããªäœ¿çšæãå ±æããæºåãã§ããŠããŸãã
é·æ
- ãã©ãããã©ãŒã ã§äœ¿çšãããããšã®ãªãããã¹ãŠã®ã³ãŒããšãã®äŸåé¢ä¿ã®çµæã®ã¢ã»ã³ããªã®äŸå€ã
- ãããžã§ã¯ãã®ãã«ãæéãççž®ããŸãããªããªã éžæãããïŒã¢ã¯ãã£ããªïŒãã¬ãŒããŒã®ã¿ãåéãããŸãã
- IoCã䜿çšããããšã®ãã¹ãŠã®å©ç¹ãã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããåé¢ããif isAndroidïŒïŒã®ã¹ã¿ã€ã«ã§èŠèŠããåå²ããªã
çæ
- Android Studioã¯ãéžæããããã¬ãŒããŒãšãã®ãã£ã¬ã¯ããªã®ã¿ãåæã«è¡šç€ºããŸãã ãã®ãããèªåãªãã¡ã¯ã¿ãªã³ã°ãJavaã¯ã©ã¹ã§ã®æ€çŽ¢ãããã³ãªãœãŒã¹ã§ã®æ€çŽ¢ã¯å®å šã«ã¯æ©èœããŸããã éã¢ã¯ãã£ããªãã¬ãŒããŒã«ã¯é©çšãããªããšããæå³ã§ã¯æ©èœããŸããã ãªãã¡ã¯ã¿ãªã³ã°åŸããã¬ãŒããŒãåãæ¿ããŠããã¬ãŒããŒããšã«åå¥ã«ãªãã¡ã¯ã¿ãªã³ã°ãç¹°ãè¿ãå¿ èŠãããå ŽåããããŸãã
ããªããèŠãããšãã§ããããã«ãç§ãã¡ã¯3å以äžã®ãã©ã¹ããããšä¿¡ããŠããŸã:)ãé£äºãã楜ãã¿ãã ããïŒ