当使用extract方法进行重构时,应该提取到一个新类中还是提取到当前类中



我一直在使用extract方法来使代码流更容易理解,但现在我已经在类文件的底部转储了大量这些方法。我曾想过为这些方法或它们的组创建单独的类,但我只是担心这是否会增加不必要的复杂性。任何优雅地做这件事的技巧都将不胜感激。

例如——我知道这是巨大的,打破了几个原则,我现在正在大力学习SOLID原则,但我已经养成了多年的坏习惯。

这是一个统一的自定义GUI检查器,用于在我的游戏中制作过场。

#if UNITY_EDITOR
[CustomEditor(typeof(Cutscene))]
public class CutsceneEditor: Editor
{
GameObject parent;
Cutscene cutscene;
GameObject currentMarker = null;
SerializedProperty startMarker, sequenceList;
string[] actionOptions = {"Movement", "Poses"};
float scrollbarOffset;
GUIContent noLabel = new GUIContent();
List<bool> foldouts;
int currentFoldout;
string hideText;
void OnEnable() 
{
cutscene = (Cutscene)target;
parent = GameObject.FindGameObjectWithTag("PathUI");
startMarker = serializedObject.FindProperty("startMarker");
sequenceList = serializedObject.FindProperty("cutsceneSequences");   
noLabel.text = "";
foldouts = new List<bool>();
//IsPathIsVisible();
if (Application.isPlaying == false && (IsPathIsVisible() == true))
{
DrawCutscenePath(1);
}
foreach(SerializedProperty Cs in sequenceList)
{
foldouts.Add(false);
}
}
public override void OnInspectorGUI() 
{
if (Application.isPlaying == false)
{
DisplayCutsceneTabs();
}
}
void DisplayCutsceneTabs()
{
for (int i = 0; i < sequenceList.arraySize; i ++)
{
EditorGUILayout.Space(5);
var sequenceElement = sequenceList.GetArrayElementAtIndex(i);
var actionMarker = serializedObject.FindProperty("actionMarker");
var actionMarkerArrow = serializedObject.FindProperty("actionMarkerArrow");
var startPoint = sequenceElement.FindPropertyRelative("cutsceneStartPoint");
var startRotation = sequenceElement.FindPropertyRelative("cutsceneStartRotation");
var cutsceneAction = sequenceElement.FindPropertyRelative("cutsceneAction");
var actionSelection = sequenceElement.FindPropertyRelative("actionSelectionIndex");
var timeToWait = sequenceElement.FindPropertyRelative("timeToWait");
var maxTimeToWait = sequenceElement.FindPropertyRelative("maxTimeToWait");
var voiceClip = sequenceElement.FindPropertyRelative("voiceClip");
var hasDialogue = sequenceElement.FindPropertyRelative("hasDialogue");
var voiceClipDelay = sequenceElement.FindPropertyRelative("voiceClipDelay");
var voiceClipVolume = sequenceElement.FindPropertyRelative("voiceClipVolume");

if (i == 0)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Start Point Object");
EditorGUILayout.LabelField("Cutscene Markers");
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PropertyField(startMarker, noLabel);
EditorGUILayout.PropertyField(actionMarker, noLabel);
EditorGUILayout.PropertyField(actionMarkerArrow, noLabel);
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space(10);
// set start position to start markers position
if (startMarker.objectReferenceValue != null)
{
GameObject startObject = startMarker.objectReferenceValue as GameObject;
startPoint.vector3Value = startObject.transform.position;
startRotation.quaternionValue = startObject.transform.rotation;
}
HandleButtons(0);
DrawBlackBox();
continue;
}


if (foldouts[i] = EditorGUILayout.BeginFoldoutHeaderGroup(foldouts[i], "Cutscene Action " + "#" + " " + i))
{
currentFoldout = i;
CloseAlmostAllFoldouts(i);
if (i > 0)
{
EditorGUILayout.BeginHorizontal();
actionSelection.intValue = EditorGUILayout.Popup(actionSelection.intValue, actionOptions, GUILayout.MaxWidth(100));
if (actionSelection.intValue == 0)
{
cutsceneAction.objectReferenceValue = EditorGUILayout.ObjectField(cutsceneAction.objectReferenceValue, typeof(MovementAction), false) as MovementAction;
}
if (actionSelection.intValue == 1)
{
cutsceneAction.objectReferenceValue = EditorGUILayout.ObjectField(cutsceneAction.objectReferenceValue, typeof(PoseAction), false) as PoseAction;
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();

timeToWait.floatValue = EditorGUILayout.Slider(timeToWait.floatValue, 0, maxTimeToWait.floatValue);
maxTimeToWait.floatValue = EditorGUILayout.FloatField(maxTimeToWait.floatValue,  GUILayout.MaxWidth(25));
if(EditorGUI.EndChangeCheck())
{
DrawCutscenePath(i);
}            
EditorGUILayout.EndHorizontal();
}
scrollbarOffset = (sequenceList.arraySize < 8) ? 20 : 32;
hasDialogue.boolValue = EditorGUILayout.ToggleLeft("Show Voice Options", hasDialogue.boolValue);
if (hasDialogue.boolValue == true)
{
EditorGUILayout.PropertyField(voiceClip);
voiceClipVolume.floatValue = EditorGUILayout.Slider("Volume", voiceClipVolume.floatValue, 0, 2);
voiceClipDelay.floatValue = EditorGUILayout.Slider("Delay", voiceClipDelay.floatValue, 0, maxTimeToWait.floatValue);

if (voiceClip.objectReferenceValue != null)
{
if (GUILayout.Button("Remove Voice Clip"))
{
voiceClip.objectReferenceValue = null;
voiceClipVolume.floatValue = 1;
voiceClipDelay.floatValue = 0;
}
}
}

HandleButtons(i);
DrawBlackBox();        
serializedObject.ApplyModifiedProperties();
}
EditorGUILayout.EndFoldoutHeaderGroup();
if (i == sequenceList.arraySize - 1)
{
var DrawPathButtonArea = EditorGUILayout.BeginVertical();
EditorGUILayout.Space(40);
EditorGUILayout.EndVertical();
if (GUI.Button(new Rect(0, DrawPathButtonArea.y, Screen.width, 20), (hideText != null)? hideText : "Hide Cutscene Tab"))
{
HideCutscenePath();
}
}
}
}
void HandleButtons(int i)
{
var tabEnd = EditorGUILayout.BeginHorizontal();
EditorGUILayout.EndHorizontal();
if (GUI.Button(new Rect(0, tabEnd.y + 15, 75, 20), "New Move"))
{
sequenceList.InsertArrayElementAtIndex(i);
CutsceneSequenceDisplay.InitializeNewMove(sequenceList.GetArrayElementAtIndex(i + 1));
foldouts.Insert(i, false);
if (i != 0)
DrawCutscenePath(i);
}
if (i > 0)
{
if (GUI.Button(new Rect(Screen.width - scrollbarOffset - 20, tabEnd.y + 15, 20, 20), "D"))
{
foldouts.Insert(i, false);
sequenceList.InsertArrayElementAtIndex(i);
DrawCutscenePath(i);
CloseAlmostAllFoldouts(i);
}
if (GUI.Button(new Rect(Screen.width - scrollbarOffset, tabEnd.y + 15, 20, 20), "X"))
{
if (i != 0)
{          
foldouts.RemoveAt(i);
sequenceList.DeleteArrayElementAtIndex(i);   
DrawCutscenePath((i)=i != 1 ? i - 1 : i);          
}
else if (sequenceList.arraySize > 0)
{
foldouts.RemoveAt(i + 1);
sequenceList.DeleteArrayElementAtIndex(i + 1);
}         
}
}
serializedObject.ApplyModifiedProperties();
}
void CloseAlmostAllFoldouts(int index)
{
for (int i = 0; i < foldouts.Count; i++)
{
if(i != index)
{
foldouts[i] = false;  
}
}
}
void DrawCutscenePath(int index)
{
GameObject[] parents = GameObject.FindGameObjectsWithTag("ParentUI");
if (IsPathIsVisible() == true || parents.Length > -1) 
{
if (parents.Length != 0)
{
for(int i = index - 1; i < parents.Length; i++)
{
if (parents[i].activeSelf == true)
{
DestroyImmediate(parents[i].gameObject);
}
}
}      
for (int i = index; i < sequenceList.arraySize; i ++)
{
var thisSequenceElement = sequenceList.GetArrayElementAtIndex(i);
var cutsceneAction = thisSequenceElement.FindPropertyRelative("cutsceneAction").objectReferenceValue;
if (cutsceneAction is MovementAction)
{
CutsceneSequenceDisplay.ProcessMovementPathing(i, sequenceList, serializedObject, ref currentMarker);
}
if (cutsceneAction is PoseAction)
{
CutsceneSequenceDisplay.ProcessPosePathing(i, sequenceList, serializedObject, ref currentMarker);
}
}    
}
}
bool IsPathIsVisible()
{
foreach (Transform child in parent.transform)
{
if (child.gameObject.activeSelf == true)
{
return true;
}
}
return false;
}
void HideCutscenePath()
{    
if (parent != null)
{
bool isPathVisible = false;
foreach (Transform child in parent.transform)
{
child.gameObject.SetActive(!child.gameObject.activeSelf);
isPathVisible = child.gameObject.activeSelf;
}
hideText = (isPathVisible) ? "Hide Cutscene Path" : "Show Cutscene Path";
}

}
void DrawBlackBox()
{
Color boxColor = new Color(0,0,0,0.2f);
EditorGUILayout.Space(15); 
var position = EditorGUILayout.BeginVertical();
EditorGUI.DrawRect(new Rect(0,position.y,Screen.width,20), boxColor);
EditorGUILayout.EndVertical();
EditorGUILayout.Space(20); 
}
}
#endif

好吧,这……取决于情况。根据经验,尽量减少类中私有方法的数量,它们总是一个坏兆头。遵循单一责任原则:一个类应该只做一件事。

此外,更喜欢组合而不是继承:处理长继承链可能会变得复杂,并导致严重的错误。请改用"组件"来定义对象的行为。

无论如何,如果你发布一些示例代码,我们可能会更具体:(

最新更新