图书馆仿真的重构(三)------类的职责讨论与对象文件的封装内容

      再一次的重构,这次就是讨论类的职责和对象文件的封装内容。类的职责,指的是我们一个类到底应该做什么?做多少?以我的图书馆仿真为例,显然,主类的职责之一就是显示结果,就是图书馆图书列表。但是,在图书馆列表这个部分,需要实现很多方法,而这些方法是否都需要在主类里实现呢?就像前面的例子那样,这次我们依然是有三个类:RatingBook,BookDepot和main,那么,它们各自应该承担的职责是什么呢?我们可以将目光先放在那些涉及到RatingBook的方法上。首先,RatingBook就像所有的对象文件一样,应该有设置数据属性和返回数据属性的方法,当然还有构造器。一般,一开始设计类的时候应该遵守的原则就是,职责尽可能简单,这样可读性才会高。

      接着就是BookDepot。这个类的最大职责就是产生Book,但是由于我自己单方面的设定是在一个String数组里随机产生,为了贴近真实情况,需要将一些重复的去除掉。本来这部分的代码是放在主类里,但是后来我将它放在BookDepot中,因为我觉得,这个类最主要的功能就是能够返回一个BookList,那么,作为附加的要求,返回一个不重复的BookList就能减少代码的逻辑冗余(所谓的逻辑冗余,就是一段代码中包含太多不相关的逻辑),这并没有不妥。而且,我这里将它作为静态方法,是因为我需要在两个地方得到bookList,但是如果我要在两个地方都new一个BookDepot,所以我将它变成静态方法,这样就无需每次 使用时都需创建一个根本没有用到的对象。

     最后就是主类。当然,经过上面这样的修改,主类的逻辑已经简洁很多,它最主要的工作就是对List进行加工,这些加工是可以放在主类里的,如果将它们放在BookDepot里,那么这个对象文件承担的职责就过多了,而且有些并不是我们这个对象产生文件应该去处理的,它最主要的功能就是产生我们想要的不重复List,至于这个List的加工,应该交给其他类处理,当然,如果我们想要写个加工类也是可以的,但是这样主类就只是启动加工类而已,这种处理我觉得是将类的职责过分的细分,类的职责的确需要细分,这是重构的很重要的原则,但是盲目的细分并不是一个正确的选择,所以,主类还是必须承担一定的职责。

      综合上述,我认为,类应该承担多少职责,这个问题应该与我们的逻辑分类有关,就像我的例子那样,所有的逻辑可以分为BookList的产生,RatingBook的设置,以及对BookList的加工这三部分,那么,就有三个职责类,然后由这三个职责类来处理这些逻辑。这对于对象文件来说同样适用,对象文件封装的逻辑应该是与其自身相关的逻辑,但是,必须要意识到一点,就是对象文件的逻辑最好不要包含有其他对象的信息,尤其是对象的创建。

       最后,就是想要说一下方法名的命名问题,我认为,可读性高的代码,并不是一定要有详尽的注释,事实上,方法名和参数列表就已经是最好的注释了,只要方法名得当,我们完全可以将方法名当做一个注释来看,所以,方法名是很重要的,当然,方法名是要根据方法的功能和参数列表来决定,这个真的是需要很高的素养才能做到,像是我的例子,就真的是很难达到要求,这需要我们在实践中不断摸索。

      这次的重构,再次暴露了我编程素养极低的弱点,甚至连一些基本的常识都不知道,比如说,一般名字前带有m的是类的成员变量,带有s的是static成员,但是我都不知道,一直以来都是随便命名,可见没有多看别人代码的坏处是如此明显!而且,我还发现,如果在代码创建这个类只是为了调用它里面的一个方法,就没有其他用途,那么,请把这个方法设为static,因为这样就不用每次都创建无用的类实例。

      这个例子远远没有完成,因为它里面还有很多我需要去思考的东西,直到我认为它已经几乎没有问题。

     

