2012-10-26 5 views
3

이것은 내 지식 부족/나쁜 프로그래밍 실습을 보여줄 수 있지만, 궁금한 점은 다음과 같습니다. a) 이미 있습니다. b)클래스의 특정 인스턴스에 대한 정적/공유 변수

은 가정하자 나는 클래스가,의는 "컴퓨터"를 부르 자하고 회사의 모든 컴퓨터의 데이터를 보유 : 너무

을 할 나쁜 프로그래밍 연습이다 그러나 여기 내 질문의 경우는, 존재하지 않는 . 이제는이 회사에 수천 대의 Dell 컴퓨터와 수천 대의 HP 만 있고 다른 것은 없습니다.

Public Class Computer 

Dim Type as string 
Dim SerialNumber as string 
Dim User as String 
... 

End Class 

을 지금, 나는 두 개의 목록을 만들 내 코드 : 다음과 같이 내 클래스를 정의 할 수 있습니다, 지금

을 (다시이 나의 점을 설명하기 위해 단지 예입니다, 여기에 나와 함께 스틱하시기 바랍니다)

Dim DellComps as new list(of computer) 
Dim HPComps as new list(of computer) 

물론, DellComps을 위해, 그들 모두는 .Type = "Dell"이되고 HPComps에 대한 모든 것 .Type = "HP"

이제 생성자에서이 변수를 매우 쉽게 설정할 수 있다는 것을 알았지 만, 클래스 내부에서 변수를 선언하는 것이 더 현명한 방법인지 궁금합니다. VB Shared/C# Static 문과 유사합니다. 클래스는 동일한 변수를 공유합니다.

내 생각은 :

  1. 클래스를 상속하고
  2. 그냥 그대로두고 자식 클래스의 공유 변수를 만들고 생성자에서 유형 VAR를 선언
  3. 어쩌면 뭔가입니다 어떻게 든
  4. 가장 가능성이 인터페이스를 통해 수행 할 수 - 난 그냥 약

타를 모르는 무언가를 nks와 나는 내가 묻고있는 것이 의미가 있기를 바란다! !!

답변

2

컴퓨터 유형 (유형을 편집 할 수있는 일반적인 비즈니스 오브젝트 시나리오는 아님)을 나타내는 플래그를 생성자에서 항상 설정하는 경우, 서브 클래스를 사용하여 문제점을 실제로 해결할 수있는 가능성이 있습니다.

서브 컴퓨터 DellComputer 및 HpComputer 클래스를 생성하는 컴퓨터.

컴퓨터의 각 유형의 목록을 만드는 한 가지 방법은 모든 컴퓨터의 마스터 목록을 가지고 있고 관심있는 유형과 일치하는 인스턴스를 선택 Linq에의 Enumerable.OfType(TResult)를 사용하는 것입니다.

당신이 유형을 원하는 실제로 경우 대신 클래스를 만든 후에 편집 가능한 클래스를 지정하는 대신 컴퓨터 유형을 수정하는 속성을 제공하십시오. 편의상 생성자 과부하를 제공하여 속성을 설정할 수도 있습니다 (개인적으로 멀리 부끄러워 할지라도). 그렇게 할 경우 해당 생성자 오버로드에 속성을 사용하여 유형을 설정하십시오. 공장 패턴의 모양에 대한

UPDATE

예.

public abstract class Computer 
{ 
    public virtual string Type { get; } 
} 

public class DellComputer : Computer 
{ 
    public override string Type 
    { 
     get { return "Dell"; } 
    } 
} 

public class HpComputer : Computer 
{ 
    public override string Type 
    { 
     get { return "HP"; } 
    } 
} 

// Here I'm using an enum to indicate the type desired. You might use a string 
// or anything else that makes sense in your problem domain. 

public enum ComputerType 
{ 
    Dell = 1, 
    Hp = 2 
} 

public class ComputerFactory 
{ 
    public Computer Create(ComputerType type) 
    { 
     switch (type) 
     { 
      case ComputerType.Dell: 
       return new DellComputer(); 
      case ComputerType.Hp: 
       return new HpComputer(); 
      default: 
       throw new InvalidArgumentException(); 
     } 
    } 
} 

// Usage would be something like: 


