Czy dobrym pomysłem jest zaprojektowanie architektury z myślą, że klasy interfejsu użytkownika można zastąpić interfejsem wiersza poleceń?

92

W Code Complete strona 25 napisano, że dobrym pomysłem jest możliwość łatwego zastąpienia zwykłych klas interfejsu użytkownika klasą z linii poleceń.

Znając jego zalety w testowaniu, co z problemami, jakie może to przynieść?

Czy ta dodatkowa praca naprawdę się opłaci w przypadku projektów internetowych i mobilnych? Co z małymi i średnimi projektami; czy obowiązują te same zasady? Co się stanie, jeśli twój projekt będzie bardziej złożony?

Julio Rodrigues
źródło
2
W Perlu właśnie do tego służą narzędzia takie jak MooseX :: Getopt i Plack :: Handler :: CLI .
Ether
4
Jeśli najpierw zbudujesz program z interfejsem CLI, interfejs użytkownika można nałożyć na niego warstwami, co daje znacznie większą elastyczność niż interfejs użytkownika głęboko osadzony w programie. To samo dotyczy usług sieciowych.
zzzzBov
28
Zawsze jest mocnym słowem.
Mark Canlas
8
Zwróć uwagę na oryginalny cytat, który brzmi: „Architektura powinna zostać zmodularyzowana, aby nowy interfejs użytkownika mógł zostać zastąpiony bez wpływu na reguły biznesowe i części wyjściowe programu. Na przykład architektura powinna dość łatwo odciąć grupa interaktywnych klas interfejsów i podłącz grupę klas wiersza poleceń. " Więc CC nie mówi, że powinieneś przygotować się do zastąpienia GUI wierszem poleceń, po prostu mówi, że architektura powinna przystosować się do zmiany interfejsu użytkownika. Linia poleceń GUI-> to tylko przykład.
sleske
2
@ Vandell Mam drugą edycję kodu Complete, która nie jest wymieniona na stronie 25. Do której edycji się odwołujesz?
JW01

Odpowiedzi:

43

Możliwość ponownego wykorzystania funkcji w różnych interfejsach (np. GUI vs CLI vs REST) ​​nie zawsze jest konieczna, ale miło jest mieć i umożliwić nieoczekiwane ponowne użycie systemu, ponieważ inni ludzie znajdują nowe sposoby interakcji z nim.

Ma to kilka wad, które należy wyważyć:

  1. Będzie to wymagało dodatkowych warstw abstrakcji (czasem nawet poziomów). Chociaż posiadanie tych warstw jest dobrą praktyką inżynieryjną, ich rozwój wiąże się z dodatkowymi kosztami, ponieważ ich zrozumienie może nie prowadzić do zmniejszenia wysiłku w innych obszarach (np. Konserwacja, ponowne użycie, testowanie), dlatego warto się nad tym zastanowić.
  2. Przepływ optymalny dla medium może być okropny dla innych. Jeśli funkcjonalność została zaprojektowana do obsługi GUI, może być zbyt rozmowna dla Internetu . Nie każda funkcjonalność jest opłacalna na każdym medium.
  3. Pułapka polega na próbie zdefiniowania ogólnego konwertera między usługami a interfejsem użytkownika, aby można było zdefiniować umowę serwisową i uzyskać automatycznie (lub w jak największym stopniu) interfejs użytkownika dla wszystkich mediów. Wiele projektów zmarnowało zbyt wiele wysiłku, próbując zbudować takie frameworki i dodając do niego wszelkie możliwe dostosowania wraz ze zmianami wymagań.

Mimo to z mojego doświadczenia wynika, że ​​wdrażanie takich warstw zawsze kończyło się wysiłkiem. W kilku przypadkach udało mi się wdrożyć systemy na czas, ponieważ ostatecznie musieliśmy zamienić media (np. Z integracji usług internetowych na interfejs użytkownika) na kilka tygodni przed terminem.

Daniel Yokomizo
źródło
2
Jak zauważyły ​​inne komentarze, powinno to zwiększyć spójność kodu i zmniejszyć sprzężenie. Oba powinny uprościć kod i ułatwić testowanie. Flow jest bardziej koncepcją GUI i zwykle nie powinien być obecny w innych funkcjach.
BillThor,
Nie mogę uwierzyć, że o tym jeszcze nie wspomniano, ale to jest istota architektury Model-View-Controller. Chodzi o to, aby móc dowolnie wymieniać widoki i kontrolery, aby zmniejszyć sprzężenie, jak mówi @BillThor. Jest to najlepszy przypadek użycia dla MVC.
Rudolf Olah,
110

