我正在制作一个有几个课程的游戏,每个人都会做一些特定的任务。
我对OOP是全新的,我想知道我应该做些什么来让我的类实例在彼此之间进行通信,而不需要重复使用静态类,方法和属性,这似乎是一件非常糟糕的事情。
我是自学成才的程序员,我意识到我做了很多不好的做法。到目前为止,我设法让这个工作使这两个类保持静态但我想知道我应该做些什么来使我的代码尽可能好。
另外,如果您可以向我推荐一些资源/书籍/文章,那么我会更好地了解这个主题(实例之间的通信)。
以下是一段代码,以便您了解我在说什么。
class Program
{
static void Main(string[] args)
{
Class1 instance1 = new Class1();
Class2 instance2 = new Class2();
// infinite loop
while (true)
{
instance1.UpdateMethod(someValue);
instance2.UpdateMethod();
}
}
}
class Class1
{
int Property;
UpdateMethod(int argument)
{
Property += argument;
if(Property == 3000)
{
// I should change the state of instance2
}
}
}
class Class2
{
UpdateMethod()
{
if(Time.GetTime() == SomeTime)
{
// here I want to change the state of instance1
}
}
}
答案 0 :(得分:2)
有关常见设计模式的概述,我建议
http://en.wikipedia.org/wiki/Category:Software_design_patterns
如果Class1
和Class2
之间存在自然关系,则一个实例保持对另一个实例的引用是很常见的。例如,如果您有一个Player
课程,并且该播放器有Weapon
,请按以下方式定义您的课程:
public class Player
{
public Weapon Weapon { get; set; }
// Other properties
}
特别是在您的情况下,您似乎想要从Class1
的实例更新Class2
的实例。我建议您在Class2
上定义一个属性,该属性包含Class1
的相关实例,就像上面的示例一样。
在软件工程中,复合模式是一个分区 设计模式。复合模式描述了一组 对象的处理方式与单个实例的处理方式相同 宾语。复合的目的是将对象“组合”成树 用于表示部分整体层次结构的结构。实施 复合模式允许客户处理单个对象和 成分均匀。
经常用于对象实例的另一种模式是Command Pattern。
在面向对象的编程中,命令模式是一种设计 一个对象用于表示和封装所有对象的模式 稍后调用方法所需的信息。这个 信息包括方法名称,拥有该方法的对象 和方法参数的值。三个词总是相关的 命令模式是客户端,调用者和接收者。客户端 实例化命令对象并提供所需的信息 稍后调用该方法。调用者决定什么时候 方法应该被调用。接收者是该类的一个实例 包含方法的代码。使用命令对象可以更容易 构造需要委托,序列或的一般组件 在他们选择的时候执行方法调用而不需要 知道方法的所有者或方法参数。
答案 1 :(得分:0)
我建议你两个链接和内容可以自由阅读
http://msdn.microsoft.com/en-us/library/dd460654.aspx
关于具有更好细节的模式的更多内容是http://www.codeproject.com/Articles/22769/Introduction-to-Object-Oriented-Programming-Concep
最后一个来自叔叔鲍勃对OOD原则http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
的良好解释答案 2 :(得分:0)
如果需要从另一个类更改对象的状态,则需要对其进行引用。通常的方法是通过构造函数:
public class Class2
{
private readonly Class1 instance;
public Class2(Class1 instance)
{
this.instance = instance;
}
public void UpdateMethod()
{
if(VisualStyleElement.TaskbarClock.Time.GetTime() == SomeTime)
{
// here I want to change the state of instance1
this.instance.SomeProperty = "Some Value";
}
}
}
或通过传递给方法的参数
public class Class2
{
public void UpdateMethod(Class1 instance)
{
if (VisualStyleElement.TaskbarClock.Time.GetTime() == SomeTime)
{
// here I want to change the state of instance1
instance.SomeProperty = "Some Value";
}
}
}
在第一种情况下,你会这样称呼它:
Class2 instance2 = new Class2(instance1);
instance2.UpdateMethod();
在第二种情况下,你会这样称呼它:
Class2 instance2 = new Class2();
instance2.UpdateMethod(instance1);
答案 3 :(得分:0)
欢迎来到OOP的世界! 要理解的一件重要事情是继承的概念。继承关于是的内容。孩子是一个人,母亲是一个人。
请看一下这个型号:
public class Person
{
protected string Name;
public string WhatsYourName()
{
return this.Name;
}
}
public class Mother: Person
{
public Mother(string personName)
{
this.Name = personName;
}
}
public class Child : Person
{
public Mother MyMother { get; set; }
public Child(string personName)
{
this.Name = personName;
}
public string WhoAreYou()
{
return string.Format("My name is {0} and my mom is {1}", this.Name, this.MyMother.WhatsYourName());
}
}
现在,对象如何与对方交谈?有很多方法可以实现这一目标,但这一切都来自一个简单的概念:参考。 当您创建一个对象(x = new ...)时,您正在创建一个新的实例,并且您有引用。
现在,看看这个:
static void Main(string[] args)
{
Mother mary = new Mother("Mary");
Child bobby = new Child("Bobby");
bobby.MyMother = mary;
Console.WriteLine(bobby.WhoAreYou());
Console.ReadLine();
}
看看我们什么时候设置Bobby的母亲?我们正在传递对象引用。
请看一下这段代码,我相信它可以提供帮助。
此外,我强烈建议您阅读设计模式。 也许从这里开始:http://www.dofactory.com/Patterns/Patterns.aspx/
希望这有帮助。
答案 4 :(得分:0)
这完全取决于Class1
和Class2
是什么以及它们是否需要耦合。
如果他们做不相关的事情并且不需要彼此了解,您可以使用事件来传达他们之间的变化:
class Program
{
static void Main(string[] args)
{
Class1 instance1 = new Class1();
Class2 instance2 = new Class2();
instance1.CriticalValueReached += instance2.DoSomething;
instance2.TimeoutElapsed += instance1.DoSomething;
// infinite loop
while (true)
{
instance1.UpdateMethod(someValue);
instance2.UpdateMethod();
}
}
}
class Class1
{
int Property;
public event Action CriticalValueReached;
public UpdateMethod(int argument)
{
Property += argument;
if (Property == 3000)
RaiseCriticalValueReached();
}
public void DoSomething()
{
// Whatever...
}
private void RaiseCriticalValueReached()
{
var handler = CriticalValueReached;
if (handler != null)
handler();
}
}
class Class2
{
public event Action TimeoutElapsed;
public UpdateMethod()
{
if (Time.GetTime() == SomeTime)
RaiseTimeoutElapsed();
}
public void DoSomething()
{
// ...
}
private void RaiseTimeoutElapsed()
{
var handler = TimeoutElapsed;
if (handler != null)
handler();
}
}