Вот небольшая проблема у меня есть в упражнении.
Задача состоит в том, чтобы упростить этот перегруженный, причудливо выглядящий код, сохранив при этом функциональность GameManager. Идея состоит в том, чтобы сделать его более читабельным. Я в недоумении, что делать и с чего начать, так как я полностью понимаю код и то, как он работает. Мысль о преобразовании цикла в собственную функцию пришла мне в голову, но это все.
Любые предложения о том, как действовать, что вырезать, что изменить и как?
Заранее спасибо.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Game
{
public class GameManager : MonoBehaviour
{
List<IUpdateable> _gameEntities = new List<IUpdateable>();
int _npcCount = 1000;
public void Awake()
{
for (int i = 0; i < _npcCount; i++)
{
var npc = new NPC();
npc.ID = i;
_gameEntities.Add(npc);
}
var player = new Player();
player.ID = _npcCount + 1;
_gameEntities.Add(player);
}
public void ChangeNPCName(int id, string name)
{
foreach (var entity in _gameEntities)
{
if (entity is NPC)
{
var npc = entity as NPC;
if (npc.ID == id)
{
npc.ChangeName(name);
}
}
}
}
public void ChangePlayerName(string name)
{
foreach (var entity in _gameEntities)
{
if (entity is Player)
{
entity.ChangeName(name);
entity.Save();
}
}
}
}
public interface IUpdateable
{
void ChangeName(string name);
void Save();
}
public abstract class Entity<T> where T : IUpdateable
{
protected string _name;
private int _id;
public int ID { get => _id; set => _id = value; }
public void ChangeName(string name)
{
_name = name;
}
}
public class NPC : Entity<NPC>, IUpdateable
{
public void Save()
{
}
}
public class Player : Entity<Player>, IUpdateable
{
public void Save()
{
}
}
}
Для меня это выглядит довольно просто, единственное... может быть... это то, что вы не используете (на данный момент) значение Entity _id, поэтому ваше свойство с get;set; результаты на том же. Сказав это... Я все равно сохраню частное значение, потому что пахнет так, как будто вы собираетесь расширить функциональные возможности Entity, которым потребуется это частное значение.
С точки зрения того, как действовать, общий совет будет заключаться в том, чтобы написать несколько модульных тестов для существующего кода, охватывающих все функции. Затем вы можете начать инкрементный рефакторинг с уверенностью, что ваши тесты подтвердят правильность поведения кода.
Благодарю вас! Я работаю над внедрением его в Unity для функционального тестирования.
На первый взгляд, код достаточно компактен, чтобы понять его с первого взгляда. Единственное, что можно было бы решить с точки зрения упрощения, — это избавиться от иерархии классов/интерфейсов.
NPC
и Player
их базовым классом Entity (просто укажите их тип с помощью свойства или поля и, возможно, внешних функций, чтобы настроить их поведение/стратегию)IUpdateable
, чтобы Entity можно было использовать как простой класс во всех местах.Благодарю за ваш ответ! У меня возникли проблемы с пониманием идеи/процесса, стоящего за пунктами 1 и 2. Как бы вы сделали это в коде? Надеюсь, это не слишком большая проблема для вас. Раньше я не работал с абстрактными классами, поэтому для меня это совершенно новое.
@Mightysaurus просто описывает класс Entity
, который, например, принимает метод в конструкторе. Предоставленный внешний метод будет играть роль реализации метода Save
, поэтому при необходимости вы можете изменить поведение конкретного экземпляра Entity
.
Если ваш код работает, рассмотрите возможность публикации на Обзор кода вместо этого (следуя рекомендациям в их Центр помощи).