【问题标题】:Is there someway to restrict the access to a member of an object only to the object that owns it by composition?有没有办法限制对对象成员的访问仅限于通过组合拥有它的对象?
【发布时间】:2017-03-10 09:40:28
【问题描述】:

我真的觉得一定有办法解决这个问题。

想象一下,我有大量对象作为所有者类的组件。我想为其成员提供对该所有者类的客户的轻松访问,因此我将所有这些对象公开。这些对象中的每一个也都有其所有成员公开。但是组件的一个成员不应被其所有者的客户访问,只能由其所有者自己访问:

public class ComponentObject
{
    public int int_field;
    public float float_field;
    public Object object_field;

    public Object public_method1()
    {
        //something;
    }

    public Object public_method2()
    {
        //something;
    }

    public Object restricted_to_owner_only()
    {
        //something;
    }
}

//all clients of Owner should be able to access all the members of its components, except
//restricted_to_owner_only, which only Owner should be able to access
public class Owner
{
    public ComponentObject component1;
    public ComponentObject component2;
    public ComponentObject component3;
    //... lots of others
    public ComponentObject component300;
}

有没有办法做到这一点?请注意,任何包中的任何类都可以拥有ComponentObject,因此在restricted_to_owner_only 处使用包级别的可见性似乎不是一种选择。 ComponentObject 就像一个实用程序类,可以在其他应用程序中重用。

也许有一个注释可以在编译时在一些不错的库中强制执行该注释?

编辑:我忘了说 ComponentObject 是现实生活中的参数化类型,并且 Owner 中的每个字段都被不同地参数化。我试图抽象出细节,以便我们可以专注于设计问题本身,但我抽象的太多了。我将在下面发布与实际问题更相似的内容:

public class ComponentObject<T>
{
    public int int_field;
    public float float_field;
    public T object_field;

    //any method could return T or take T as an argument.
    public T public_method1()
    {
        //something;
    }

    public Object public_method2()
    {
        //something;
    }

    public Object restricted_to_owner_only()
    {
        //something;
    }
}

//all clients of Owner should be able to access all the members of its components, except
//restricted_to_owner_only, which only Owner should be able to access
public class Owner
{
    public ComponentObject<String> component1;
    public ComponentObject<File> component2;
    public ComponentObject<Consumer<Boolean>> component3;
    //... lots of others
    public ComponentObject<Integer> component300;
}

编辑 2(可能是一个解决方案): 伙计们,受罗密欧与朱丽叶的爱的启发,我写了这个解决方案,你能找出其中的任何错误吗?还是会按我的预期工作?

//add this class
public class OwnershipToken
{
    private static int id_gen = 0;
    public final int id = id_gen++;

    @Override
    public boolean equals(Object obj)
    {
        return (obj instanceof OwnershipToken) && ((OwnershipToken)obj).id == id;
    }

    @Override
    public int hashCode()
    {
        return id;
    }
}

//Then change this in ComponentObject<T>:
public class ComponentObject<T>
{
    //add this field:
    private final OwnershipToken ownershipToken;

    //add this constructor
    public ComponentObject(OwnershipToken onwershipToken)
    {
        this.ownershipToken = ownershipToken;
    }

    //change restricted_to_owner_only signature:
    public Object restricted_to_owner_only(OwnershipToken ownershipToken)
    {
        //add this condition
        if(this.ownershipToken.equals(ownershipToken)
            //something;
    }
}

//finally, Owner gains a field:
public class Owner
{
    private final OwnershipToken ownershipToken = new OwnershipToken();
    //... etc, remainder of the class
}

这会按预期工作吗?

【问题讨论】:

  • 所以,假设你有对象 A,它有字段 B、C 和 D,你想让其他人能够使用 B、C 和 D,但是他们的方法应该只有 A 可以访问?
  • 我不想说它是重复的,但这听起来像是朋友的概念:stackoverflow.com/questions/182278/…
  • @Compass 这个优雅的莎士比亚解决方案可能给了我一个想法。

标签: java oop design-patterns composition class-visibility


【解决方案1】:

我明白你想要什么,我认为这是不可能的。 但是,仍然有一种方法可以做到!

在所有者类中创建一个 id:

private int id = new Random().nextInt(10000);

在组件对象中:

private id;

public ComponentObject(int id){
    this.id = id;
}

public Object restricted(int id){
    if(this.id != id)
        return null;
    else
        return object;
}

在所有者中:

private ComponentObject<String> string;

public Owner() {
    string = new ComponentObject<>(id);
    string.restricted(id);
    //if the id is right it will return the restricted object, if not i will                
    //return null   

}

【讨论】:

  • 这将是一个很好的解决方案,问题是我的问题不够清楚,让我通过编辑来解决它。
  • 但正如您所见,一个Owner 可以有很多ComponentObjects&lt;T&gt;,每个ComponentObjects&lt;T&gt; 都以不同的方式进行参数化。
  • 试试我的解决方案
  • 是的,我编辑了受 cmets 2 用户在其上发布的问题启发的问题,指出它与另一个关于 Java 中缺少 friend 访问修饰符的问题有些相似
  • 你想试试我的解决方案吗?
猜你喜欢
  • 2016-03-31
  • 2011-02-07
  • 2018-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-12
  • 1970-01-01
相关资源
最近更新 更多