Шаблон разработки для использования вместо множественного наследования

Редактировать: Причина, по которой глобальные переменные не поощряются в js, заключается в том, что весь код имеет одно глобальное пространство имен, где javascript автоматически подразумевает глобальные переменные (например, переменные, которые явно не объявлены в локальной области видимости, являются автоматически добавляется в глобальное пространство имен). Полагая слишком много на глобальные переменные , можно привести к некоторым конфликтам между скриптами на одной странице. Это не значит, что вы не должны использовать глобальные переменные, но вы не должны использовать их легкомысленно. Если вам нужно, чтобы переменная была доступна после завершения функции, ваш выбор ограничен, поэтому либо используйте глобальную переменную, либо передайте переменную той функции, в которой вы нуждаетесь.

Вам просто нужно сохранить результат doStuff и затем получить доступ к этой переменной в addArray:

var result
function doStuff() {

  //document.write("We are testing document writing now!");

  let numArray;
  let sumArray;
  let start = parseInt(prompt("Enter a small number"));
  let end = parseInt(prompt("Enter a larger number"));

  if (start > end) {
    alert("Error: first int greater than last!")
  } else {
    let arraySize = end - start;
    numArray = [start];
    for (let x = start + 1; x <= end; ++x) {
      numArray.push(x);
    }
    result = numArray; // save result for later (has to be a global scope)
  }
}

function addArray() { // you defined this without an input in your form, so stick to that
  if (result) // check if value exists
    console.log(result);
  else
    console.log("Please enter the numbers boundaries first first.");
}
<form>
  <input type="button" value="Click Me to generate an array of numbers!" onclick="doStuff()" />
  <input type="button" value="Click me to add the array numbers" onclick="addArray()" />
</form>

23
задан Dinah 2 April 2010 в 18:45
поделиться

8 ответов

Вы можете использовать шаблон стратегии или что-то подобное для использования используется (композиция) вместо , это (наследование):

public class TypeA : CustomButtonUserControl, IMagician {
    IMagician magicObj = new Magical();
    public void DoMagic() {
        magicObj.DoMagic();
    }
}

public class TypeB : CustomButtonUserControl, IMagician {
    IMagician magicObj = new Magical();
    public void DoMagic() {
        magicObj.DoMagic();
    }
}

public class Magical : IMagician {
    public void DoMagic() {
        // shared magic
    }
}

Есть и другие способы создания экземпляров ваших частных членов IMagician (например, передача их в качестве параметра через конструктор), но приведенное выше должно помочь вам начать работу.

10
ответ дан 29 November 2019 в 02:51
поделиться
  • В .Net вы можете применять методы расширения к интерфейсам. Это действительно аккуратно, когда это возможно, и применимо для вас, потому что это редкий способ применить общую реализацию к интерфейсу. Конечно, подумайте об этом, но это может не сработать для вас, поскольку вы говорите, что DoMagic работает со многими частными пользователями. Можете ли вы упаковать эти закрытые переменные internal? Таким образом, метод расширения может получить к ним доступ.
  • Имеют общую функциональность в другом классе. Если есть логичное место для размещения этой общей функциональности, передайте свои объекты этому другому методу класса (возможно, это функциональность пользовательского интерфейса, и у вас уже есть помощник пользовательского интерфейса ...). Опять же, можете ли вы предоставить личные данные внутренней / публичной собственности? (Безопасность / инкапсуляция является проблемой во всем этом, конечно. Я не знаю, предназначены ли ваши классы только для внутреннего использования или будут доступны публично.)
  • В противном случае передайте отдельный класс функциональности (или определенную функцию указатель) в интерфейсный метод. Вам понадобится немного дублированного кода для передачи ваших личных переменных в эту ссылку на внешнюю функцию, но, по крайней мере, это будет немного, и ваша реализация будет в одном месте.
  • Мы могли бы сделать это слишком сложным. Это не заставит вас чувствовать себя полностью объектно-ориентированным, когда вы ложитесь спать сегодня вечером, но не могли бы вы иметь статическую подпрограмму в своей библиотеке, где бы ее ни вызывали все разработчики IMagician?
  • В конце концов, Adapter действительно может быть тем, что ты ищешь. Менее вероятным, но все же заслуживающим рассмотрения является шаблон Decorator .

Если ничто не кажется особенно хорошим, выберите то, что вам больше всего нравится, используйте его пару раз и переставьте завтра. :) [1 110]

9
ответ дан 29 November 2019 в 02:51
поделиться

В этом случае ваша кишка верна. Шаблон Adapter - это то, что вы ищете.

У DoFactory есть хорошие примеры .NET (которые также должны быть очень близки к их Java-аналогам):

Шаблон проектирования адаптера в C # и VB.NET

3
ответ дан 29 November 2019 в 02:51
поделиться
public interface  IMagician{ /* declare here all the getter/setter methods that you need; they will be implemented both in TypeA and TypeB, right? */ }

public static class MyExtensions {
  public static void doMagic(this IMagician obj)
  { 
           // do your magic here
  }
}   

Теперь, проблема в том, что если вам ДЕЙСТВИТЕЛЬНО нужно использовать частные свойства / методы (в отличие от «внутренних»), этот подход не будет работать. Ну, на самом деле, вы можете творить чудеса, если сможете прочитать эти свойства с помощью отражения, но даже если это работает, это довольно уродливое решение:)

[Обратите внимание, что «doMagic» автоматически появится станьте частью TypeA и TypeB просто потому, что вы внедрили IMagician - нет необходимости иметь там какую-либо реализацию]

1
ответ дан 29 November 2019 в 02:51
поделиться

Заменить наследование композицией.

Переместите общую функцию в отдельный класс, создайте экземпляр этого класса и вставьте его в объект TypeA и в объект TypeB.

3
ответ дан 29 November 2019 в 02:51
поделиться

Составной шаблон предназначен для сложных объектов, это означает, что основное внимание уделяется одному объекту, состоящему из других объектов. Шаблон стратегии можно рассматривать как частный случай этого, но стратегия не обязательно должна быть объектом. Я думаю, это больше относится к вашему случаю. Опять же, это сильно зависит от характера того, что делает DoMagic () .

1
ответ дан 29 November 2019 в 02:51
поделиться
abstract class Magical: CustomButtonUserControl
{
    public void DoMagic()
    {
        // ...
    }
}

public class TypeA : Magical
{

}

public class TypeB : Magical
{

}
-3
ответ дан 29 November 2019 в 02:51
поделиться

Вы можете использовать композицию, чтобы иметь мага как свойство типа A и типа B

class Magician : IMagician
{
    public void DoMagic()
    {}
}

Class TypeA : CustomButtonUserControl
{
   //property
   Magician magicianInTypeA
}

Class TypeB : CustomTextUserControl
{
    //property
    Magician magicianInTypeB
}
0
ответ дан 29 November 2019 в 02:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: