일부 사용자를위한 기능 숨기기 / 비활성화


11

무료 및 유료 버전의 앱이 있다고 가정 해 보겠습니다. 유료 버전은 사용자가 사용할 수있는 기능과 관련하여 무료 버전의 상위 세트입니다. 즉, 유료 버전에는 무료 앱의 모든 기능과 추가 기능이 포함됩니다.

시작시로드되는 플래그 (예 : 무료 / 유료)를 기반으로 기능 가용성을 토글하는 패턴이 있습니까?

나는 어디에서나 다음 코드 블록을 갖는 아이디어를 좋아하지 않습니다.

if(isFreeVersion){
    // ...
} else {
    // ...
}

모든 버전이 별도의 자식 가지를 갖는 것은이 둘을 유지 (또는 그 이상)의 코드 소스를 의미하기 때문에 옵션이 아닙니다, 일반적으로 실용적이지 것보다 여기에 설명되어 있습니다 : 버전 제어에서 동일한 코드베이스에서 두 별도의 소프트웨어 버전을 유지 .

단일 코드 기반을 유지하면서 무료 / 유료 플래그를 확인하는 조건문으로 코드를 낭비하지 않는 방법이 있습니까?

나는 이것이 전에 여러 번 논의되었다고 확신 하고이 문제에 접근하는 데 몇 가지 패턴이 있다고 확신하지만 찾을 수는 없습니다.

우리는 Android / Java를 사용합니다.



@ gnat tnx, 좋은 발견. 그러나 별도의 지점이 필요하지 않고 여러 코드베이스를 유지 관리하지 않는 옵션에 대해 논의하고 싶습니다
Tadija Bagarić

2
다른 인증 수준을 갖는 것과 비슷합니다. 특정 사용자 / 역할에서만 기능을 사용할 수있는 문제가 일반적으로 어떻게 해결되는지 조사 할 수 있습니다.
Bart van Ingen Schenau

@BartvanIngenSchenau 나는 if금지 된 기능에 대한 컨트롤을 숨기거나 사용자가 허용되지 않은 작업을 시도 할 때 팝업 대화 상자 가 있는지 확인 하는 것이 대부분이라는 것을 알았 습니다. 코드에서 많은 조건을 피할 수있는 방법을 찾고
싶습니다

2
다 언론을 사용하십시오. 이 if 문에 대해 다시 묻지 않아도되며 유지 관리가 훨씬 쉬워집니다!
Steve Chamaillard

답변:


9