Zupełnie poza testowaniem, oczywistą zaletą tego podejścia jest to, że uczyni twój projekt automatycznym i skryptowalnym . Jeśli jestem w stanie wysyłać polecenia wiersza polecenia do programu, mogę napisać skrypt do wykonywania skomplikowanych zadań znacznie łatwiej (i bardziej niezawodnie!) Niż mogę utworzyć makro automatyzujące to samo w interfejsie GUI.

To, czy warto to robić, zależy oczywiście całkowicie od tego, czy masz wielu użytkowników, którzy chcieliby zautomatyzować Twój program.

Mason Wheeler
źródło
12
Wiele aplikacji używa do tworzenia skryptów modelu wtyczki. Zwykle model obiektowy jest ujawniony, a do pisania skryptów używany jest język taki jak python. Nie sądzę, aby parametry wiersza polecenia działały w przypadku nietrywialnej aplikacji.
softveda,
Kolejną korzyścią może być wykrywalność. Ctrl-Shift-P funkcji Sublime Text jest tego fantastycznym przykładem. Jeśli potrzebuję jakiejś niejasnej funkcjonalności, zamiast przeszukiwać menu, po prostu wpisuję, jak sądzę, to, jak by się ona nazywała, i widzę polecenie (i skrót) i jestem w stanie wykonać je natychmiast.
Adam Iley,
OpenDJ, oparty na Javie serwer LDAP typu open source, jest tego doskonałym przykładem: wiersz poleceń dla każdej modyfikacji dokonanej w GUI jest dostępny w oknie dialogowym potwierdzenia.
Franck
1
@ Marnixv.R .: gesty są jedynie wygodnym sposobem wykonywania pewnych czynności, które można określić za pomocą polecenia, np. „Powiększ 35,73 N 118,23 W”. Rysunek może być wprowadzany jako polecenia, chociaż byłoby to niewygodne. Nadal uważam, że istnieje wygodne narzędzie w wygodnym dla skryptów interfejsie i bardzo niewiele pracy potrzeba do jego stworzenia.
kevin cline
7
+1: Kolejną kluczową zaletą jest to, że ułatwia rejestrowanie działań użytkownika, upraszczając odtwarzanie problemów produkcyjnych.
kevin cline
81

To nie jest dodatkowa praca, tylko inna praca. Jeśli zrobisz to dobrze, nie tylko nie będzie to uczynić go bardziej skomplikowane, to zrobi to prostsze , ponieważ będzie zmuszać do oddzielenia swój projekt. Bez względu na to, czy faktycznie zaimplementujesz interfejs CLI, lepiej będzie, jeśli Twój projekt będzie w stanie to zrobić.

Karl Bielefeldt
źródło
4
-1 dla kilku całkowicie niepoprawnych instrukcji. Oczywiście sprawi, że będzie to bardziej skomplikowane. Jest to przecież dodatkowy wymóg / funkcja.
Boris Yankov
@BorisYankov Myślę, że miał na myśli „skomplikowane” zamiast „skomplikowane” - brzmią podobnie i mają na siebie znaczenie, więc czasami łatwo je pomylić
Izkata
43

Jedną z kluczowych zalet, o której najwyraźniej nie wspomniano, jest fakt, że możliwość wykonania tej czynności wymusza ścisłe oddzielenie interfejsu użytkownika od kodu źródłowego. Jedną z kluczowych zalet tego jest to, że oznacza to, że jeśli musisz znacząco zmienić GUI (powiedzmy standardy iOS na standardy OSX lub jeden silnik graficzny na inny), to wszystko, co musisz zmienić, ponieważ podstawowy kod nie zależy od układ interfejsu użytkownika. Nie może tak być, ponieważ gdyby tak było, narzędzia wiersza poleceń nie działałyby.

Poza tym kluczową zaletą jest możliwość zautomatyzowania testów.

