控制对字段的读/写访问

本文关键字:写访问 字段 控制 | 更新日期: 2023-09-27 18:36:19

>假设我们想在接口模式中分离出读写访问权限,如下所示。

namespace accesspattern
{
    namespace ReadOnly
    {
        public interface IA { double get_a(); }
    }
    namespace Writable
    {
        public interface IA : ReadOnly.IA { void set_a(double value); }
    }
}

这很容易实现:

namespace accesspattern
{
    namespace ReadOnly
    {
        public class A : IA
        {
            protected double a;
            public double get_a() { return a; }
        }
    }
    namespace Writable
    {
        public class A : ReadOnly.A, IA
        {
            public void set_a(double value) { base.a = value; }
        }
    }
}

假设我们需要另一个继承自 A 的类,因此我们继续为它定义一个接口:

namespace accesspattern
{
    namespace ReadOnly
    {
        public interface IB : ReadOnly.IA { int get_b(); }
    }
    namespace Writable
    {
        public interface IB : ReadOnly.IB, Writable.IA { void set_b(int value); }
    }
}

实现这一点并不容易。人们总是觉得 Writable.B 应该继承两个基类,Writable.A 和 ReadOnly.B,以避免重复代码。

是否有推荐的设计模式?目的是能够根据需求分别返回"只读访问"和"读写访问"对象(在编译时决定)。如果解决方案模式可以轻松添加更多继承层,类 C、D...

我知道多重继承的问题在这里出现,并且在很多很多地方的其他地方已经详细讨论了这个问题。但我的问题不是"如何在不使用多重继承的情况下实现在命名空间访问模式中定义的接口"(尽管我想学习最好的方法),而是我们如何单独定义类的只读/可写版本并支持继承而不会变得非常, 非常,凌乱

对于这里的价值,这是一个(混乱的)解决方案[请参阅下面的更好的实现]:

    namespace accesspattern
    {
        namespace ReadOnly
        {
            public class A : IA
            {
                protected double a;
                public double get_a() { return a; }
            }
            public class B : IB
            {
                protected int b;
                public int get_b() { return b; }
            }
        }
        namespace Writable
        {
            public class A : ReadOnly.A, IA
            {
                public void set_a(double value) { base.a = value; }
            }
            public class B : ReadOnly.B, IB
            {
                private IA aObj;
                public double get_a() { return aObj.get_a(); }
                public void set_a(double value) { aObj.set_a(value); }
                public void set_b(int value) { base.b = value; }
                public B() { aObj = new A(); }
            }
        }
    }
}

更新:我认为这(下面)就是尤金所说的。我认为这种实现模式非常好。通过仅传递类的"writeProtected"视图,可以实现要求类的状态不会更改的算法,并且仅使用"writeEnabled"视图,这意味着函数将/可能导致状态避免更改。

namespace access
{
    // usual usage is at least readable
    public interface IA { double get_a(); }
    public interface IB : IA { int get_b(); }
    // special usage is writable as well
    namespace writable
    {
        public interface IA : access.IA { void set_a(double value);  }
        public interface IB : access.IB, IA { void set_b(int value);}
    }
    // Implement the whole of A in one place
    public class A : writable.IA
    {
        private double a;
        public double get_a() { return a; }
        public void set_a(double value) { a = value; }
        public A() { }
        //support write-protection
        public static IA writeProtected() { return new A(); }
        public static writable.IA writable() { return new A(); }
    }
    // implement the whole of B in one place and now no issue with using A as a base class
    public class B : A, writable.IB
    {
        private int b;
        public double get_b() { return b; }
        public void set_b(int value) { b = value; }
        public B() : base() { }
        // support write protection 
        public static IB writeProtected() { return new B(); }
        public static writable.IB writable() { return new B(); }
    }
    public static class Test
    {
        static void doSomething(IA a)
        {
            // a is read-only
        }
        static void alterState(writable.IB b)
        {
            // b is writable
        }
        static void example()
        {
            // Write protected
            IA a = access.A.writeProtected();
            IB b = access.B.writeProtected();
            // write enabled
            writable.IA A = access.A.writable();
            writable.IB B = access.B.writable();
            Console.WriteLine(a.get_a());
            B.set_b(68);
            doSomething(A); // passed as writeprotected
            alterState(B); // passed as writable
        }
    }
}

控制对字段的读/写访问

我知道

这个线程已经有一年的历史了,但我想知道这样的东西是否有意义:

 interface ReadOnlyA
 {
    object A { get; }
 }
 interface WriteableA : ReadOnlyA
 {
   new object A {get; set;}
 }

您可以在服务级别而不是实体级别提供读/写访问权限。在这种情况下,您可以代码生成一个围绕处理读/写访问的服务包装器。使用的模式:装饰器、依赖注入