编辑:已编辑以提供更多特定代码
正如你所看到的,我的精灵绘图违反了这条规则。
如果有人能够根据我的代码解释,我会非常感激(这是因为我已经阅读了很多关于这条规则的解释,但我仍然没有&#39我真的明白为什么它是一个问题或如何在不破坏这条规则的情况下做我需要做的事情:-()
1)为什么这会导致我的代码出现问题?
&安培;
2)请解释一下我尝试做的另一种方法(同时保留一个专门用于加载资源和创建精灵对象的单独资源类)。 / p>
通过2个或更多类对象访问对象是否有任何问题。我将通过一些代码解释:
这里我有3个类,从class2到另一个对象访问方法有什么问题,如下面的第三个类..........:
代码
我的资源类
//Resource class
public Class Resource(){
Bitmap myTexture;
Quad mySprite;
public void LoadResources(){
//Load graphics
myTexture = BitmapFactory.decodeResource(view.getResources(), R.drawable.myBitmap);
//Create my objects
mySprite = new Quad(); //Create new Quad object
mySprite.setTexture(myTexture); //Set texture to this quad
mySprite.setSize(100,100); //Set size of this quad
}
}
我的四类
public class Quad(){
//This custom class has the bulk of the code to create all of the Quads / Sprites
public void setTexture(Bitmap textre){
//etc.....
}
//etc....
}
public void draw(int x, int y){
//Draw code here
}
最后,我的主要GLRenderer课程:
public class MyGLRenderer implements GLSurfaceView.Renderer{
Resource res;
public MyGLRenderer(){
res = new Resources(); //Create object to my resources
}
public voide onDrawFrame(){
//Here is my main loop and I need to draw my sprites here, so........
res.mySprite.draw(x, y); //Draw my sprite
}
答案 0 :(得分:7)
违反法律
这违反了称为law of demeter的编码习惯。该法律规定您只应与“旁边的”课程交谈。
为什么这是一件坏事
原因是,通过调用其他几个类中的方法,您的类需要了解这些方法,并依赖于那些方法的变化。这称为close coupling。如果方法发生变化,则需要更改其他类中的大量代码。这被称为“Shotgun手术”,并不是一个程序中令人满意的功能!
可能的解决方案
查看代理设计模式。它主要用于为另一个类提供接口,它可能对您有所帮助。也许通过引用这两个对象,这个类可以为所有方法提供一个通用接口来进行通信,并减少类之间的耦合。
你的榜样实际上并不那么糟糕。你得到一个对象,然后对它进行方法调用。依赖项以一种形式出现:如果从类中删除mySprite
字段,则代码将无法正常工作,如果从sprit中删除draw
方法,则无效。对我而言,最简单的解决方案是向Proxy method
类添加Resources
,该类名为draw()
,接受sprite
作为参数。
其次,也许不是直接访问mySprite
,而是可以通过方法。假设你有一个看起来像这样的成员:
private ArrayList<Quad> sprites = new ArrayList<Quad>();
这意味着为了从外部访问这些精灵,你需要有某种方法。现在,通过强制其他类通过这些方法进行通信,您可以减少耦合。这是因为原始类只需要知道另一个类中的一个方法,而另一个类将完成这项工作。然后你写了一个drawSprite
方法,看起来像:
public void drawSprite(int index) // Index really is up to you {
sprites.get(x).draw();
}
现在我知道它可能有更多参数,但它只意味着来自MyGLRenderer
类的一个方法调用,因此符合demeter定律,并减少类中的耦合。
答案 1 :(得分:1)
正如迈克指出的那样,只有在你进入方法时,在任何SomeClass
方法中实例化的类才是“活着的”/有效的。这意味着实例化对象特定于方法,并且无法在方法外部访问。
解决方案是向SomeClass2
添加SomeClass
成员。如果你在SomeClass
的构造函数中实例化这个成员,它将保持活着直到SomeClass
在范围内,使你可以使用它。代码看起来像这样:
SomeClass的:
class SomeClass
{
// Define the class attributes. This class can be then accessed publicly
SomeClass2 class2
// Constructor - Instantiate all your members here
public SomeClass()
{
// Instantiate class2 in the constructor
this.class2 = new SomeClass2();
}
// Your method which does what you need
public void classMethod()
{
class2Object.class2Method();
}
}
SomeClass2将保持不变
而SomeClass3将是:
class SomeClass3
{
public void class3Method()
{
SomeClass classObject = new SomeClass();
// Call the instantiated member and then call it's method
classObject.class2.class2Method();
}
}
这应该编译/运行。我会对设计发表评论,但在我做之前,我会等你知道你打算用它做什么! :)
答案 2 :(得分:0)
它会工作(除了你在方法中声明了你的SomeClass2
对象,它应该在类中作为成员变量,但我认为这是一个错字。)
但我会考虑使用getter和setter(它被认为是更好的练习):
class SomeClass{
private SomeClass2 class2Object = new someClass2();
public SomeClass2 getClass2Object() { return class2Object; }
}
class SomeClass2{
public void class2Method(){
//Some code here
}
}
SomeClass3{
public void class3Method(){
SomeClass classObject = new SomeClass();
classObject.getClass2Object().class2Method();
}
}