deworde
źródło
Popraw mnie, jeśli się mylę, ale zmiana jednego interfejsu graficznego na inny nadal wymagałaby znacznej pracy w zakresie sprawdzania poprawności formularza / pokazywania komunikatów o błędach, ustawiania procedur obsługi zdarzeń itp.
Kliknij Upvote
5
Tak, ale cała ta weryfikacja jest częścią dobrego interfejsu użytkownika, który powiedziałem, że musisz zmienić. Kod zaplecza przechowujący (na przykład) bieżący stan konta użytkownika, algorytm wyszukiwania przedmiotów, szczegółowe zasady gry itp. Kluczową kwestią jest to, że jeśli muszę zmienić interfejs użytkownika myszy / klawiatury na ekran dotykowy UI do gry, nadal powinienem móc korzystać z tego samego silnika zaplecza do obsługi obliczeń bojowych i oceniania, więc mogę skupić się na pisaniu nowych procedur obsługi zdarzeń korzystających z tego samego systemu.
deworde
2
to wcale nie jest łatwe, ale nienawidzę pisania programów obsługi zdarzeń i tworzenia kodu weryfikacyjnego bardziej niż kodu biznesowego. (choć zgadzam się z tobą, że należy je odłączyć w sposób opisany przez ciebie)
Kliknij Upvote
2
@ClickUpvote W pewnym stopniu zależy to od sposobu wdrożenia GUI. Naprawdę cienki interfejs GUI, który po prostu wysyła komunikaty ValueChanged do klasy wsparcia i odbiera w odpowiedzi komunikaty ValueValid / ValueInvalid, będzie znacznie łatwiej zamienić ten, który wykonuje całą weryfikację zdarzeń OnTextboxChanged.
Dan Neely,
@ClickUpvote Całkowicie się zgadzam, dlatego chcę być w stanie skupić się na tym, co lubię nieskorumpowane, lub dać temu, czego nienawidzę, całą moją uwagę, aby móc to zrobić jak najszybciej.
deworde
17

Tak, to prawie zawsze dobry pomysł.

Jeśli zastosujesz to podejście, prawdopodobnie nie będziesz mieć logiki biznesowej ani dostępu do danych w tym samym wątku co GUI i za jakimś programem obsługi GUI. Już tylko z tego powodu warto inwestować.

Koder
źródło
2
Jaka byłaby z tego korzyść, jeśli piszesz np. Edytor tekstu?
nikie
5
@nikie Ponieważ, na przykład, możesz zastąpić widok edytora tekstu WYSIWIG zwykłym interfejsem opartym na tekście lub znacznikach i dopóki przekaże te same informacje do modelu bazowego, twoja infrastruktura będzie nadal działać.
deworde
5

Myślę, że to dobry pomysł. Ponadto możliwość napisania drugiego interfejsu wiersza poleceń ostatecznie dowodzi, że logika biznesowa jest całkowicie oddzielona od konkretnej architektury serwera aplikacji.

Tulains Córdova
źródło
5

Jedynym niebezpieczeństwem, jakie widzę podczas tego, jest to, że aby dostać się do pewnej części interfejsu użytkownika, użytkownik zwykle musi przejść inne części interfejsu użytkownika.

Gdzie jako programista może po prostu bezpośrednio uruchomić interfejs użytkownika. Widziałem sytuacje, w których programista nie mógł odtworzyć problemu użytkowników, dopóki nie używał produktu.

Uwzględnij to również podczas tworzenia testów.

Simon O'Doherty
źródło
3

Nie. Straszna porada.

To trochę yagni (nie będziesz go potrzebować).

Ujawnienie interfejsu wiersza poleceń nie jest tym samym, co struktura aplikacji w sposób, który obsługuje testy jednostkowe lub jest zgodny z dowolną częścią SOLID lub jakąkolwiek praktyką programistyczną, którą poleciłbym.

Nie działa dla żadnego interfejsu użytkownika, który po prostu nie pasowałby do interfejsu wiersza poleceń. MS Paint jest naprawdę prostą aplikacją, ale w jaki sposób, w każdej sytuacji, widzisz korzyść z możliwości kontrolowania jej z wiersza poleceń?

Nie pomogłoby to w implementacji skryptów. W rzeczywistości utrudniłby to postęp w tym kierunku.