public class Library {
    public static void main(String[] args) throws InterruptedException,
            IOException {
        searchBookAndGetResultOfSearch();
    }
private static void searchBookAndGetResultOfSearch(String name) throws IOException { String name = enterAndGetName();
List
<RatingBook> list = getBookListFromZhongZhuanTaiByName(name); List<RatingBook> depotList = BookDepot.createBookListFromDepot(10, 1); List<RatingBook> bookList = getListContainsName(name, depotList); for (RatingBook libraryBook : bookList) { for (RatingBook zhongZhuanTaiBook : list) { if ((libraryBook.getName()) .equals((zhongZhuanTaiBook.getName()))) { libraryBook.setRating(zhongZhuanTaiBook.getRating()); } } } showList("图书馆里的图书列表:", bookList); }
 private static String enterAndGetName() throws IOException {
       
BufferedReader name
= new BufferedReader(new InputStreamReader(System.in));
  String entername
= name.readLine().toLowerCase();
       
return entername;
   }

private static List<RatingBook> getBookListFromZhongZhuanTaiByName( String name) { List<RatingBook> list = BookDepot.createBookListFromDepot(10, 6); List<RatingBook> containsBook = getListContainsName(name, list); showList("中转台图书列表:", list); showList("中转台符合条件的图书:", containsBook); return list; } private static List<RatingBook> getListContainsName(String name, List<RatingBook> list) { List<RatingBook> bookList = new ArrayList<RatingBook>(); for (RatingBook ratingBook : list) { String book = ratingBook.getName().toLowerCase(); if (book.contains(name)) { bookList.add(ratingBook); } } return bookList; } private static void showList(String string, List<RatingBook> list) { sortBookByRating(list); System.out.println(string); for (RatingBook book : list) { System.out.println(book.getName() + "评分:" + book.getRating()); } } private static void sortBookByRating(List<RatingBook> list) { for (int i = 0; i < list.size() - 1; i++) { for (int j = i + 1; j < list.size(); j++) { if ((list.get(i).getRating()) <= (list.get(j).getRating())) { String temp = list.get(i).getName(); int rating = list.get(i).getRating(); list.get(i).setName(list.get(j).getName());
list.get(i).setRating(list.get(j).getRating());
list.get(i).setName(temp);
list.get(i).setRating(rating);
} } } } }
public class RatingBook {
    private int mRating = 0;
    private String mName = "";

    public RatingBook() {}

    public RatingBook(String name, int rating) {
        mName = name;
        mRating = rating;
    }

    public void setRating(int rating) {
        mRating = rating;
    }

    public void setName(String name) {
        mName = name;
    }

    public String getName() {
        return mName;
    }

    public int getRating() {
        return mRating;
    }
}
public class BookDepot {
    static String[] sBookDepot = { "java and javascript", "java and C++",
            "java and c", "sql", "CEHNJINSHENG", "java", "C++", "javascript",
            "Java", "java and C", "java and SQL", "chenjinsehng", "int" };

    static List<RatingBook> createBookListFromDepot(int num, int rating) {
        List<RatingBook> list = new ArrayList<RatingBook>();
        int len = new Random().nextInt(num);
for (int i = 0; i < len; i++) { RatingBook book = new RatingBook(sBookDepot[len], returnRandom(rating)); list.add(book); } List<RatingBook> newList = removeSameBookFromList(list); return newList; } private static List<RatingBook> removeSameBookFromList(List<RatingBook> list) { Map<String, Integer> map = createMapWithSingalKeyOfBookName(list); List<RatingBook> bookList = new ArrayList<RatingBook>(); @SuppressWarnings("rawtypes") Set entries = map.entrySet(); if (entries != null) { @SuppressWarnings("rawtypes") Iterator iterator = entries.iterator(); while (iterator.hasNext()) { @SuppressWarnings("rawtypes") Map.Entry entry = (Entry) iterator.next(); String key = (String) entry.getKey(); Integer value = (Integer) entry.getValue(); RatingBook book = new RatingBook(); book.setBook(key, value); bookList.add(book); } } return bookList; } private static Map<String, Integer> createMapWithSingalKeyOfBookName( List<RatingBook> list) { Map<String, Integer> map = new HashMap<String, Integer>(); for (RatingBook book : list) { map.put(book.getName(), book.getRating()); } return map; } }

 

posted @ 2012-10-25 21:37  文酱  阅读(537)  评论(13编辑  收藏  举报