Если у Вас есть установленный SSH, необходимо быть в состоянии работать..
ssh-keygen
Тогда проходят шаги, у Вас будет два файла, id_rsa
и id_rsa.pub
(первым является Ваш закрытый ключ, вторым является Ваш открытый ключ - тот, который Вы копируете в удаленные машины)
Затем соединитесь с удаленной машиной, к которой Вы хотите войти в систему, в файл ~/.ssh/authorized_keys
добавляют содержание Ваш того id_rsa.pub
файл.
, О, и chmod 600
весь эти id_rsa*
файлы (и локально и удаленный), таким образом, никакие другие пользователи не могут считать их:
chmod 600 ~/.ssh/id_rsa*
Точно так же гарантируют удаленное ~/.ssh/authorized_keys
, файл chmod 600
также:
chmod 600 ~/.ssh/authorized_keys
Затем когда Вы делаете ssh remote.machine
, это должно попросить у Вас пароля ключа, не удаленной машины.
Для создания более хорошим использовать можно использовать ssh-agent
для содержания дешифрованных ключей в памяти - это означает, что Вы не должны вводить пароль своей пары ключей каждый раз. Для запуска агента Вы работаете (включая кавычки обратной галочки, который оценка вывод эти ssh-agent
команда)
`ssh-agent`
На некоторых дистрибутивах, ssh-агент запускается автоматически. Если Вы работаете echo $SSH_AUTH_SOCK
, и это показывает путь (вероятно, в/tmp/), это уже - установка, таким образом, можно пропустить предыдущую команду.
Затем для добавления ключа Вы делаете
ssh-add ~/.ssh/id_rsa
и вводите свой пароль. Это хранится, пока Вы не удаляете его (использование эти ssh-add -D
команда, которая удаляет все ключи из агента)
Но мне всегда говорили, что проверка типов - это признак того, что код действительно следует реорганизовать.
Это признак того, что либо иерархия классов, либо код, который ее использует может потребоваться рефакторинг или реструктуризация. Но часто не будет рефакторинга / реструктуризации, чтобы избежать проблемы.
В этом случае, когда у вас есть методы, которые применяются только к определенным подтипам, наиболее многообещающим рефакторингом было бы создание отдельных списков для животных, которые являются несушками и животные, которые потеют.
Но если вы не можете этого сделать, вам нужно будет проверить типы. Даже isEggLayer ()
/ isMammal ()
включает проверку типа; например,
if (x.isEggLayer()) {
((IEggLayer) x).layEgg(); // type cast is required.
}
Я полагаю, что вы можете скрыть проверку типа с помощью метода asEggLayer ()
; например
public IEggLayer asEggLayer() {
return ((IEggLayer) this);
}
или
// Not recommended ...
public IEggLayer asEggLayer() {
return (this instanceof IEggLayer) ? ((IEggLayer) this) : null;
}
Но всегда происходит проверка типа и вероятность того, что она потерпит неудачу. Более того, все эти попытки скрыть проверку типов влекут за собой добавление «знаний» о подтипах к интерфейсу супертипа, что означает, что его необходимо изменять по мере добавления новых подтипов.
Я думаю, как задуматься над этим вопросом is: Что делает цикл? У цикла есть цель, и он пытается что-то сделать с этими объектами. Это что-то может иметь метод в интерфейсе IAnimal, и реализации могут потеть или откладывать яйца по мере необходимости.
Что касается вашей проблемы с возвращаемым значением, вы вернетесь null, вы ничего не сможете с этим поделать, если поделитесь методы. Не стоит выполнять приведение внутри цикла, чтобы избежать лишнего return null; чтобы удовлетворить компилятор. Однако вы можете сделать его более явным, используя универсальные типы:
public interface IAnimal<R> {
public R generalMethod();
}
public interface IEggLayer extends IAnimal<Egg> {
public Egg generalMethod(); //not necessary, but the point is it works.
}
public interface IMammal extends IAnimal<Void> {
public Void generalMethod();
}
Из вашего комментария, в котором вы заботитесь о типе возвращаемого значения, вы можете получить тип возвращаемого значения и отправить его фабричному методу, который проверяет тип и возвращает что-то общее, которое подвергается подгруппе к конкретному типу и действовать в соответствии с этим.
Есть много способов сделать это. Наиболее подходящая точность зависит от вашего контекста. Я собираюсь предложить ввести дополнительный уровень косвенности. Это решает большинство проблем. Я предпочитаю конструкции, которые избегают множественного наследования интерфейса (если бы я был президентом языка, я бы запретил это).
Я не думаю, что layEggsOrSweatOrDoBothIfYoureWeirdOrNoneIfYouCant ()
- отличный метод для загрязнения Животное
с. Поэтому вместо добавления каждого Animal
непосредственно к животным
, оберните каждого в отдельную оболочку. Я говорю «обертка» как общее имя - случайная операция, которую мы пытаемся выполнить, не имеет никакого смысла.
private final List<AnimalWrapper> animals =
new ArrayList<AnimalWrapper>();
public void doStuff() {
for (AnimalWrapper animal : animals) {
animal.doStuff();
}
}
Затем нам нужен какой-то способ добавления оболочек. Что-то типа:
public void addPlatypus(final Platypus platypus) {
animals.add(new AnimalWrapper() { public void doYourStuff() {
platypus.sweat();
platypus.layEgg();
}});
}
Если вы попытаетесь написать эти оболочки без достаточного контекста, у вас возникнут проблемы. Для этого необходимо, чтобы на месте вызова был выбран правильный. Это можно было сделать путем перегрузки, но это чревато опасностями.
/*** Poor context -> trouble ***/
public void addNormalMamal(final Mamal mamal) {
animals.add(new AnimalWrapper() { public void doYourStuff() {
mamal.sweat();
}});
}
public void addNormalEggLayer(final EggLayer eggLayer) {
animals.add(new AnimalWrapper() { public void doYourStuff() {
eggLayer.layEgg();
}});
}
public <T extends Mamal & EggLayer> void addMamalEggLayer(final T animal) {
animals.add(new AnimalWrapper() { public void doYourStuff() {
animal.sweat();
animal.layEgg();
}});
}
Ясно, что вашему интерфейсу IAnimal
(или его расширению) нужен метод callAllMethods
, который каждый разработчик интерфейса может закодировать для полиморфного выполнения этой задачи - - кажется, единственный подход, звучащий в оригинальном стиле!
в C #, вы должны иметь возможность сделать это прозрачно.
foreach(IEggLayer egglayer in animals) {
egglayer.layEgg();
}
foreach(IMammal mammal in animals) {
mammal.sweat();
}
Почему бы и нет есть методы, добавленные в isAnimal:
public interface IAnimal {
bool isEggLayer();
bool isMammal();
}
Затем вы можете пройти цикл и каждый раз запрашивать это логическое значение.
Обновление:
Если это было рисование животного, то иметь полностью закрытый класс вполне разумно, вы просто вызываете drawVehicle
, и он рисует корвет, цессну, мотоцикл, что угодно.
Но, похоже, это не-ООП-архитектура, поэтому, если архитектура приложения не может измениться, так как мой исходный ответ получен не очень хорошо, то кажется, что АОП будет лучшим выбором.
Если вы поместите аннотацию к каждому классу, у вас может быть
@IsEggLayer
@IsMammal
public class Platypus() implements EggLayer, Mammal {
...
}
Это тогда позволит вам создавать аспекты, которые вытягивают всех яйцекладчиков и выполняют все необходимые операции.
Вы также можете вводить в animal взаимодействует с любыми дополнительными классами, чтобы заставить эту идею работать.
Мне нужно будет подумать о том, что делать дальше, но я чувствую, что это может быть лучшим решением, если переделать невозможно.