Jedyną pozytywną rzeczą jest to, że pojawiła się na stronie 25, więc przynajmniej dostaniesz ostrzeżenie, że reszta książki może być ... śmierdząca. Przeczytałem to dawno temu i nie podobało mi się to, więc jestem stronniczy.

Ian
źródło
1
Uzgodniony +100000000
4
Skryptowalne MSPaint wydaje się naprawdę przydatne.
RoundTower
IMO najlepsza odpowiedź. Odkąd podążam za mantrą „nie wdrażaj YAGNI”, mam znacznie więcej czasu, koncentrując się na prawdziwej pracy i mam jeszcze dość czasu, aby dużo eksperymentować. Próba bycia sprytnym z góry pokazała mi, że przez większość czasu klient chciał innego rozszerzenia niż wcześniej wspomniane, więc nie marnowałem czasu na coś niepotrzebnego.
topskip
PSPaint + interfejs wiersza poleceń = AutoCAD
Vorac
-1 (gdybym mógł) Zauważ, że nie mówi „zaimplementuj CLI, a także GUI”; napisano „zaspokoić potrzeby implementacji alternatywnego interfejsu użytkownika, takiego jak CLI”.
Mark Hurd
2

Opierając się na tym, co powiedział Mason Wheeler, możliwość interakcji z aplikacją za pomocą wiersza polecenia sprawia, że ​​bardzo łatwo jest zautomatyzować zadania.

Jest to szczególnie przydatne w testowaniu.

Aby podać praktyczny przykład, jeśli chcę uruchomić automatyczne testy aplikacji, może być konieczne zainstalowanie aplikacji automatycznie. Aby to zrobić, mogę przekazać następujące parametry: „myApplication.exe / silentinstall”.

Mógłbym tak zaprogramować, aby po określeniu tego przełącznika wiersza polecenia instalacja była przeprowadzana w tle w trybie cichym, bez instalatora GUI. Wszelkie dane wejściowe do instalatora (takie jak katalog instalacyjny) można pobrać z pliku XML.

Weź inny przykład. Interfejs Microsoft Test Manager GUI (dostarczany z Visual Studio) pozwala użytkownikom uruchamiać testy z interfejsu GUI, ale zapewnia również interfejs wiersza poleceń, aby zrobić to samo (przy użyciu kombinacji przełączników i danych wejściowych). Oznacza to, że mogę połączyć ze sobą skrypt PowerShell lub DOS, aby zautomatyzować uruchamianie testów, a następnie mogę utworzyć zaplanowane zadanie, aby skrypty mogły być uruchamiane co noc.

Niektóre aplikacje mają przełączniki wiersza polecenia, które określają, że aplikacja ma być otwierana z pewnymi opcjami (na przykład mogę użyć „/ maximize”, aby otworzyć aplikację w zmaksymalizowanym oknie).

Istnieje wiele scenariuszy, w których można użyć interfejsu wiersza polecenia. To tylko niektóre przykłady.

CiaranG
źródło
1

Zwróć uwagę na zwrot: „[To dobry pomysł], aby móc łatwo zastąpić zwykłe klasy interfejsu użytkownika jedną z linii poleceń”. Nie oznacza to, że musisz napisać CLI, tylko że możesz to zrobić z łatwością.

Mówi więc, że interfejs użytkownika powinien być oddzielony od reszty kodu.

José Dinuncio
źródło
2
Myślę, że chciałeś skomentować, prawda?
Julio Rodrigues,
1

To zależy, a kiedy mówię, że to zależy, nie chodzi tylko o to, by mieć kilka przypadkowych przypadków, ale jest to bardzo zależne od aplikacji i grupy docelowej. Zakładając, że eliminujemy gry z równania, nadal istnieje szeroki wachlarz aplikacji, które możesz pisać w miejscach, w których takie polecenie jest mało prawdopodobne lub nigdy nie zostanie wdrożone. Z góry mojej głowy każda aplikacja kierowana na środowisko mobilne (np. IOS, Android itp.) Prawdopodobnie będzie objęta tym nagłówkiem.