if/else블록 이 마음에 들지 않으면 상속을 사용하도록 블록을 리팩터링 할 수 있습니다 ( Marin Fowler 's Refactoring book 의 조건부에서 다형성 으로 조건부 바꾸기 참조 ). 이것은 :

  • 코드를 추론하기가 약간 더 간단합니다.

  • 무료 버전 용 클래스와 유료 버전 용 클래스 두 개를 사용할 수있게하여 다른 클래스로 호출을 전달하여 무료 버전과 유료 버전의 구분이 두 클래스로 제한되도록합니다 (세 가지 기본 클래스).

  • 나중에 저렴한 변형 또는 프리미엄 버전과 같은 다른 형태의 소프트웨어를 쉽게 추가 할 수 있습니다. 다른 클래스를 추가하고 코드에서 한 번 선언 하면 전체 코드베이스가 여전히 예상대로 작동한다는 것을 알 수 있습니다.


3
구현 상속 이 필요하지 않다는 것을 더 명확하게하고 싶을 수도 있습니다 . 또 다른 이점은 무료 기능을 프리미엄 기능없이 제공 할 수 있다는 것입니다. if 조건이 항상 true가되도록 Java 바이트 코드를 수정하는 것은 그리 어렵지 않습니다.
JimmyJames

15

조건부 유사은 코드에서 한 번만if(isFreeVersion) 발생해야합니다 . 이것은 패턴이 아니지만 이미 그 이름을 알고 있다고 확신합니다. 이것을 DRY 원칙 이라고 합니다 . 코드 에서 둘 이상의 위치에 " " 와 같은 코드가 있으면 이 행 / 논리를 반복한다는 의미이므로 반복을 피하기 위해 리팩토링해야합니다.if(isFreeVersion)

" if(isFreeVersion)"는 다른 기능에 대한 내부 구성 옵션 목록을 설정하는 데 사용해야합니다. 결과 코드는 다음과 같습니다.

 if(isFreeVersion)
 {
      feature1Enabled=false;
      feature2Enabled=false;
      maxNoOfItems=5;
      advertisingStrategy=new ShowLotsOfAdvertisementsStrategy();
      // ...
 } 
 else
 {
      feature1Enabled=true;
      feature2Enabled=true;
      maxNoOfItems=int.MaxValue; // virtually unlimited
      advertisingStrategy=new ShowMinimalAdvertisementsStrategy();
 }

단일 "isFreeVersion"플래그를 다른 기능에 매핑합니다 . 기능 제어에보다 복잡한 매개 변수화가 필요한 경우 개별 기능에 개별 부울 플래그를 사용하거나 공통 인터페이스가있는 다른 전략 오브젝트와 같은 다른 매개 변수를 사용하도록 여기에서 결정할 수 있습니다.

이제 무료 버전에있는 것과 유료 버전에있는 것을 한곳에서 제어 할 수 있으므로이 논리를 매우 간단하게 유지 관리 할 수 ​​있습니다. if(feature1Enabled)DRY 원칙에 따라 많은 문장으로 코드를 복잡하게 만들지 않도록 조심해야 하지만 이제이 검사를 유지하는 것이 더 이상 고통스럽지 않습니다. 예를 들어, 기존 유료 기능을 무료로 (또는 그 반대로) 변경하려는 경우 변경해야 할 사항을 훨씬 잘 제어 할 수 있습니다.

마지막으로 기능 토글 에 대한 Fowler의 블로그 기사를 살펴 보자. 기능 토글 / 토글 포인트에 대해 이야기한다. 하나의 중심점을 인용하겠습니다.

토글을 사용하여 새 기능 코드의 모든 코드 경로를 보호하려고 시도하지 말고 사용자를 유도하는 진입 점에만 집중하고 해당 진입 점을 토글하십시오.

따라서 전반적인 전략으로 사용자 인터페이스 에 집중 하고 특정 기능이 나타나거나 사라지는 데 필요한 최소한의 포인트로 검사를 제한하십시오. 불필요한 불필요한 혼란없이 코드베이스를 깨끗하게 유지해야합니다.


5
기본적으로 IsFreeVersion을 FeaturexEnabled로 바꾸었지만 호출 횟수를 줄이지 않았습니다. 나는 그 경우를 정확히 알지 못했지만 항상 메뉴를 만들 때 사용자가 보지 않아야 할 옵션을 비활성화하여 비슷한 것을 처리했습니다. 대부분 이것은 폼을 만들 때이지만 팝업 메뉴를 준비 할 때 가끔해야했습니다.
Loren Pechtel

1
@LorenPechtel : 더 신중하게 내 대답을 다시 읽어야합니다. 나는 실제로 조건부 테스트의 수를 줄이기 위해 가지를 언급 했는데, 그중 하나는 DRY 원칙이고, 그중 하나는 UI 테스트에 중점을 둡니다. 더 중요한 것은, 같은 불특정 플래그를 매핑 isFreeVersion특정 대부분의 이러한 테스트의 고통의 기능 매개 변수 제거합니다 - 그들은 실제로 이해하기 시작하고 더 이상 유지 보수 혼란을 생성하지 않습니다.
Doc Brown

6

Feature Toggle Pattern을 적용하면 질문을 꽤 잘 해결할 수있는 것 같습니다 .

종종 그렇듯이 Pete Hodgson 은이 기사를 적용 할 수있는 모든 시나리오를 한 기사에서 설명했습니다 .

이 패턴을 지원하는 라이브러리도 있습니다. Java에서 FF4J 로 작업 한 경험이 있지만 다음을 입력하면 추측합니다.

feature toggle <whatever language you prefer>

... 모든 검색 엔진에는 여러 가지 솔루션이 있습니다.


2

이를 달성하는 방법은 여러 가지가 있습니다. 간단하고 직접적인 방법은 많은 기사에서 제공되는 기능 토글 패턴 을 사용하는 것 입니다. 다음 접근 방식은 플러그 가능 기능을 설계하는 것과 관련이 있습니다. Android와 IOS 모두 인앱 결제가 있습니다. 그 지불과 함께 다운로드 가능성이 있습니다.

서블릿, JAMES Mailets 및 IDE 플러그인을 살펴보면 모두 플러그인 아키텍처의 개념을 사용합니다.

  • 앱에서 사용 방법을 알고있는 인터페이스를 정의하십시오. 이 인터페이스는 애플리케이션의 내비게이션 및 플러그인 터치 포인트를위한 다른 앱에 자신을 주입하는 방법을 제공해야합니다.
  • 시작할 때 앱이 읽을 경로를 설정합니다 (런타임 플러그인 관리는 훨씬 더 어렵습니다)
  • 플러그인이 존재하면 (Java Jar 파일과 같이) 앱은 매니페스트를 읽어 플러그인 인터페이스의 구현을 찾거나 인터페이스를 구현하는 클래스를 검색합니다.
  • 해당 클래스가 발견되면 인스턴스화되고 새 기능을 통합하기 위해 적절한 메소드가 호출됩니다.

이 기능을 사용하면 다양한 대상에 대해 다양한 클래스의 기능을 사용할 수 있습니다. 사용자는 지불 한 기능 만 갖습니다.

애플리케이션 코드는 하나의 코드 기반으로 유지 보수되며 플러그인은 별도의 코드 기반이지만 플러그인과 관련된 파트 만 포함합니다. 앱은 플러그인이있을 때 플러그인을 처리하는 방법을 알고 있으며 플러그인은 인터페이스와 상호 작용하는 방법 만 알고 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.