2

レストランの一覧から検索方法を作りたいです。ユーザーには GUI フォームがあり、必要なフィールドのみを入力します。このレストランが存在するかどうかを確認するメソッド meetCriteria を作成しました。それは機能しますが、すべての場合ではありません。

public class RestaurantList {
    private ArrayList<Restaurant> _restaurants = new ArrayList<Restaurant>();
        RestaurantList selRest;

        RestaurantList searchRestaurant(String name, String area, String phone, String category)
                {
                    selRest = new RestaurantList();
                    for (int i=0; i< _restaurants.size(); i++)
                    {
                        if(_restaurants.get(i).meetsCriteria(name, area, phone, category))
                        {
                            selRest.addRestaurant(_restaurants.get(i));
                        }

                    }
                    return this.selRest;
                }

public class Controller {


    //this is list with all Restaurants
    static RestaurantList restList = new RestaurantList();
    //this is list with the result of the search.

    public static RestaurantList selList; // selectedList


    public void addRestaurant (Restaurant rest)
    {
        restList.addRestaurant(rest);
    }

    public  void searchCriteria(String name, String area, String phone, String category)
    {

        int size = restList.getRestaurants().size();
        for(int i =0; i<size; i++)
            selList = restList.searchRestaurant(name, area, phone, category);

    }  
}

public class Restaurant {
        private String _name;
    private String _address;
    private String _phoneNum;
        private Area _area;

        public boolean meetsCriteria(String name, String area, String phone, String category)
        {
            if( this._name.equals(name) && this._area.getArea().equals(area) && this._phoneNum.equals(phone) && this._category.equals(category) )
            {
                return true;


            }
            if ( name.equals("") && area.equals(this._area.getArea()) && phone.equals("") && category.equals("") )
            {
                return true;


            }
            if ( name.equals("") && area.equals(this._area.getArea()) && phone.equals(this._phoneNum) && category.equals("") )
            {
                return true;


            }
            if (name.equals("") && area.equals(this._area.getArea()) && phone.equals("") && category.equals(this._category) )
            {
               return true; 


            }
            if ( area.equals(this._area.getArea()) && phone.equals("") && category.equals("") )
            {
                int index = this._name.indexOf(name);
                if (index != -1)
                {
                    return true; 
                }else return false;


            }
            if (area.equals(this._area) && category.equals(this._category) )
            {
                return true;
            }
            else
            {
            return false;
            }
        }
}
4

2 に答える 2

1

あなたの meetCriteria() メソッドは少し複雑に見え、指定されているかどうかにかかわらず、多くの基準の組み合わせを見逃しています。4 つのパラメーターがあり、各パラメーターを指定することも指定しないこともできるため、16 (2^4) の異なるケースが考えられます。明らかに、コードにはそれほど多くは含まれていません。このレストラン クラスにフィールドを追加するたびに、可能なケースの数が 2 倍になります。フィールドごとに 1 つのテストのみを追加する必要があることを確認して、この組み合わせの爆発を回避する方法を見つける必要があります。

この方法を試すことをお勧めします:

public class Restaurant {
    private String _name;
    private String _address;
    private String _phoneNum;
    private Area _area;

    public boolean meetsCriteria(String name, String area, String phone, String category)
    {
        if ( !name.equals("") && !name.equals(this._name) && this._name.indexOf(name) < 0){
            // name has been specified and does not match
            return false;
        }

        if(!areas.equals("") && this._aread.getArea().equals(area)){
            // area has been specified and does not match
            return false;
        }

        // ... snip ...
        // do the same kind of thing for phone and category
        // ... snip ...

        // At this point, all the criteria that have been specified by the user match,
        // and all the criteria that haven't been specified have been ignored.
        return true;
    }
}

これらすべてを 1 つの巨大な if() ステートメントで実行できる可能性がありますが、それはおそらく読みにくいでしょう。

またはさらに良いことに、次のように、各フィールドの一致ロジックを独自のメソッドに抽出できます。

public class Restaurant {
    private String _name;
    private String _address;
    private String _phoneNum;
    private Area _area;

    public boolean meetsCriteria(String name, String area, String phone, String category)
    {
        return matchesName(name) && matchesArea(area) && matchedPhone(phone) && matchesCategory(category);
    }

    private boolean matchesName(String name){
        return name.equals("") || name.equals(this._name) || this._name.indexOf(name) >= 0;
    }

    private boolean matchesArea(String area) {
        return areas.equals("") || this._aread.getArea().equals(area);
    }

    // create the missing methods yourself.
}
于 2012-06-13T16:32:09.357 に答える
1

どの条件が成功し、どの条件が失敗するかを簡単に確認できるように、「meetsCriteria」メソッドの単体テストを作成することから始めます。

例えば:

assertTrue(myRestaurant.meetsCriteria("nandos", "new york", "0124536", "tasty"));

追伸、私はおそらくあなたの「searchRestaurant」を次のように変更します:

List<Restaurant> searchRestaurant(List<Restaurant> allRestaurants, String name, String area, String phone, String category) {
    List<Restaurant> matches = new ArrayList<Restaurant>();
    for (Restaurant restaurant : allRestaurants) {
        if (restaurant.meetsCriteria(name, area, phone, category)) {
            matches.addRestaurant(allRestaurants.get(i));
        }
    }
    return matches;
}
于 2012-06-13T16:27:52.913 に答える