Mając to na uwadze, w ogólnej przestrzeni oprogramowania żadna aplikacja silnie uzależniona od wizualizacji (np. PowerPoint, Maya itp.) Prawdopodobnie nigdy nie wdroży zastępowania wiersza poleceń. W rzeczywistości w przypadku oprogramowania graficznego, takiego jak Maya, dobrym ćwiczeniem umysłowym jest ustalenie, w jaki sposób działałaby pełna i właściwa wersja wiersza poleceń i może nie być to możliwe z punktu widzenia użytkownika. Jest zatem jasne, że istnieją definitywnie powszechne aplikacje, które można napotkać, gdy interfejs podobny do komendy prawdopodobnie nigdy nie będzie widoczny lub pożądany, nawet jeśli skrypt aplikacji może być pożądany.

Następnie, jeśli spojrzymy na sugestię z punktu widzenia ogólnej architektury oprogramowania, widzę, gdzie warto okresowo zadawać sobie pytanie: „Jak mogę uzyskać dostęp do tej funkcji bez interfejsu użytkownika?” Ogólnie rzecz biorąc, jeśli nie ma sposobu, aby to zrobić i nie jest to bezpośrednia interakcja z użytkownikiem (np. Wprowadzanie gestów), prawdopodobnie istnieje sytuacja, w której ogólna architektura wymaga poprawy. Aby umożliwić łatwość testowania, będziesz chciał mieć bezpośredni dostęp do polecenia bez przechodzenia przez interfejs użytkownika, nawet jeśli nie można ich wywoływać za pomocą wiersza polecenia. Ogólnie oznacza to, że musi istnieć solidny interfejs API i teoretycznie dobry interfejs API powinien umożliwiać dostęp za pośrednictwem wiersza polecenia lub interfejsu użytkownika. Ponadto w dłuższej perspektywie

Pod koniec dnia myślę, że to, co sugeruje ta sugestia, ma sens (tj. Mieć dobry interfejs API i zbudować z tego interfejs użytkownika), ale wybór słów może być nieco lepszy, aby uzyskać sens .

rjzii
źródło
1
Ogólnie nie zgadzam się, ale jedną z największych zalet Mayi jest fakt, że ma ona bardzo silny interfejs API do obsługi skryptów (pierwotnie MELScript, teraz Python).
jwd
@jwd - Maya jest przykładem, który wybrałem, ponieważ użyłem go kilka lat temu, jeśli masz lepszy w tej samej myśli, daj mi znać. Może Bryce, choć nie jest tak dobrze znany?
rjzii
0

To zależy.

Często dzielimy nasze programy na modele / model / widok / kontrolery lub model / widok / widok / model. Wygląda na to, że model powinien umożliwiać dostęp do wiersza poleceń, ale nie jestem tak pewien co do kontrolera. Oczywiście widok jest zastępowany.

Może istnieć pewna różnica w zależności od łańcucha narzędzi. Code Complete to książka Microsoft Press, więc może używasz technologii Microsoft do tego GUI? Jeśli tak, myślę, że może pojawić się pole wyboru podczas tworzenia aplikacji do wyświetlania interfejsów przez COM lub DCOM. W przypadku niektórych technologii Microsoft uważam, że tabele zasobów i przekazywanie wiadomości są dość intensywnie połączone ze wszystkim, co pomaga Czarodziejom w szybkim prototypowaniu. Myślę, że jest coraz lepiej, ale jeśli utrzymujesz MFC lub formularze, może to trochę boleć.

W niektórych przypadkach program oparty na graficznym interfejsie użytkownika może być otoczony interfejsem zarządzania lub może mieć tak małą logikę, że interfejs wiersza poleceń nie ma wiele do kontrolowania. Zbudowanie oddzielnej aplikacji na konsolę może być szybsze i nadal umożliwiać pisanie skryptów, testowanie lub używanie ważnych danych.

Chyba kluczową kwestią jest to, że sugestia nie jest regułą. Jeśli będziesz go przestrzegać, powinieneś uzyskać łatwiejsze testy jednostkowe i akceptacyjne lub interfejs awaryjny, gdy ty lub klient wolicie pisać zamiast klikać. Jeśli to się opłaca, zrób to. Powodzenia.

DeveloperDon
źródło
4
-1: Code Complete to niezależna od języka książka o programowaniu jednostek.
deworde
1
Nigdy nie powiedział inaczej.
Kliknij Upvote
A jego pytanie dotyczyło rozwoju interfejsu użytkownika ... Masz na myśli, panie deworde?
Ian
0

