我应该使用 2-way 聚合还是有更好的解决方案?
Should I use 2-way aggregation or are there better solutions?
我正在开发一个简单的搜索引擎,现在我有一个 class Directory
,其中包含一个 ArrayList<Person>
,其中包含来自 Person
class. Person
class 有名字、姓氏和电子邮件。 Directory
class 有一个 searchPerson(String searchTerm)
方法,它遍历 directory
class 和 return 的 Persons 的 ArrayList等于 searchTerm 的名称、姓氏或电子邮件。不太难。
public class Directory {
private List<Person> directory;
// constructors, getters and setters
public List<Person> searchPerson(String searchTerm) {
List<Person> found = new ArrayList<>();
for (Person person: this.directory) {
if (person.toString().toLowerCase().contains(searchTerm)) {
found.add(person);
}
}
return found;
}
}
public class Person {
private String name;
private String surName;
private String email;
// constructors, getters and setters
}
但是,在项目的下一节中(我在JetBrains上做项目),必须根据3种不同的搜索策略搜索列表:(一次可能有多个searchTerms)
- ALL:只有 return 等于所有 searchTerms 的人。
- 任意:Return 至少等于一个搜索词的所有人物
- NONE:只有 return 等于搜索条件 none 的人。
他们建议我使用策略设计模式。因此,我创建了一个抽象 class searchStrategy
并为 Directory
提供了一个 SearchStrategy
类型的实例变量。接下来,我创建了三个具体的 classes,它们都扩展了 SearchStrategy
,称为:SearchALL
、SearchANY
和 SearchNONE
。现在,可以实施不同的搜索策略(还没有这样做)。
public class Directory {
private List<Person> directory;
private SearchStrategy strategy; // reference to the strategy
// constructors, getters and setters
}
但是,现在问题来了:前一段提到的三个Search###
class无法访问Directory
[=64=的persons的ArrayList ](当然,这是他们必须搜索的列表)。
作为解决方案,我现在是否应该给 SearchStrategy
class 一个实例变量,它在 Directory
中引用相同的 ArrayList<Person>
以便搜索策略可以访问它?这将导致(某种)双向聚合(Directory
有一个 SearchStrategy
和一个 ArrayList<Person>
和 SearchStrategy
有相同的 ArrayList<Person>
)并且真的感觉很奇怪。
// let's say I'd give this class a reference to the ArrayList
public class SearchALL extends SearchStrategy {
private ArrayList<Person> directory // now they (kinda) point to each other
}
或者我应该简单地将 ArrayList<Person>
从 Directory
移动到 SearchStrategy
?
因此,我想知道,这是不好的做法吗,我应该避免吗?我应该如何实施我的搜索引擎计划?
编辑:添加了一些代码。删除了最后一部分(只是令人困惑)
Edit2:尽管(我认为)这种情况很容易解决(因为搜索策略的不同之处在于条件),但我想知道一般应该做什么。
要走的路是让策略实施具有以关键字和列表作为参数进行搜索的方法。
首先,您需要对策略的引用和它的 setter。其次,您的搜索方法只是将参数传递给策略实现。
class Directory {
private List<Person> entries;
private SearchStrategy strategy;
List<Person> search(String a, String, b, String c) {
return strategy.search(entries, a, b, c);
}
// setter for strategy
}
interface SearchStrategy {
List<Person> search(List<Person> list, String a, String b, String c);
}
class SearchAll implements SearchStrategy {
@Override
List<Person> search(List<Person> list, String a, String b, String c) {
// do your thing and return the result
}
}
Strategy pattern 的要点是将算法与 class 分开,以便可以动态更改算法。将列表移动到实现 class 的算法中不是一个好主意,因为它会将 algorithm 与 data 混淆工作。出于同样的原因,在实现 class 的算法中引用也是不好的。 Directory
class 是正确的地方。
我正在开发一个简单的搜索引擎,现在我有一个 class Directory
,其中包含一个 ArrayList<Person>
,其中包含来自 Person
class. Person
class 有名字、姓氏和电子邮件。 Directory
class 有一个 searchPerson(String searchTerm)
方法,它遍历 directory
class 和 return 的 Persons 的 ArrayList等于 searchTerm 的名称、姓氏或电子邮件。不太难。
public class Directory {
private List<Person> directory;
// constructors, getters and setters
public List<Person> searchPerson(String searchTerm) {
List<Person> found = new ArrayList<>();
for (Person person: this.directory) {
if (person.toString().toLowerCase().contains(searchTerm)) {
found.add(person);
}
}
return found;
}
}
public class Person {
private String name;
private String surName;
private String email;
// constructors, getters and setters
}
但是,在项目的下一节中(我在JetBrains上做项目),必须根据3种不同的搜索策略搜索列表:(一次可能有多个searchTerms)
- ALL:只有 return 等于所有 searchTerms 的人。
- 任意:Return 至少等于一个搜索词的所有人物
- NONE:只有 return 等于搜索条件 none 的人。
他们建议我使用策略设计模式。因此,我创建了一个抽象 class searchStrategy
并为 Directory
提供了一个 SearchStrategy
类型的实例变量。接下来,我创建了三个具体的 classes,它们都扩展了 SearchStrategy
,称为:SearchALL
、SearchANY
和 SearchNONE
。现在,可以实施不同的搜索策略(还没有这样做)。
public class Directory {
private List<Person> directory;
private SearchStrategy strategy; // reference to the strategy
// constructors, getters and setters
}
但是,现在问题来了:前一段提到的三个Search###
class无法访问Directory
[=64=的persons的ArrayList ](当然,这是他们必须搜索的列表)。
作为解决方案,我现在是否应该给 SearchStrategy
class 一个实例变量,它在 Directory
中引用相同的 ArrayList<Person>
以便搜索策略可以访问它?这将导致(某种)双向聚合(Directory
有一个 SearchStrategy
和一个 ArrayList<Person>
和 SearchStrategy
有相同的 ArrayList<Person>
)并且真的感觉很奇怪。
// let's say I'd give this class a reference to the ArrayList
public class SearchALL extends SearchStrategy {
private ArrayList<Person> directory // now they (kinda) point to each other
}
或者我应该简单地将 ArrayList<Person>
从 Directory
移动到 SearchStrategy
?
因此,我想知道,这是不好的做法吗,我应该避免吗?我应该如何实施我的搜索引擎计划?
编辑:添加了一些代码。删除了最后一部分(只是令人困惑) Edit2:尽管(我认为)这种情况很容易解决(因为搜索策略的不同之处在于条件),但我想知道一般应该做什么。
要走的路是让策略实施具有以关键字和列表作为参数进行搜索的方法。
首先,您需要对策略的引用和它的 setter。其次,您的搜索方法只是将参数传递给策略实现。
class Directory {
private List<Person> entries;
private SearchStrategy strategy;
List<Person> search(String a, String, b, String c) {
return strategy.search(entries, a, b, c);
}
// setter for strategy
}
interface SearchStrategy {
List<Person> search(List<Person> list, String a, String b, String c);
}
class SearchAll implements SearchStrategy {
@Override
List<Person> search(List<Person> list, String a, String b, String c) {
// do your thing and return the result
}
}
Strategy pattern 的要点是将算法与 class 分开,以便可以动态更改算法。将列表移动到实现 class 的算法中不是一个好主意,因为它会将 algorithm 与 data 混淆工作。出于同样的原因,在实现 class 的算法中引用也是不好的。 Directory
class 是正确的地方。