아래와 같이 인터페이스 패턴에서 읽기 및 쓰기 액세스를 분리하려고한다고 가정합니다.필드에 대한 읽기/쓰기 액세스 제어
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); }
}
}
구현 :
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; }
}
}
}
우리가 상속 해, 우리가 가서 그것을위한 인터페이스를 정의하는 다른 클래스가 필요하다고 가정 해 보겠습니다 :
namespace accesspattern
{
namespace ReadOnly
{
public interface IA { double get_a(); }
}
namespace Writable
{
public interface IA : ReadOnly.IA { void set_a(double value); }
}
}
이 쉽게 구현할 수있다 이것은 그렇게 쉬운 일이 아닙니다. Writable.B는 반복적 인 코드를 피하기 위해 Writable.A와 ReadOnly.B라는 두 개의 기본 클래스에서 상속해야한다고 항상 생각합니다.
사용할 권장 디자인 패턴이 있습니까? 목표는 요구 사항에 따라 "읽기 전용 액세스"및 "읽기 쓰기 액세스"객체를 개별적으로 반환 할 수 있도록하는 것입니다 (컴파일 타임에 결정됨). 솔루션 패턴으로 상속 계층, 클래스 C, D를 더 쉽게 추가 할 수 있다면 좋을 것입니다 ...
다중 상속 문제는 여기에서 다루고 있으며, 다른 곳에서도 논의 된 바 있습니다. 많은, 많은, 장소. 하지만 내 질문에 너무 많은 "어떻게 상속을 사용하지 않고 네임 스페이스 accesspattern 내부에 정의 된 인터페이스를 구현하는"(비록 내가 그 최선의 방법을 배우고 싶지만)보다는 오히려, 우리는 어떻게 정의 할 수 ReadOnly/클래스의 쓰기 가능 버전과 별도로 클래스를 생성하지 않고도 상속을 지원합니다.?
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
}
}
}
는 사용할 수 없습니다 속성을? 각각의'get'과'set'에 대한 접근을 개별적으로 지정할 수 있습니다. 또한 List <>에는 AsReadOnly()가 있다는 것을 기억합니다. 어쩌면 비슷할 수도 있지만 쓰기 가능한 클래스에서 호출해야합니다. BTW, 수업을 명확하게 분리하는 이유는 무엇입니까? – cyanic
우리는 어떻게 클래스의 ReadOnly/Writable 버전을 개별적으로 정의 할 수 있으며 상속을 매우 어렵게하지 않고도 지원할 수 있습니까? - 쓰기 및 읽기 액세스 용으로 두 개의 인터페이스를 작성하고 한 클래스에서 상속해야하며 필요한 클래스 버전을 선택하는 fabrica를 작성해야합니다. Fabrica는 필요한 인터페이스를 통해 클래스의 인스턴스를 반환합니다. 그게 다야. –
@GMMan get set 속성을 사용하면 xml serialization 사용을 배제합니까? http://msdn.microsoft.com/en-us/library/182eeyhh%28VS.85%29.aspx? – user859400