• 开发,从需求出发 · 之二 造飞机的工厂


    CD镇楼~~!


    如今。让我们切换到后端开发者的角度看问题。我们须要做的是实现一下这个类,让它返回真实的业务数据。

    package cn.com.sitefromscrath.service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import cn.com.sitefromscrath.entity.Result;
    
    public class SearchService {
    
    	public List search(String keywords) {
    		
    		List results = new ArrayList();
    		results.add(new Result("result 1", "something.................."));
    		results.add(new Result("result 2", "something.................."));
    		results.add(new Result("result 3", "something.................."));
    		results.add(new Result("result 4", "something.................."));
    
    		return results;
    	}
    
    }
    

    因为须要重写这种方法,原来费劲手工录入的模拟数据就得删除掉。显得有点儿可惜,因此,我决定又一次定义一个类,

    package cn.com.sitefromscrath.service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import cn.com.sitefromscrath.entity.Result;
    
    public class SearchServiceInRealBiz extends SearchService {
    	
    	public List search(String keywords) {
    		
    		 List results = new ArrayList();
    		
     		//do sth. 这里是真实业务逻辑,为了不一下子把问题搞复杂,偏离这章的中心思想,我们先相同採用Mock中的返回数据。
    		results.add(new Result("result 1", "something.................."));
    		results.add(new Result("result 2", "something.................."));
                    。

    。。。。

    。。。。

    。。。

    。。。

    。。。

    。。。

     return results;}} <pre>

    注意,这里须要:

    SearchServiceInRealBiz extends SearchService

    以此来迎合java的恶趣味。否则。我们的SearchServlet中的代码:

    SearchService searchService = (SearchService)BeanFactory.getBean("searchService");

    会抛出cast异常。

    插一句,之所以”恶趣味“,主要是个人更偏好”Duck Typing“,比方python。


    如今我能够说明我的标题了。由于我们在第一章 建造了一个工厂。因此。我们仅仅须要调整非常少的代码,就能够让整个系统从模拟状态切换到真实业务状态。

    package cn.com.sitefromscrath;
    
    import cn.com.sitefromscrath.service.SearchService;
    import cn.com.sitefromscrath.service.SearchServiceInRealBiz;
    
    public class BeanFactory {
    	
    	public static Object getBean(String id) {
    		if("searchService".equals(id)) {
    //			return new SearchService();
    			return new SearchServiceInRealBiz();
    		}
    		
    		throw new RuntimeException("cannot find the bean with id :" + id);
    	}
    
    }
    

    我们凝视掉了

    return new SearchService();

    而返回新定义的类:

    return new SearchServiceInRealBiz();

    如今,我确信前端页面会展示真实的数据——这样的确信不须要建立在和前端开发者协调。甚至不须要执行tomcat操作一遍web。

    当然。口说无凭,本着”没有做过測试的代码一定会出问题“的原则,

    public class BeanFactory {
    	
            public static Object getBean(String id) {
    		if("searchService".equals(id)) {
    //			return new SearchService();
    			return new SearchServiceInRealBiz();
    		}
    		
    		throw new RuntimeException("cannot find the bean with id :" + id);
    	}
    	
    	public static void main(String ... arg) {
    		String keywords = "test";
    		SearchService searchService = (SearchService)BeanFactory.getBean("searchService");	
    		List results = searchService.search(keywords);
    		for(int i = 0; i < results.size(); i++) {
    			Result result = (Result) results.get(i);
    			System.out.print("[" + result.title + "]");
    			System.out.println(result.content);
    		}
    	}
    
    }

    
    执行,得到输出结果:
    

    [result 1]something..................
    [result 2]something..................
    [result 3]something..................
    [result 4]something..................
    bingo!

    測试通过。——为了不把问题搞复杂。这里就不採用Junit鸟。:)

    出于java程序猿的”模式“。我决定设计一个接口,这样看起来更java style 一点儿。

    package cn.com.sitefromscrath.service;
    
    import java.util.List;
    
    public interface SearchService {
    	
    	public List search(String keywords);
    
    }
    
    注意。这里我们为了不改动jsp。将接口命名为
    SearchService 

    然后,是一个模拟数据实现类和一个业务数据实现类

    真实:

    package cn.com.sitefromscrath.service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import cn.com.sitefromscrath.entity.Result;
    
    public class SearchServiceInRealBiz implements SearchService {
    	
    	public List search(String keywords) {
    		
    		List results = new ArrayList();
    		
    		//do sth.
    
    		return results;
    	}
    }
    

    模拟:

    package cn.com.sitefromscrath.service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import cn.com.sitefromscrath.entity.Result;
    
    public class SearchServiceMock implements SearchService {
    
    	public List search(String keywords) {
    		
    		List results = new ArrayList();
    		results.add(new Result("result 1", "something.................."));
    		results.add(new Result("result 2", "something.................."));
    		results.add(new Result("result 3", "something.................."));
    		results.add(new Result("result 4", "something.................."));
    
    		return results;
    	}
    
    }
    

    好了,如今看看工厂类,没有什么比工厂更能满足程序猿的控制欲了:)


    package cn.com.sitefromscrath;
    
    import cn.com.sitefromscrath.service.SearchServiceMock;
    import cn.com.sitefromscrath.service.SearchServiceInRealBiz;
    
    public class BeanFactory {
    	
    	public static boolean MOCK = false; 
    	
    	public static Object getBean(String id) {
    		if("searchService".equals(id)) {
    			if(MOCK) {
    				return new SearchServiceMock();
    			} else {
    				return new SearchServiceInRealBiz();
    			}			
    		}
    		
    		throw new RuntimeException("cannot find the bean with id :" + id);
    	}
    
    }
    

    这里我们放了一个开关 : 

    public static boolean MOCK = false; 

    这样,通过控制这个开关,我们就能实现一个便捷的切换。


    ————————————————————————————————————————————————————————————————————————————

    本章该收尾了,俺也恶趣味一把。反复第一章的结束部分:


    嗯,到这里,我们究竟达到了什么目的?有这个必要吗?有这个必要吗?


    除了通过一个开关,保证了对前端恒定(模拟)的数据输出。因此保证了自己的开发工作不干扰前端开发者的开发和測试之外,貌似确实没什么必要。

    BUT...请注意。我们在实现和測试代码的过程中。没有启动tomcat,可是相同达到了”代码/模块可靠性“的保证——我相信。非常多web开发者在开发过程中。最常干的一件事情就是重新启动tomcat,手工运行表单操作。肉眼查看页面输出结果——太慢了,太慢了啊。亲!

    (补充一句,上文提到了junit,我们所做的模拟服务:

    SearchServiceMock 

    也能够使用工具easyMock。有兴趣的同学能够尝试试用一下。


    当然,假设你还是认为看不出必要性。那是由于我们的业务逻辑还不够复杂。


    下一章。我们会试着模拟一个业务流程,把简单的事情搞的更复杂一点儿。


    to be continued....

    
       
    
  • 相关阅读:
    LeetCode 788. Rotated Digits
    LeetCode 606. Construct String from Binary Tree
    LeetCode 13. Roman to Integer
    LeetCode 387. First Unique Character in a String
    LeetCode 520. Detect Capital
    LeetCode 557. Reverse Words in a String III
    RSA加密算法及其与SpringMVC集成
    用phantomjs 进行网页整页截屏
    redis应用场景
    MQ产品比较-ActiveMQ-RocketMQ
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/7003335.html
Copyright © 2020-2023  润新知