ant*_*009 3 java design-patterns
我正在使用工厂模式来创建不同连接的对象 java version "1.7.0_60"
我面临的问题是每个具体类将具有该特定类的唯一属性.由于工厂在返回具体类的实例时将使用多态性,因此无法访问唯一属性.ie getHostType()
仅限于SqlServerConnection
.
我所做的解决方法是getHostType()
在超类中声明抽象并在每个具体类中实现它.但是,我真的不想这样做,因为我添加的更具体的类具有它们的唯一属性,我将必须包含在超类中的更抽象的方法,然后在每个具体类中实现它们.
我想保留我的工厂模式和抽象的超级课程.我只是想知道是否有其他方法而不是超类中的抽象方法?我可以包括任何设计模式来解决这个问题?
public abstract class Connection {
private int port;
private int ipAddress;
public Connection() {}
public String description() {
return "Generic";
}
/* Implement in every concrete class, even if the concrete type doesn't have that property */
public abstract int getHostType();
}
public class SqlServerConnection extends Connection {
private int sqlHostType;
public SqlServerConnection() {
sqlHostType = 5060;
}
@Override
public String description() {
return "Created a Sql Server connection type";
}
@Override
public int getHostType() {
return sqlHostType;
}
}
public class OracleConnection extends Connection {
public OracleConnection() {}
@Override
public String description() {
return "Created an Oracle connection type";
}
}
final public class ConnectionFactory {
protected String mType;
public ConnectionFactory(String type) {
mType = type;
}
/* Create the connection we want to use */
public Connection createConnection() {
if(mType.equals("Oracle")) {
return new OracleConnection();
}
else if(mType.equals("SQLServer")) {
return new SqlServerConnection();
}
else {
return null;
}
}
}
public class TestConnection {
public static void main(String[] args) {
ConnectionFactory factory = new ConnectionFactory("SQLServer");
Connection conn = factory.createConnection();
conn = factory.createConnection();
System.out.println(conn.description());
/* need to access the getHostType() */
System.out.println(conn.getHostType());
}
}
Run Code Online (Sandbox Code Playgroud)
你应该看一下访客模式.您需要声明一个接口ConnectionVisitor,并为层次结构中的每个连接类添加方法访问.
public interface ConnectionVisitor {
public int visit (Connection connection);
public int visit (SqlServerConnection sqlconnection);
public int visit (OracleConnection oracleConnection)
}
Run Code Online (Sandbox Code Playgroud)
现在,您需要在基类连接中添加一个accept方法,并接受ConnectionVisitor,然后在其上调用visit.你的新Connection类看起来像
public abstract class Connection {
private int port;
private int ipAddress;
public Connection() {}
public String description() {
return "Generic";
}
public int accept(ConnectionVisitor visitor){
return visitor.visit(this);
}
Run Code Online (Sandbox Code Playgroud)
}
请注意,accept方法执行双重调度.它调用它所调用的对象的基础以及传递给此方法的参数.这是访客模式的核心.
然后,您可以实现ConnectionVisitor接口以定义任何新功能,而无需更改基类.
class DemoVisitor implements ConnectionVisitor{
public int visit(Connection connection){
System.out.println("Visiting Connection");
return 1;
}
public int visit(SqlServerConnection sqlServerConnection){
System.out.println("Visiting SqlServerConnection");
return 1;
}
public int visit(OracleConnection oracleConnection){
System.out.println("Visiting Oracle Connection");
return 1;
}
Run Code Online (Sandbox Code Playgroud)
}
在TestConnection类中,您只需创建一个新的连接对象,然后在该对象上调用accept方法传递访问者对象.
public class TestConnection {
public static void main(String[] args) {
ConnectionFactory factory = new ConnectionFactory("SQLServer");
Connection conn = factory.createConnection();
conn = factory.createConnection();
System.out.println(conn.description());
ConnectionVisitor visitor = new DemoVisitor();
System.out.println(conn.accept(visitor));
}
Run Code Online (Sandbox Code Playgroud)
}
因此,现在任何子类特定功能都不能驻留在连接类层次结构中,而必须在新访问者中实现.
请注意,此模式不适合您的方案.此模式的一个限制是访问者界面中所有方法的返回类型必须相同.这种模式可能适合您的需求,也可能不适合您的需求,但值得研究您的情况.您可能需要修改此模式以满足您的需求.这就是模式是关于寻找一些常见的解决方案,然后修改这些解决方案以适应您的问题.