#java #android #design-patterns
#java #Android #шаблоны проектирования
Вопрос:
У меня есть действительно потрясающий класс с двумя методами, которые запускают или останавливают некоторые службы, когда эти службы доступны. Что-то вроде следующего (они не являются if-elses, просто if):
void startServices() {
if (service1 == true) {
start1();
}
if (service2 == true) {
start2();
} if (serviceN == true) {
startN();
}
}
void stopServices() {
if (service1 == true) {
stop1();
}
if (service2 == true) {
stop2();
}
if (serviceN == true) {
stopN();
}
}
Вы порекомендуете мне какой-нибудь шаблон дизайна, чтобы сделать его красивее?
Спасибо!
Комментарии:
1. Я не буду отвечать на это, потому что существующие ответы хороши, но я просто хотел бы отметить, что
== true
это несколько избыточно в любомif()
.
Ответ №1:
Зависит; моя первая реакция — сохранить сервисы в хэше или массиве. Каждая служба реализует интерфейс с методами запуска и остановки. Для запуска или остановки службы требуется только служебный ключ или индекс.
Возможно, он все еще немного хрупкий, но, не зная больше, я не уверен, как «доменировать» ut, чтобы это больше походило на то, что вы делаете.
Ответ №2:
Вы можете использовать шаблон стратегии.
Идея в том, что вы должны знать, какую стратегию вы собираетесь использовать при создании экземпляра вашего класса (или вы можете изменить его динамически latrr). Таким образом, вы можете передать эту стратегию при создании экземпляра (и при необходимости заменить ее позже).
public interface IStartupStrategy
{
void Start();
}
public interface IStopStrategy
{
void Stop();
}
public class MyClass
{
private readonly IEnumerable<IStartupStrategy> startupStrategies;
private readonly IEnumerable<IStopStrategy> stopStrategies;
public MyClass(IEnumerable<IStartupStrategy> startup, IEnumerable<IStopStrategy> stop)
{
this.startupStrategies = startup;
this.stopStrategies = stop;
}
public void Start()
{
foreach(var strategy in this.startupStrategies)
{
strategy.Start();
}
}
public void Stop()
{
foreach(var strategy in this.stopStrategies)
{
strategy.Stop();
}
}
}
Комментарии:
1. У меня создается впечатление, что шаблон стратегии был слепо применен к этой проблеме. Я не думаю, что именование имеет слишком большой смысл; существует несколько стратегий запуска? По одному для каждой службы?
2. Действительно. Я пытался дать четкое представление о шаблоне, но при этом я разбил то, что должно было быть «IService», на несколько стратегий запуска и остановки. В идеале вы должны использовать интерфейс «IService», который будет иметь методы запуска и остановки. Затем эта служба может решить, хочет ли она реализовать запуск или остановку. Службы будут передаваться на основе того, какие службы доступны, и вызывающий класс будет решать, когда эти службы следует запускать или останавливать. Это все еще шаблон стратегии, но стратегия будет иметь более одного метода.
3. Я просто перечитал то, что написал в предыдущем комментарии. Если шаблон стратегии по существу передает некоторый алгоритм для выполнения, который вызывающий класс не предоставляет… можно ли считать инверсию управления в целом шаблоном стратегии? Просто мысль.
4. Я думаю, что взаимосвязь между ними такова: инверсия управления реализуется с помощью шаблона стратегии. Это может быть реализовано многими различными способами, но стратегия кажется простым способом сделать это. Один из них — это то, что вы хотите сделать (инвертировать управление), а другой — как вы это делаете (используя шаблон стратегии).
5. @Guven, 1 за прагматичный ответ.
Ответ №3:
Используйте объекты, в которых у вас есть список служб, которые вы можете перебирать, отключая их с помощью унаследованного метода stop() .
public interface Service {
void start();
void stop();
}
public class TestService implements Service {
@Override
void start() {
}
@Override
void stop() {
}
}
Каждая служба также может сохранять свое состояние, чтобы отключать их только в том случае, если они включены.
Ответ №4:
Инструкции Switch менее запутанны. При использовании вместе с перечислениями код становится очень читаемым.