To zależy od tego, jak użyteczny byłby program wiersza poleceń. Niektóre rzeczy, takie jak wytyczenie trasy na mapie lub granie w trójwymiarowe gry, po prostu nie nadają się do interfejsu wiersza poleceń. Ale inne rzeczy, takie jak narzędzia systemowe, są znacznie lepsze z wiersza poleceń niż z GUI, z tego prostego powodu, że można je pisać w skryptach.

Dr Richard Hipp powiedział kiedyś, że jego idealnym systemem operacyjnym z graficznym interfejsem użytkownika jest pusty pulpit z ikoną do otwierania okien poleceń i inną ikoną do otwierania przeglądarki internetowej. Czuję się prawie tak samo. Jeśli byłby użyteczny jako program wiersza poleceń i nie jest zbyt trudny do zbudowania w ten sposób, zrobiłbym to. GUI może być całkowicie oddzielnym programem, być może zbudowanym przez kogoś innego!

GlenPeterson
źródło
Dlaczego wykreślenie trasy na mapie nie nadaje się do automatyzacji CLI? Coś takiego PlotRoute(startPoint, endPoint)jest dość proste.
Mason Wheeler,
@MasonWheeler - Wierzę, że byłoby to bardziejPlotRoute(startPoint, endPoint, chart)
Fabricio Araujo
0

W dzisiejszych czasach (przynajmniej dla Javy) wydaje się, że prędzej czy później wszystkie programy dodają usługę internetową (SOAP lub Ajax lub obie) wcześniej czy później. Tak więc ogólnie myślę w ten sposób, ale fronton usługi internetowej jest bardziej prawdopodobny niż linia poleceń, jeśli chcesz lepszej metafory mentalnej ... i bardziej prawdopodobnej.

ArtB
źródło
0

Jest inny sposób patrzenia na rzeczy. Zamiast zakładać, że jedynym wyjściem jest linia poleceń, dlaczego nie założyć, że zamiast niej można zastosować kontrolę mowy? Potrzebny jest zatem zupełnie inny paradygmat.

Zanim Jobs przejął Apple, badano bardzo wyrafinowane mechanizmy sterowania głosem. Apple zatarło to na korzyść takich rzeczy jak Siri.

Westchnienie.

Popularne i oczywiste nie zawsze są „najlepsze”.

Siajanai
źródło
Jednym z głównych powodów wiersza poleceń jest głównie możliwość testowania i skryptowania funkcjonalności oprogramowania. Nagrywanie klipów audio naszych głosów w celu przetestowania oprogramowania lub uruchomienia skryptu wsadowego może być nieco niewygodne (a przynajmniej dyskretne).
0

To ogólnie dobry pomysł, tak.

Metafora, ludzie mogą myśleć o tym jako o formie RESTful design. .... nie jest to per se, ponieważ typowy (G) interfejs użytkownika może obejmować złożone transakcje wieloetapowe, takie jak tworzenie konta.

Better that one stays away from multi-stage complexity through shopping-cart-like models for transactional setup.

Kiedyś zaprogramowałem w przeglądarce metaforę przeciągania i upuszczania. Bardzo złożone reguły interakcji na zapleczu, aby UX wydawał się naturalny. Rozwiązałem to, zmieniając witrynę w interfejs API, a GUI była pełną aplikacją, która generowała zdarzenia po akcji. Moduł przechwycił te zdarzenia i na zegarze umieścił je w „wywołaniach API” (w celu zwiększenia wydajności sieci).

Rezultatem był całkowicie RESTful system rdzenia. Drugą konsekwencją było to, że miałem interfejs dla stron trzecich, który mogłem ujawnić za pomocą profili afiliacyjnych zgodnie z modelem biznesowym.

NewAlexandria
źródło
-1

Jedną z zalet jest to, że będziesz zmuszony myśleć o przepływie interfejsu użytkownika z perspektywy użytkownika. (Co próbuję osiągnąć? Jaki kontekst muszę skonfigurować? Biorąc pod uwagę ten kontekst, w jaki sposób osiągnąć cel?)

Istnieje duża różnica między „Utwórz konto bankowe” a „Napisz dokument MS Word”. Nawet jeśli nie zbudujesz interfejsu CLI, może to stanowić wartość dodaną, biorąc pod uwagę potrzebę „kontekstu CLI”. Modele nie działają tylko w modelu obiektów biznesowych!

Aswidi
źródło