如何有效控制实现多接口的class对象?
How can I control the class object which implements multi interface effectively?
method:ClientProgram::deleteObject() 的目标是删除目标对象。并在删除对象之前显示对象的详细信息。
//#1. Client program which delete the target object.
public class ClientProgram {
List<AbstractBase>list = new ArrayList<ConcreteA>();
void deleteObject(String key) {
for(AbstractBase obj : list){
if(!obj.isTarget(key))continue;
//show info and delete the object
Msg( obj.getInfo().toString() );
obj.delete();
break;
}
}
}
当具体class从抽象基础class(如下面的#2、#3)或具有多种方法的接口扩展时是可行的。
//#2. A base abstract class for concrete classes
public abstract class AbstractBase {
public abstract boolean isTarget(String key);
public abstract void delete();
public abstract void update(AbstractBase obj);
public abstract AbstractBase getInfo();
}
//#3. A concrete class with an abstract class
public class ConcreteA extends AbstractBase {
....
}
但是一旦所有的方法都像#4一样被隔离到四个不同的接口中(因为应用了ISP),你只能用隔离接口中的任何一个来控制具体对象,而不能调用getInfo()和delete( ) 同时。
//#4. A concrete class with segregated interfaces
public class ConcreteA implements Delete, Update, GetInfo, Target {
....
}
使用像 #4 这样的 ISP class 创建像 deleteObject() 这样的方法的 best/common 实践是什么?
来自 Wikipedia page about interface segregation principle:
In the field of software engineering, the interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use.)
在您的情况下,您的客户确实依赖于 getInfo()
和 delete()
;因此,您应该以两者都包含的粒度隔离您的界面。
另一种理解 ISP 的方式是为每个客户端构建一个接口。有时,同一个界面可供多个客户端使用,但通常一个界面会在其自身与一个客户端之间建立契约。
如果您需要使用ISP
你的版本 #4 看起来不错,但你不能用它来删除对象,
所以这是解决方案
class MyInfo {
//some fields
}
interface Delete {
void delete();
}
interface Info {
MyInfo getInfo();
}
interface Update {
}
interface Target {
boolean isTarget();
}
interface ClientProgramm extends Delete, Info, Target {
}
class ConcreteA implements ClientProgramm {
@Override
public void delete() {
}
@Override
public MyInfo getInfo() {
return null;
}
@Override
public boolean isTarget() {
return false;
}
}
你所有的接口和类都是独立的,你可以将一些必要的逻辑收集到接口ClientProgramm
中,
为了获得更大的灵活性,您可以将 ClientProgramm
拆分为 2 个不同的接口,例如 UpdateObject
和 DeleteObject
method:ClientProgram::deleteObject() 的目标是删除目标对象。并在删除对象之前显示对象的详细信息。
//#1. Client program which delete the target object.
public class ClientProgram {
List<AbstractBase>list = new ArrayList<ConcreteA>();
void deleteObject(String key) {
for(AbstractBase obj : list){
if(!obj.isTarget(key))continue;
//show info and delete the object
Msg( obj.getInfo().toString() );
obj.delete();
break;
}
}
}
当具体class从抽象基础class(如下面的#2、#3)或具有多种方法的接口扩展时是可行的。
//#2. A base abstract class for concrete classes
public abstract class AbstractBase {
public abstract boolean isTarget(String key);
public abstract void delete();
public abstract void update(AbstractBase obj);
public abstract AbstractBase getInfo();
}
//#3. A concrete class with an abstract class
public class ConcreteA extends AbstractBase {
....
}
但是一旦所有的方法都像#4一样被隔离到四个不同的接口中(因为应用了ISP),你只能用隔离接口中的任何一个来控制具体对象,而不能调用getInfo()和delete( ) 同时。
//#4. A concrete class with segregated interfaces
public class ConcreteA implements Delete, Update, GetInfo, Target {
....
}
使用像 #4 这样的 ISP class 创建像 deleteObject() 这样的方法的 best/common 实践是什么?
来自 Wikipedia page about interface segregation principle:
In the field of software engineering, the interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use.)
在您的情况下,您的客户确实依赖于 getInfo()
和 delete()
;因此,您应该以两者都包含的粒度隔离您的界面。
另一种理解 ISP 的方式是为每个客户端构建一个接口。有时,同一个界面可供多个客户端使用,但通常一个界面会在其自身与一个客户端之间建立契约。
如果您需要使用ISP 你的版本 #4 看起来不错,但你不能用它来删除对象,
所以这是解决方案
class MyInfo {
//some fields
}
interface Delete {
void delete();
}
interface Info {
MyInfo getInfo();
}
interface Update {
}
interface Target {
boolean isTarget();
}
interface ClientProgramm extends Delete, Info, Target {
}
class ConcreteA implements ClientProgramm {
@Override
public void delete() {
}
@Override
public MyInfo getInfo() {
return null;
}
@Override
public boolean isTarget() {
return false;
}
}
你所有的接口和类都是独立的,你可以将一些必要的逻辑收集到接口ClientProgramm
中,
为了获得更大的灵活性,您可以将 ClientProgramm
拆分为 2 个不同的接口,例如 UpdateObject
和 DeleteObject