List<Computer> computers = new List<Computer>(); 
computers.Add(ComputerFactory.Create(ComputerTypes.Dell); 
computers.Add(ComputerFactory.Create(ComputerTypes.Dell); 
computers.Add(ComputerFactory.Create(ComputerTypes.Hp); 
+0

에릭 - 답변 해 주셔서 감사합니다! 한 가지 질문 - 마스터 목록에서 ** Enumarable.OfType **을 사용하면 단일 부모 클래스를 만든 다음 생성자의 각 요소 유형을 설정해야합니다. 하위 클래스를 만들지 만 두 유형의 하위 클래스를 모두 보유하는 목록을 만들지 않습니까? 아마 YYY 멘션이나 인터페이스처럼 추상 클래스를 사용하고 있을까? - 내가 바라는 바가 의미가 있기를 바랍니다. –

+0

@ JohnBustos : 목록 을 만들면 Computer의 하위 클래스를 수용 할 수 있습니다. 새 인스턴스를 만들 때 하위 클래스 방식을 사용하는 경우 일반적으로 팩토리 패턴을 사용하여 실제 인스턴스를 만듭니다. 내 대답을 업데이트하여 팩토리 패턴이 어떻게 보이는지 보여줍니다. –

0

당신은 유형이없는 것이 경우 PC에서 모음 및 기타 데이터 가있는 클래스를 만들 수 있습니다.

public class Computers 
{ 
    private List<Computer> pcs= new List<computer>(); 

    public List<Computer> PCs get { return { pcs; } }; 

    public String Brand { get; private set; } 

    public Computers(string brand) {Brand = brand;} 
} 

정적 변수 관련. 모든 구성원이 브랜드를 공유하는 것을 원하지는 않습니다.

와 마찬가지로 생성자에서 데이터를 반복합니다.
Dell이 HP와 동일한 속성을 가진 경우 동일한 클래스를 사용합니다.
새 브랜드를 구입했다면 새로운 클래스 또는 하위 클래스를 만들고 싶습니까?
구조화 된 브랜드 목록을 원한다면 각 브랜드에 대해 별도의 클래스가 아닌 Enum을 사용합니다.

5

가장 가까운 것은 abstract 키워드입니다. Computer이라는 추상 클래스가 있고 구체적인 서브 클래스 인 DellComputerHpComputer에 의해 재정의됩니다. 그 캡슐을 나누기 때문에

public abstract class Computer 
{ 
    public string Type { get; protected set; } 
} 

public class DellComputer : Computer 
{ 
    public DellComputer() 
    { 
     this.Type = "Dell" 
    } 
} 

당신은 일반적으로 인스턴스의 톤 사이에서 하나의 변수를 공유하지 않으 및 단위 테스트를 시도 할 때 더 사실적으로 큰 문제가 될 수 : 원유 (C 번호)를 예로들 수 암호. 따라서 당신이 말하는 순수한 형태는 대단히 좋은 생각은 아니지만 실제적인 유스 케이스는 매우 일반적이며 확실히 지원됩니다.

편집 : 아래 의견의 일부로 매우 밀접하게 관련된 virtual 키워드를 사용하는 다른 접근 방식이 있습니다.

public abstract class Computer 
{ 
    public virtual string Type { get; } 
} 

public class DellComputer : Computer 
{ 
    public override string Type 
    { 
     get { 
      return "Dell"; 
     } 
    } 
} 
+4

상속을 사용하려면 setter를 전혀 제공하지 말고 상수 문자열 만 반환하려면 모든 하위 유형에서 getter를 재정의하십시오. 또한 속성을 가상으로 설정하는 것을 잊지 마십시오. 그대로, 생성자에서 설정 한 단 하나의 속성으로 인스턴스의 수명 동안 속성을 변경할 수 있습니다. * 매우 * 최소한, 당신은'ReadOnly'을 추가함으로써 그것을 막을 수 있습니다. – Servy

+0

기본 클래스에서 'abstract'속성을 개선하는 것이 좋습니다. 이 방법으로 모든 상속 클래스는 속성을 구현해야합니다. 그렇지 않다면 콘드는 컴파일되지 않을 것이다 – GolfWolf

+0

즉,'public abstract string Type {get; }'그리고'public override string Type {get {return "Dell"; }}'in'DellComputer' – GolfWolf

관련 문제