【问题标题】:Restrict access to only necessary data-class accessors / getters限制对仅必要的数据类访问器/获取器的访问
【发布时间】:2023-03-05 02:22:01
【问题描述】:

我有一个在一个类中创建的数据类,并且可以传递给实现特定接口的多个 Android UI 活动之一。

每个 UI 都使用相同的数据,但是,并非所有 UI 都需要所有数据。我想知道是否有 simple 解决方案允许每个 UI 仅使用数据的特定部分(仅使用特定的访问器/获取器)

ClickListener 处理程序类

// ICalculatorAbstraction is what all my UI's implement. It has method... void updateResult(ExpressionState expression)
public final View.OnClickListener listenerOn(final ICalculatorAbstraction UI) {

    return listener = new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            // Calculations

            ExpressionState expression = new ExpressionState.Builder()
                    .setFirstNumber(num1)
                    .setSecondNumber(num2)
                    .setTotal(total)
                    .setOperator(operator.getSign())
                    .build();

            UI.updateResult(expression); 

        }
    };

}

ICalculatorAbstraction 接口

同样,我所有的 Android 活动 (UI) 都实现了这个接口

public interface ICalculatorAbstraction {

    ...

    void updateResult(ExpressionState result);

}

需要所有访问器 UI

@Override
public void updateResult(ExpressionState result) {

    String results = String.format( // NOTE: this one needs ALL the accessors / getters!!
            "%s %s %s = %s",
            result.getFirstNumber(),
            result.getOperator(),
            result.getSecondNumber(),
            result.getTotal()
    );

    this.txtResult.setText(results);

需要一个访问器 UI

@Override
public void updateResult(ExpressionState result) {

    String results = String.format( // NOTE: this one needs ONE accessor / getter!!
            "Wow. Such Calcuation. %s",
            result.getTotal()

            // NOTE: These should not be allowed in this instance because this UI does not use them
            // result.getFirstNumber()
            // result.getOperator()
            // result.getSecondNumber()

    );

    this.txtResult.setText(results);

如何更改 updateResult(...)(在界面和 UI 中),以便特定 UI 的 updateResult(...) 只允许我使用所需的评估器/获取器?

我尝试创建一个空白接口,然后创建了 2 个实现该空白接口的抽象类。抽象类只有我需要的访问器/获取器,但是当我尝试修改上面的代码时,没有任何效果。

这可能吗?


更新

这就是我希望看到的——你可以说“我最好的解决方案”。

需要所有访问器 UI

@Override
public void updateResult(IAllAccessors result) {

    String results = String.format( 
            "%s %s %s = %s",
            result.getFirstNumber(),
            result.getOperator(),
            result.getSecondNumber(),
            result.getTotal()
    );

    this.txtResult.setText(results);

需要一个访问器 UI

@Override
public void updateResult(IOneAccessorOnly result) {

    String results = String.format( 
            "Wow. Such Calcuation. %s",
            result.getTotal()            // I should not be able to do result.getFirstNumber(); for example

    );

    this.txtResult.setText(results);

ExpressionState / 生成器类

public class ExpressionState implements IOneAccessorOnly, IAllAccessors {

    private ExpressionState(Builder builder) { ... }

    public double getFirstNumber() { ... }   // IAllAccessors
    public double getSecondNumber() { ... }  // IAllAccessors
    public String getOperator() { ... }      // IAllAccessors
    public double getTotal() { ... }         // IAllAccessors, IOneAccessorOnly

    public static class Builder { ... }

}

这个解决方案的问题在于,我无法弄清楚如何处理上面的界面!我不能有一个参数可以让编译器对这两个 UI 都满意。


更新 2

我不能...

在我的ClickListener 类中使用构建器创建ExpressionState

IOneAccessorOnly var = new ExperssionState.Builder()...

这是因为在我的ClickListener 类中,我不知道要创建哪一个。它必须非常通用。在我的 UI 中,我想简化我可以使用的内容。我不能用这种方法做到这一点

因为它不知道是什么,所以它必须是“一切”

ExpressionState var = new ExpressionState.Builder()...

除此之外真的不可能。该解决方案必须专门处理 UI(活动)以缩小允许范围!!

【问题讨论】:

    标签: java android interface adapter


    【解决方案1】:

    如果表达式状态是你自己的类,我会让它实现两个不同的接口,就像这样。

    public class ExpressionState implements InterfaceOne, InterfaceTwo {
        public void interfaceOneGetterMethod()
        public void interfaceTwoGetterMethod()
    }
    

    在另一个文件中:

    public interface InterfaceOne {
        public void interfaceOneGetterMethod();
    

    最终文件:

    public interface InterfaceTwo {
        public void interfaceTwoGetterMethod();
    

    现在,当您创建 ExpressionState 对象时,将它们分配给定义为的对象:

    InterfaceTwo var = new ExperssionState(blah);  
    

    或者修改你的构建器只返回接口(更好)

    【讨论】:

    • 这根本不适合我的需要。在 ExpressionState 创建期间,该类不知道要创建哪一个,因此它必须非常广泛。我希望我的 UI 尽量减少这种过度影响,并且只使用需要的东西。因此,如果您可以重新提交答案,那就太好了。我会将您的代码作为我不想要的东西放在我的问题中,以便其他人知道
    • 我试过这个代码。这是行不通的!!我正在尝试您的构建器返回一个界面;但是,这并不符合我的需要。
    • 构建器或工厂的整个想法是构建对象本身是由调用的不同方法或在构建时发送的不同参数决定的。在做出这样的响应之前,您可能需要查找 Builder 设计模式或不同的 Factory 设计模式。使用接口被认为是封装数据和隐藏实现的最佳实践。
    • 使用Builder模式是为了避免使用伸缩反模式。这就是我使用它的原因。就像我说的那样,您的解决方案不符合我在问题中所述的需求。请更新您的答案。我对你提到的工厂有点感兴趣。这符合我的需要吗?
    • 我的问题不是接口的使用。我的代码已经加载了它们,我计划使用更多。我了解封装和隐藏实现。我鼓励这样做,所以你在这里错了。我试过你的方法......它不起作用,因为你的回答没有考虑到我的整个问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-12
    相关资源
    最近更新 更多