android 使用分层架构企业应用(一)
背景:在用android开发企业应用的时候,发现按照传统的模式开发的代码结构比较差,业务逻辑处理与Activity是放在一起处理的,结构不清晰,类与类之间的耦合度较高,类的功能复杂,导致单元测试也很难开展;所以就有办法保证这个版本的稳定性,于是我跟我的团队都没有信心。因为我压根不知道程序什么时候会无缘无故报出一个bug,我总结一下原因是对过程缺乏必要的跟踪,导致业务行为模糊。我需要用敏捷管理的思想解决这些问题,所以我就开始重构了。
重构的目标:
采用分层架构思想将类解耦,使类遵循单一职责原则。加入单元测试以保证过程跟踪。加入自动化构建工具并集成代码检查工具。加入持续集成输入单元测试结果及代码覆盖率。
具体实现:
将业务逻辑处理单独分离出来,并与Context分离,使其成为与android无关的可独立运行的类如:
SessionManagerService.java
public interface SessionManagerService {// 用户登录public String login(User user)throws RequestError;}public class SessionManagerServiceTest extends AndroidTestCase {private SessionManagerService sms;@Overrideprotected void setUp() throws Exception {super.setUp();sms = new SessionManagerServiceImpl();}/** * 测试登录成功 * * @throws Exception */@LargeTestpublic void testLoginSuccess() throws Exception {User user = new User();user.setUserName("qnlpkuge");user.setPassword("111111");String result = sms.login(user);assertEquals("true", result);}/** * 测试用户名不存在 * * @throws Exception */@LargeTestpublic void testUserNotExist() throws Exception {User user = new User();user.setUserName("qnlpkugedfswe");user.setPassword("111111sdf");String result = sms.login(user);assertTrue(!"true".equals(result));assertTrue(result.contains("用户名或密码错误"));}/** * 测试密码错误 * * @throws Exception */@LargeTestpublic void testPasswordError() throws Exception {User user = new User();user.setUserName("qnlpkuge");user.setPassword("111111sdfa");String result = sms.login(user);assertTrue(!"true".equals(result));assertTrue(result.contains("密码错误"));} /** * 异常测试 */public void testValidate() {try {User user = new User();user.setUserName("qnlpkuge");sms.login(user);fail("Should raise an RequestError");} catch (RequestError e) {assertEquals("用户名或密码不能为空!",e.getError());assertTrue(true);}}}public class LoginActivityTest extendsActivityInstrumentationTestCase2<LoginActivity> {private Solo solo;public LoginActivityTest() {super("com.goosun.view", LoginActivity.class);}public void setUp() throws Exception {solo = new Solo(getInstrumentation(), getActivity());}public void testLogin() throws Exception {solo.clearEditText(0);solo.enterText(0, "admin");solo.clearEditText(1);solo.enterText(1, "admin");getActivity().runOnUiThread(new Runnable() {@Overridepublic void run() {ImageButton btn = (ImageButton) getActivity().findViewById(com.tianque.seed.R.id.login_option);btn.requestFocus();}});solo.clickOnImageButton(0);Activity f = getInstrumentation().waitForMonitorWithTimeout( getInstrumentation().addMonitor(MainGrid.class.getName(), null, false), 9); assertNotNull(f);assertEquals(getActivity().getString(R.string.main_grid), solo.getCurrentActivity().getTitle().toString());Assert.assertTrue(solo.searchText("泡妞管理系统"));}@Overridepublic void tearDown() throws Exception {getActivity().finish();}}