How do you create low-level objects using instantiation information from the top-level application?
I have an application that reads an input file with various user settings in it. Some of these settings apply to very specific classes that are instantiated开发者_StackOverflow at a very low level. But the input file is read and the settings are stored at the top level of the app.
What's the design pattern here for instantiating a low-level class (that's several links removed from the top level) using information that's read at the top level?
Have the top level deal with abstractions only, and use your platform's reflection library to instantiate the concrete types.
A factory class/provider can be useful, where you can pass it a set of properties that it can use to construct the concrete type.
Putting it all together, it might look like this in Java:
interface Factory<T> {
public T create(Properties p);
}
class MyObjFactory implements Factory<MyObj> {
public MyObj create(Properties p) {
return new MyObj(p.get("name"));
}
}
class MyObj {
private String name;
public MyObj(name) {
this.name = name;
}
}
Then MyObjFactory
would be constructed reflectively, and could be used to construct a MyObj
.
It's customary to have single global App object which contains global properties, so, low-level classes can access everything they need from that single point. If project is not very complex this solution is quite manageable.
As a variation you can have global application object implementing interfaces in which low-level classes interested and inject it at the construction time. Like (C#):
interface ITextFileProperties
{
string Encoding;
}
interface IGraphicsFileProperties
{
int Resolution;
}
interface IFileProperties : ITextFileProperties, IGraphicsFileProperties
{
}
static class App : IFileProperties
{
public string Encoding = "UTF-8"; // ITextFileProperties
public int Resolution = 1024; // IGraphicsFileProperties
}
class TextFile
{
public TextFile(ITextFileProperties data)
{
_globalEncoding = data.Encoding;
}
}
class GraphicsFile
{
IGraphicsFileProperties properties;
public GraphicsFile(IGraphicsFileProperties data)
{
properties = data; // in case we'll need it later, if it can change at run time, etc.
}
}
class SomeObjectUsingFiles
{
public SomeObjectUsingFiles(IFileProperties properties)
{
_globalProperties = properties;
}
public void ProcessText()
{
var textFile = new TextFile(_globalProperties);
}
public void ProcessGraphics()
{
var grFile = new GraphicsFile(_globalProperties);
}
}
Pass to object only minimum information it needs. So you can keep your concrete "workhorse" classes (files) simple and loosely coupled and deal with parameter passing later, if needed.
精彩评论