zoukankan      html  css  js  c++  java
  • 【回复:致我团队中的程序员应聘者】

    首先要道歉。
    非常抱歉,本来答应前几天回复,不过最近每天真是太忙了,计划表中每天都要实现一个功能,所以直到今天早上才查看并修改。


    代码功能先放在一边,首先有几个问题要说明。


    1.代码不可运行。
    不知道是不是Unity版本不对,
    或是什么别的原因,
    代码拷进来之后根本无法运行,
    提示错误连篇。
    于是我开始大幅度修改,
    直到成功运行。


    不过版本问题先放在一边,
    话说发过来的版本中Init方法中的Window都没有调用Show方法,
    不知道原本是如何运行的。


    2.在半个小时的修改过程中,
    我主要做了以下几件事:


    -----------------------------


    ①.重命名变量。
    比如说那个map_a,
    非局部变量应使用骆驼峰式命名。


    ②.抽取方法。
    当看到OnGUI中格式代码(StartHorizontal)和功能代码混在一起,
    一个方法就有三四十行的时候,
    我有些失去耐心了。


    提取方法我使用了以下几种方法:
    (1).删除重复代码。比如说那个DestroyImmediately,提取成了assertNull,
    还顺便取消原来的"gobj"变量。


    (2)化繁为简。比如说我将两个Button的功能提取为两个方法,简明扼要。


    (3)便于理解。将长代码拆分成不同的功能部分,一来简化代码,其次将不同的
    功能区域区分开,便于阅读。


    ③.减少花括号数目。
    这一点你在编程时也能感受到,
    当五六七八个花括号叠在一起时,
    无论是阅读还是欣赏都毫无意义。
    如果你之前习惯Java或是Android编程,
    那我要提醒一句,
    在Unity或是C#中,
    这么玩可不行。


    双重for循环无法精简,那就将里面的if和else拆分开就可以了。
    使用continue或是break什么的代替,
    很容易就能减少花括号的数量。


    ④.减少临时变量数目。
    obj和gobj的命名问题先放在一边,
    但这两个临时变量多次出现在不同方法,
    这一点就足以证明程序不够精简,
    运行起来也会毫无疑问效率较低。
    尽最大可能减少临时变量的出现,
    尤其是重复出现时,
    就该思考是否有什么方法可以弥补这一点。


    ⑤.取消多余行数/添加符号空格。
    这一点如果你之前习惯使用成熟的编译器可能无法体会,
    但在脚本编程中,
    符号是否有空格就决定了其旁边的变量名是否可以被搜索到,
    也就决定了是否可以使用Ctrl + H来重命名。
    要知道脚本语言大部分无法被Refactor。
    成千上万行的脚本,如果无法使用Ctrl+H来重命名,
    那修改代码的效率自然可以想象。


    至于行数的作用,
    最主要的就是分隔功能块。
    如果这一点无法保证,
    那代码注释再多也无济于事。


    ⑥.添加/取消注释。
    之前你跟我说我的代码的注释太少,
    我承认这一点。
    在一个人编程的时候,
    我并不太过在意注释问题,
    因为我崇尚一条真理:


    ——最好的注释就是没有注释。


    为什么?
    因为将所有注释应该写明的东西,
    用完整的命名,有条理的顺序,以及规范的格式就可以表现。
    脱离这一点,
    试图使用注释来弥补其他方面的弊端,
    那自然是欲盖弥彰。


    除此之外,
    代码中尽量不要出现中文,
    这也是成熟团队的一个默认标准。


    -----------------------------


    这只是一个检验,
    我并不只是想看看应试者是否能够"实现"什么东西,
    更重要的是希望看到你们如何来"实现"。


    你们每个人并不是对Unity都非常了解,
    正因如此,
    类似as关键词的使用或是接口选择之类的问题我并未列在上述表单之中。


    但编程能体现的是一个编程者对于程序的理解,
    以及他的经验。


    功能在我看来是最简单不过的东西,
    一个功能,研究一天,一星期或是一个月一年总该有结果,
    但实现的过程,
    却并非一朝一夕可以完善的。


    团队编程最重要的就是相互之间的默契,
    而代码,就是程序员之间的交流语言,
    一注释一空格之间就足以表明诸多要素。


    我自己热爱编程,
    每次编程都能够乐在其中,甚至大多数情况都无法自拔。
    因为我将编程的过程看作是写诗,
    如何去构造,如何去描述,如何选词酌句,
    都是需要大量的实践与思考才能至善至美的。
    在这个过程中,
    我可以很明显地可以感受到沉浸其中所带来的快乐的。


    抛开这一点不提,
    程序员最讨厌的莫过于Bug。
    而绝大多数的Bug并非在于逻辑错误,
    而是在于编程规范。
    如何减少Bug,
    也是编程水平提升的重要一步。



    至此,
    再次为我迟到的回复致以歉意。
    并推荐几本书,供你日后编程作为参考:


    《Clean Code》
    《Refactoring To Patterns》

    《敏捷编程系列》


    更改后代码:

    using UnityEngine;
    using UnityEditor;
    using System.Collections;
    
    public class MapGenerator: EditorWindow 
    {
    	/// <summary>
    	/// The height of the meta prefab.
    	/// </summary>
    	int prefabHeight = 1;
    	int prefabWidth = 1;
    	
    	const int horizontalNumber = 8;
    	const int verticalNumber = 8;
    	
    	/// <summary>
    	/// The map array.
    	/// </summary>
    	public Object[,] mapArray = new Object[verticalNumber,horizontalNumber];
    	
    	[MenuItem ("MyTools/MapGenerator")]
    	static void Init () 
    	{
    		MapGenerator window = (MapGenerator)EditorWindow.GetWindow(typeof (MapGenerator));
    		
    		window.Show();
    	}
    	
    	void OnGUI () 
    	{
    		// setting of prefab
    		GUILayout.Label ("Basic Settings", EditorStyles.boldLabel);
    		
    			prefabHeight = EditorGUILayout.IntField ("PrefabHeight:",prefabHeight);
    			prefabWidth = EditorGUILayout.IntField ("PrefabWidth:",prefabWidth);
    		
    		EditorGUILayout.Space();
    		
    		// the area of map editor
    		GUILayout.Label ("MapEditor", EditorStyles.boldLabel);
    		
    			for(int j = 0;j < horizontalNumber;j++)
    			{
    				EditorGUILayout.BeginHorizontal();
    				
    					for(int i = 0;i < verticalNumber;i++)
    						mapArray[i,j] = EditorGUILayout.ObjectField(mapArray[i,j],typeof(Object), true);
    					
    				EditorGUILayout.EndHorizontal();
    	   		}
    			
    		EditorGUILayout.Space();
    		
    		// the area of button
    		EditorGUILayout.BeginHorizontal();
    		
    			if (GUILayout.Button("Create"))
    				Create();
    			
    			if (GUILayout.Button("Reset"))
    				Reset();
    		
    		EditorGUILayout.EndHorizontal();
    	}
    	
    	private void Create()
    	{
    		for(int j = 0;j < horizontalNumber;j++)
    		{
    			for(int i = 0;i < verticalNumber;i++)
    			{
    				if(null == mapArray[i,j])
    					continue;
    				
    				assertNull(GameObject.Find("Tile" + j + i));
    						
    				Vector3 pVector = new Vector3(i*prefabWidth, (horizontalNumber-j)*prefabHeight, 0);
    				
    				generateObject(pVector,j,i);
    			}
    		}	
    	}
    	
    	private void Reset()
    	{
    		prefabWidth = 1;
    		
    		prefabHeight = 1;
    		
    		for(int j = 0;j < horizontalNumber;j++)
    		{
    			for(int i = 0;i < verticalNumber;i++)
    			{
    				if(null == mapArray[i,j])
    					continue;
    					
    				assertNull(GameObject.Find("Tile" + j + i));
    				
    				mapArray[i,j] = null;
    			}
    		}		
    	}
    	
    	/// <summary>
    	/// Generate object and assign some properties
    	/// </summary>
    	/// <param name='pos'>
    	/// Generate position.
    	/// </param>
    	/// <param name='h'>
    	/// Index of height
    	/// </param>
    	/// <param name='w'>
    	/// Index of weight.
    	/// </param>
    	protected void generateObject(Vector3 pos,int h,int w)
    	{
    		Object obj = Instantiate(mapArray[h,w],pos, Quaternion.identity);
    			
    		obj.name = "Tile" + h + w;
    		
    		(obj as GameObject).transform.localScale = new Vector3(prefabWidth,prefabHeight,1);
    	}
    	
    	/// <summary>
    	/// Asserts the gameObject is null.
    	/// </summary>
    	/// <param name='gameObject'>
    	/// Game object.
    	/// </param>
    	protected void assertNull(GameObject gameObject)
    	{
    		if(gameObject)
    			DestroyImmediate(gameObject);
    	}
    }


    By Elezor 2013.8.24

  • 相关阅读:
    QT类型转换(九种转换)
    QString类的使用(无所不包,极其方便)
    在TreeWidget中增加右键菜单功能 以及TreeWidget的基本用法
    在ubuntu上安装nodejs[开启实时web时代]
    排序和搜索
    new关键字
    Dynamicaly Typed(动态定型), Objective-C Runtime Programming
    图形化机构树
    java-并发之高性能对象
    委托的基本理解与使用
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3279862.html
Copyright © 2011-2022 走看看