14 重构太阳系(1)

在《嵌套(以太阳系为例)》中,我们显示了太阳、水星、地球和月球。但是所有的代码都是直接丢进文档类中,这样导致文档类比较臃肿,且逻辑关系复杂。很难想象如果将其他行星都加在进来,文档类会是什么样子?

现在是时候重构SunSys项目的时候了。什么事重构呢?重构就是在不改变代码外在行为(功能)的前提下,对代码做出修改,以改进程序内部结构。

分析文档类发现程序中存在4个实体,分别是太阳、水星、地球和月亮。依据面向对象思想,我们为太阳、水星、地球和月亮各自创建一个类,并将图片材质的生成放入各自的类中。

具体代码如下代码清单。

Sun.as

package  
{
    import org.papervision3d.materials.BitmapFileMaterial;
    import org.papervision3d.objects.primitives.Sphere;
    /**
     * ...
     * @author hellopv3d
     */
    public class Sun extends Sphere 
    {
        
        public function Sun() 
        {
            var sunMaterial:BitmapFileMaterial = new BitmapFileMaterial("../assets/sun.jpg");
            super(sunMaterial, 80, 20, 20);
        }
        
    }

}

Water.as

package  
{
    import org.papervision3d.materials.BitmapFileMaterial;
    import org.papervision3d.objects.primitives.Sphere;
    /**
     * ...
     * @author hellopv3d
     */
    public class Water extends Sphere 
    {
        
        public function Water() 
        {
            var waterMaterial:BitmapFileMaterial = new BitmapFileMaterial("../assets/water.jpg");
            super(waterMaterial, 30, 20, 20);
            this.x = 600;
        }
        
    }

}

Earth.as

package  
{
    import org.papervision3d.materials.BitmapFileMaterial;
    import org.papervision3d.objects.primitives.Sphere;
    /**
     * ...
     * @author hellopv3d
     */
    public class Earth extends Sphere
    {
        
        public function Earth() 
        {
            var earthMaterial:BitmapFileMaterial = new BitmapFileMaterial("../assets/earth.jpg");
            super(earthMaterial, 40, 20, 20);
            this.x = 1200;
        }
        
    }

}

Moon.as

package  
{
    import org.papervision3d.materials.BitmapFileMaterial;
    import org.papervision3d.objects.primitives.Sphere;
    /**
     * ...
     * @author hellopv3d
     */
    public class Moon extends Sphere
    {
        
        public function Moon() 
        {
            var moonMaterial:BitmapFileMaterial = new BitmapFileMaterial("../assets/moon.jpg");
            super(moonMaterial, 20, 20, 20);
            this.x = 200;
        }
        
    }

}

SunSys.as

package  
{
    import flash.events.Event;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.view.BasicView;
    /**
     * ...
     * @author yl
     */

    public class SunSys extends BasicView
    {
        private var sun:Sphere;
        private var water:Sphere;
        private var earth:Sphere;
        private var moon:Sphere;
        
        private var waterContain:DisplayObject3D;
        private var earthContain:DisplayObject3D;
        private var moonContain:DisplayObject3D;
        
        public function SunSys() 
        {
            initContain();//初始化容器
            init3DObjects();//初始化3D对象
            //设置摄像机位置
            camera.y = 500;
            camera.z = -2000;
            
            startRendering();        
        }
        
        private function initContain():void {
            //创建容器
            waterContain = new DisplayObject3D();
            scene.addChild(waterContain);
            
            earthContain = new DisplayObject3D();
            scene.addChild(earthContain);
            
            moonContain = new DisplayObject3D();
            earthContain.addChild(moonContain);
            
        }
        
        private function init3DObjects():void {
            createSun();
            createWater();
            createEarth();
            createMoon();
        }
        
        private function createSun():void {
            //创建太阳
            sun = new Sun();
            scene.addChild(sun);
        }
        
        private function createWater():void {
            //创建水星
            water = new Water();
            waterContain.addChild(water);
        }
        
        private function createEarth():void {
            //创建地球
            earth = new Earth();
            earthContain.addChild(earth);
        }
        
        private function createMoon():void {
            //创建月球
            moon = new Moon();
            //调用createEarth方法后才能调用此方法,因为此方法使用到earth对象
            moonContain.position = earth.position;
            moonContain.addChild(moon);
        }
        
        
        override protected function onRenderTick(e:Event = null):void {
            super.onRenderTick();
            //旋转各球体
            earthContain.rotationY++;
            waterContain.rotationY += 2;
            
            earth.localRotationY += 3;
            moonContain.rotationY += 15;
        }    
    }
}

下图为嵌套图,红色为一个部分(earthContain),其包含earth、moonContain、moon;蓝色为一个部分(waterContain),其包含water。


重构后的类图如下所示。


Sun、Water、Earth和Moon继承自Sphere。SunSys和Sun、Water、Earth、Moon、WaterContain、EarthContain、MoonContain为组合关系。

如何判断类之间的组合关系呢?这里有一些简单的判断准则:

1 被组合的类在整体类中被定义。如在SusSys类中定义了属性sun。

2 整体类的构造函数中包含了被组合类的实例化。在我们的代码中,SunSys是文档类(整体类),测试的时候会被自动new,且首先执行构造方法,在SusSys构造方法中实例化了Sun等所有被组合类。这些类紧密的耦合在一起,同生共灭。Sun等组合类是不可以脱离SunSys而独立存在的。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值