Как мне упростить мой код? - PullRequest
3 голосов
/ 24 марта 2010

Я только что закончил создание своего первого основного приложения на C # / Silverlight. В итоге общее количество строк составило более 12 000 строк кода. Учитывая, что это было переписано php / javascript-приложение, которое я создал за 2 года, в котором было более 28 000 строк, я на самом деле очень горжусь своим достижением.

Прочитав много вопросов и ответов здесь на stackoverflow и других сайтах в Интернете, я последовал совету многих авторов: я создал классы, процедуры и тому подобное для вещей, которые я бы скопировал и вставил год назад; Я создал логические схемы для определения сложных функций; убедитесь, что нет сумасшедших скрытых символов (вместо табуляции используются табуляция); и несколько других вещей; при необходимости размещайте комментарии (у меня много комментариев).

Мое приложение состоит из 4 плиток, расположенных горизонтально, с пользовательскими элементами управления, загруженными в каждый слайс. Вы можете загружать от одного до четырех фрагментов в любое время. Если у вас есть один загруженный срез, он занимает весь артборд ... если у вас есть 2 загруженных, каждый занимает половину, 3 третью, 4 четверть.

Каждый из этих кусочков представляет (для примера) управление освещением. Каждый срез имеет 3 элемента управления ползунка в нем. Теперь, когда я закодировал функциональность ползунков, я использовал оператор switch / case внутри публичной функции, которая запускала команду на указанном слайсе / слайдере. Это создало некоторый дубликат кода, но я не нашел пути его обойти, так как каждый фрагмент был назван по-своему. Так что я бы сделал slice1.my.commands (); slice2.my.commands (); и т.д.

Мой вопрос к вам: как мне очистить мой код еще дальше? (К сожалению, я не могу опубликовать свой код). Есть ли способ вынести это повторение из моего кода?

Ответы [ 5 ]

11 голосов
/ 24 марта 2010

Что вам нужно, так это интерфейс с вашим другом паттерном Стратегия. Например:

public interface ISlice 
{
    public Slider Slide {get;set;}
}

public class Slice1 : ISlice 
{
    public Slider Slide { get; set; }
}

public static class SliceSlider
{
    public static void DoSomethingCoolWithTheSliceSlide(ISlice slice) 
    {
        slice.Slide.LookitMeIAmLearningDesignPatterns();
    }
} 
7 голосов
/ 24 марта 2010

Написание меньшего количества кода не должно быть вашей целью. В конце концов, это все о совокупной стоимости владения.

Хотя меньшее количество кода может улучшить совокупную стоимость владения, существует один фактор, который оказывает гораздо большее влияние на совокупную стоимость владения: удобство обслуживания. Вы должны написать наиболее поддерживаемый код. Начните с чтения Чистый код Роберта Мартина .

Обновление:

Также вы говорите «У меня много комментариев» . Это точка, где вы можете улучшить свой код. Как вы узнаете из книги Мартина, хороший код вряд ли нуждается в комментариях. Мартин говорит, что «комментарии - это ложь» и «должны быть зарезервированы для технических заметок о коде и дизайне». .

Обновление 2:

Пока я добавляю это, вот мои любимые цитаты из книги Роберта Мартина:

  • "класс или модуль должен иметь одну и только одну причину для изменения [Принцип единой ответственности]" [стр. 138]
  • "Более трех [аргументов метода] очень сомнительно и их следует избегать с предубеждением." [стр. 288]
  • «Первое правило функций состоит в том, что они должны быть маленькими. Второе правило функций заключается в том, что они должны быть меньше этого». [стр. 34]
  • «Вряд ли длина функций должна составлять 20 строк» ​​ [стр. 34]
  • «Все операторы в функции должны быть написаны на одном уровне абстракции» [стр. 304]
  • "Комментарии должны быть зарезервированы для технических примечаний о коде и дизайне." [страница 286]
2 голосов
/ 24 марта 2010

Интерфейсы и абстрактные классы являются очень сильной частью платформы .net.

Интерфейс - не что иное, как требование контракта для класса.То есть: интерфейс - это определенный набор методов и / или свойств, которые должен иметь класс, реализующий этот интерфейс.Интерфейс - это просто объявление контракта.

Абстрактный класс действительно мощный, потому что вы можете переносить логику в классы, реализующие этот абстрактный класс.Но это совсем другая игра с мячом.

Рассмотрим:

public interface ISlice
{
    bool DoStuff(string someParameter);
}

public class MySpecificSliceOfType : ISlice
{
    // this must have a method implementation for the [bool DoStuff(string)] method
    public bool DoStuff(string mySpecificParameter)
    {
       // LOGIC in the Specific class
       return(true);
    }
}

public class MyOtherSliceOfType : ISlice
{
    // this must have a method implementation for the [bool DoStuff(string)] method
    public bool DoStuff(string myOtherParameter)
    {
       // LOGIC in the Other class
       return(true);
    }
}

Хотя это сильно упрощенный пример, объявляет реализацию интерфейса интерфейса ISlice как для классов "MySpecificSliceOfType", так и для классов.«MyOtherSliceOfType» означает, что необходимый метод DoStuff () не зависит от того, какой у вас есть, потому что вы можете делать такие вещи, как:

bool sliceReturn = ((ISlice)currentSlice).DoStuff(currentStringParameterValue);

Это может спасти вас от работы в таких вещах, как:

bool sliceReturn = false;
switch(typeofSlice)
{
    case "other" :
        sliceReturn = MyOtherSliceOfType.DoStuff(currentStrignParamterValue);
        break;
    case "specific" :
        sliceReturn = MySpecificSliceOfType.DoStuff(currentStrignParamterValue);
        break;
}

Суть, проиллюстрированная здесь, становится еще более сильной, если у вас> 2 разных типа.

И интерфейсы, и абстрактные классы прекрасно сочетаются с проверкой типа C #.

Интерфейсы являются фундаментальнымив Reflection ... что-то, что нужно использовать очень экономно, но недооценено, потому что это может сэкономить так много в определенных случаях ... и в сериализации (иначе как сериализация), которая действительно может помочь вам летать.

2 голосов
/ 24 марта 2010

Я склонен согласиться со Стивеном. Написание меньшего количества кода или меньше строк не всегда является целью. Вспоминая некоторые истории о Стиве Возняке, он использовал для изготовления очень компактное оборудование, складывая тонны логики в очень маленький пакет, но очень немногие люди могли следить за тем, что он делал, обслуживать или изготавливать.

При этом я предлагаю вам очень хорошо ознакомиться с шаблонами проектирования. Они могут не уменьшить ваши строки кода, но они могут сделать ваш код легче писать, поддерживать и понимать. И много раз они уменьшают количество линий, которые у вас есть. Вот некоторые ресурсы:

Справочник шаблонов проектирования DoFactory

Статья шаблона дизайна Википедии

0 голосов
/ 24 марта 2010

Поскольку вы не можете опубликовать какой-либо код, я мог бы выбросить случайную мысль. Можете ли вы положить эти кусочки в массив? Если это так, вы можете избавиться от некоторого избыточного кода, если каждый из элементов управления установит переменную (я назову это whichSlice). Таким образом, все элементы управления устанавливают whichSlice на правильный номер 1-4, а затем вы запускаете обычный переключатель и звоните slices[whichSlice].my.commands();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...