我想知道这种设计是对还是错,或两者兼而有之 我有一个带有几个组件(对象)的应用程序,每个组件都有一个配置(标志,功能等) 在任何时候,我都想从物体中找回配置 为此,我这样做了:
class ConfigRetriever {
public String getConfigString() {
String configString = "";
configString += "component 1 flag : "+component1.getFlag()+"\n";
configString += "component 2 flag : "+component2.getFlag()+"\n";
// ...
return( configString );
}
}
其他地方,需要配置时:
class SomeClass {
public void someMethod() {
ConfigRetriever configRetriever = new ConfigRetriever();
String configString = configRetriever.getConfigString();
// Do some stuff with configString...
}
}
我是对象编程的新手,为一个特定的动作创建一个对象(ConfigRetriever)仍然感觉很奇怪(即使对象能够做其他的事情)。
我也谈到了单身模式,有些事情是这样的:
String configString = ConfigRetriever.getInstance().getConfigString();
这是一个简洁的线条,但由于对象在应用程序结束之前一直停留在内存中,我真的不知道什么是对的,什么是错的。
我的设计会更好吗?怎么样 ?为什么?
更新
谢谢您的回答。我觉得我的问题有点乱,我错过了我要求的内容
整个配置和组件故事在这里作为我正在处理的那种情况的一个例子。这是快速而脏的代码,我应该警告你。真正的问题是:“创建一个对象只需一次(或有时)访问其中一种方法是否合适?”
那么,阅读你的答案并再次思考它,似乎正确的答案是“这取决于你的目标,课程,责任等等......”
我想在我的对象中存储信息吗?不能是静态的方法
使用永久内存的单例是一个问题吗?大多数情况下,因为我认为你必须有充分的理由在全局状态下维护内存中的对象。所以,大多数时候:没有单身人士。
最后,创建一个用于实例化某个对象的类是一个问题吗?它不是,去吧! : - )
答案 0 :(得分:1)
我认为没有必要在这里使用单身。
为单个操作创建对象并不奇怪,但如果经常调用该方法可能效率不高。我认为你能做的最好就是使用dependency injection:
class SomeClass {
private final ConfigRetriever retriever;
public SomeClass(ConfigRetriever retriever) {
this.retriever = retriever;
}
public void someMethod() {
// use this.retriever here
}
}
答案 1 :(得分:1)
还没有人提到static
方法。典型的Java模式是使用静态方法,您可以在没有类实例的情况下进行分类。类似的东西:
class ConfigRetriever {
public static String getConfigString() {
StringBuilder sb = new StringBuilder();
sb.append("component 1 flag : ").append(component1.getFlag()).append('\n');
sb.append("component 2 flag : ").append(component2.getFlag()).append('\n');
// ...
return sb.toString();
}
}
因此,您可以执行以下操作:
// call the static method on the class, not on an instance
String configString = ConfigRetriever.getConfigString();
由于您没有实例,因此无法在ConfigRetriever
内存储状态。我不确定component1
和component2
对象来自何处。
注意我转换了您的getConfigString()
方法,以使用比StringBuilder()
方法 更高效的+=
类实际上在内部使用多个 StringBuilder
类。
答案 2 :(得分:0)
几个问题 -
答:您的原始代码有一个返回void的方法,名为getConfigString - 这应该是固定的。
B.此外,还不清楚ConfigRetriever类中提供组件的位置。
C.您可以选择以下选项:
1.具有ConfigProvider类层次结构,它将与您的组件层次结构匹配 -
如果您有名为ComputerComponent的类,您将拥有匹配的ComptuerConfigProider。
您可以考虑在Component类中使用ConfigProider getConfigProvider方法。
public abstract class Component {
public abstract ConfigProvider getConfigProvider()'
}
然后具体的类看起来像:
public class ComputerComponent extends Component {
public ConfigProvider getConfigProvider() {
return new ComputerConfigProvider(this);
}
}
2.类似于第一个的解决方案,但是有一个ConfigProvider类,其中包含添加配置组件的方法。
例如,假设ConfigurationProvider仅包含键和值的映射。
在这种情况下,您的代码可以如下所示:
public class ConfigProvider {
private Map<String,String> internalMap = new HashMap<String,String>();
public String getConfigProvider() {
//Return a string representation of the internal map
}
public ConfigProvider addConfigElement(String key,String value) {
map.put(key,value);
return this;
}
}
public class ComputerComponent extends Component {
private int memory;
private String cpu;
public ConfigProvider getConfigProvider() {
ConfigProvider configProvider = new ConfigProvider();
return configProvider.addConfigElement("memory",Integer.toString(memory)).
addConfigElement("cpu",cpu);
} }
3.如果你仍然想使用单线 - 由于你的配置取决于组件状态,有一个配置提供者单线是错误的,除非你把getConfigProvider变成一个“无状态”方法 -
String getConfigString(Component component)
但在这种情况下,您可能会考虑不使用单线,而只是使用静态方法,代码如下:
public class ConfigurationProvider {
public static String getConfigString(Component component) {
StringBuilder sb = new StringBuilder();
//Append the component values to the string builder
return sb.toString();
}
}