프로젝트간에 작은 코드 스 니펫을 공유하기위한 우수 사례


102

나는 항상 직장에서 DRY 원칙 을 따르려고 노력합니다 . 게으름에서 코드를 반복 할 때마다 나중에 두 위치에서 해당 코드를 유지해야 할 때 물립니다.

그러나 종종 서로 참조 할 수없는 두 프로젝트에서 재사용 해야하는 작은 방법 (어쩌면 10-15 줄의 코드)을 작성합니다 . 이 방법은 네트워킹 / 문자열 / MVVM 등과 관련이있을 수 있으며 원래 프로젝트에 국한되지 않은 일반적으로 유용한 방법입니다.

이 코드를 재사용하는 표준 방법은 재사용 가능한 코드에 대해 독립적 인 프로젝트를 만들고 필요할 때 해당 프로젝트를 참조하는 것입니다. 이것의 문제는 우리가 이상적이지 않은 두 가지 시나리오 중 하나에 빠진다는 것입니다.

  1. 우리는 재사용 할 필요가있는 작은 클래스 / 방법을 수용하기 위해 수십 / 수백 개의 작은 프로젝트로 끝납니다. .DLL작은 코드만으로도 완전히 새로운 것을 만드는 것이 가치가 있습니까?
  2. 우리는 점점 더 많은 관련없는 메소드와 클래스를 보유하는 단일 프로젝트로 끝납니다. 이 접근법은 내가 일했던 회사가하는 일입니다. 그들은 base.common위에서 언급 한 것과 같은 폴더 가있는 프로젝트라는 이름 을 가지고 있습니다 : 네트워킹, 문자열 조작, MVVM 등 매우 유용하지만 필요없는 모든 관련 코드를 불필요하게 드래그하여 참조합니다.

그래서 내 질문은 :

소프트웨어 팀은 프로젝트간에 작은 코드를 재사용하는 데 가장 좋은 방법은 무엇입니까?

특히이 분야에 대한 정책이 있거나 개인적으로이 딜레마를 겪은 회사에서 일한 사람이 있다면 관심이 있습니다.


참고 : "Project", "Solution"및 "Reference"라는 단어는 Visual Studio의 .NET 개발 배경에서 비롯된 것입니다. 그러나이 문제는 언어와 플랫폼에 독립적이라고 확신합니다.


21
+1이지만 .NET에서 일하는 사람에게는 DLL 참조를 통해 관련이없는 코드를 드래그하는 데 관심이있는 유머 요소가 있다고 생각합니다.
JDB

2
@ColeJohnson .NET 자체는 큰 참조입니다! 아마 내가 만들려는 dll보다 훨씬 큽니다.
George Powell

2
나는 그것을 얻는다. 그러나 .NET의 JIT 컴파일러는 필요한 메소드 만 RAM에로드합니다 (호출 될 때)
Cole Johnson

1
참된. 제품을 사용하려는 모든 사람에게 여전히 전체 .NET 프레임 워크를 배포해야하지만 대규모 프로젝트와 복잡한 솔루션은 관리하기가 더 어렵습니다.
George Powell

답변:


75

그것들이 실제로 재사용 가능한 메소드 / 클래스라면 소수의 '스위스 육군 나이프'라이브러리에 쓸 수 있습니다. 우리 회사에서이 작업을 자주 수행합니다. 이를 프레임 워크 라이브러리라고합니다.

  • Framework.Data -데이터베이스 쿼리 작업을위한 유틸리티.
  • Framework.ESB -엔터프라이즈 서비스 버스와 상호 작용하기위한 표준 방법
  • Framework.Logging -통합 로깅 시스템
  • Framework.Services -웹 서비스와 상호 작용하기위한 유틸리티
  • Framework.Strings -고급 문자열 조작 / 퍼지 문자열 검색 등을위한 유틸리티
  • ...

전체적으로 약 12여 개의 라이브러리가 있습니다. 코드를 실제로 배포 할 수는 있지만 적합하다고 생각되면 수백 가지로 끝나거나 모든 것을 하나의 거대한 어셈블리에 덤프 할 필요가 없습니다. 이 접근 방식은 우리 프로젝트 중 일부만 필요 Framework.Data하고 일부만 필요하기 때문에 적합 Framework.Strings하므로 소비자는 특정 프로젝트와 관련된 프레임 워크 부분 만 선택할 수 있습니다.

실제로 재사용 할 수있는 실제 메소드 / 클래스가 아닌 스 니펫 일 경우 IDE에 코드 스 니펫으로 배포하면됩니다 (예 : Visual Studio Code Snippets ). 과거에 함께 작업 한 팀에는 공통 코드 조각 라이브러리가있어 모든 사람이 내부 코드로 표준 코딩 방법을 쉽게 따라갈 수있었습니다.


4
+1 이것은 나의 접근 방식이기도합니다. 두 가지 이상의 측면을 다루는 코드를 어디에 둘 것인지 결정하는 방법에 관심이 있습니다. 예를 들어 IPAddressToString입니다. 그리고이 라이브러리들이 서로를 사용할 수 있는지 여부. 예를 들어 서비스와 데이터는 아마도 로깅을 통해 많은 이점을 얻을 수 있습니다.
Marjan Venema

5
@MarjanVenema 교차 절단 코드의 경우 소비자에게 어떤 방법이 더 유용한 지에 따라 다릅니다. 의 경우 IPAddressToString네트워크 프로토콜을 다루는 소비자가이를 사용해야 할 가능성이 있지만 문자열을 많이 사용하는 소비자는 IP 주소를 전혀 신경 쓰지 않을 수 있습니다. 아마 아마 오히려 네트워킹 패키지가 될 것 Framework.Strings입니다.
pswg

@MarjanVenema 우리는 상호 의존성을 피하려고 노력합니다. 당사의 서비스 및 데이터 프레임 워크는 자체적으로 로깅을 수행하지 않지만 소비자가 적절한 로깅 코드를보다 쉽게 ​​작성할 수 있도록 작성되었습니다. 프레임 워크 라이브러리는 서로를 참조 할 수 있지만, 확장에 의해서만 가능합니다. 예를 들어 Framework.Logging.Gibraltar로깅 시스템에 대한 특정 애드온입니다.
pswg

5
+1이 프레임 워크 라이브러리를 가져 와서 네트워크 폴더처럼 간단한 내부 NuGet 리포지토리에 배포 할 수 있으며이를 관리 할 수있는 좋은 방법이 있습니다.
Steven Evers 2016 년

2
@SteveEvers 지금 실제로 설정하고 있습니다. : P
pswg

21

여러 가지 이유로 허용 된 답변에 동의하지 않습니다.

내 경험상 받아 들여진 대답과 같은 "기타"라이브러리를 볼 때 바퀴재발 명 할 변명 (또는 여기에 발명되지 않음) -Dont Repeat Yourself (DRY)를 위반하는 것보다 훨씬 더 큰 죄 입니다.

때로는 DRY를 위반하는 것이 합당한 타협이 될 수 있으며, 타이트한 커플 링을 도입하는 것보다 낫습니다. 재사용은 우수한 객체 지향 디자인과 비교하여 부차적 인 관심사입니다. 스파게티 코드 기반보다 약간의 중복 ( 소량을 의미하며 규칙 3을 적용 )이 이해하기 쉽습니다.

수많은 범용 라이브러리의 접근 방식은 나쁜 예를 제시합니다. 세밀한 조립으로 이어지고 너무 많은 조립품이 나쁩니다. 최근에 사내를 24 개의 도서관에서 6 개의 도서관으로 줄였습니다. 컴파일 시간이 몇 분에서 ~ 20 초로 향상되었습니다. Visual Studio는 더 많은 어셈블리에서로드 속도가 느리고 반응 속도가 느립니다. 라이브러리가 너무 많으면 코드가 어디에 있어야하는지 혼동 될 수 있습니다. 더 적고 간단한 규칙을 선호합니다.

.Net Framework의 항목이 충분하지 않은 이유는 무엇입니까? 프레임 워크는 꽤 큽니다. 여러 번 이미 존재하는 것들을 다시 구현하는 코드를 보았습니다. 실제로 프레임 워크가 .Net 프레임 워크의 틈새를 채우고 미학적 이유로 존재하지 않아야합니다 (예 : "여기서 .Net 프레임 워크가 마음에 들지 않습니다"또는 아마도 조기 최적화 )

아키텍처에 다른 계층을 도입하면 상당한 복잡 비용이 발생합니다. 레이어가 존재하는 이유는 무엇입니까? 나는 잘못된 재사용을 보았습니다. 즉, 코드는 사내 프레임 워크 위에 구축됩니다. 표준 라이브러리 위에 직접 구현하는 것이 훨씬 효율적이었습니다.

.Net 프레임 워크 및 인기있는 타사 / 오픈 소스 라이브러리와 같은 표준화 된 기술을 사용하면 기술을 구축 할 때의 기술적 이점보다 종종 이점이 있습니다. 이러한 기술을 아는 인재를 쉽게 찾을 수 있으며 기존 개발자가이를 배우는 데 더 많은 투자를 할 것입니다.

내 추천 :

  • 이 코드를 공유하지 마십시오.
  • 응집력있는 목적을 가지고 있다면 새 라이브러리를 만드십시오 . 진흙 디자인 패턴공을 사용하지 마십시오 .
  • 가능한 경우 기존 타사 라이브러리를 재사용하십시오.
  • 코드가 어디에 있어야하는지에 대한 간단한 규칙으로 더 적은 어셈블리를 선호하십시오.

1
사용 가능한 경우 오픈 소스 라이브러리를 사용하면 큰 이점이 있습니다. 개선 된 부분이 있으면 커뮤니티와 다시 공유 할 수 있습니다! 예를 들어 .Net MS는 일반적인 시나리오를위한 훌륭한 도구 세트를 제공하는 EnterpriseLibrary (이제 오픈 소스)를 게시했습니다. 모두 혜택!
glenatron

2
나는 여기에 받아 들여진 대답에 동의하지 않습니다 :-). "코드가 어디에 위치해야하는지에 대해 더 간단한 규칙을 가진 더 적은 어셈블리"는 수용된 답변과 모순되지 않습니다. 대답은 또한 합리적으로 보이는만큼 다른 어셈블리를 사용하는 것을지지합니다.
sleske

5 년 후 마이크로 서비스 지침도이 관행에 수렴되었습니다 : medium.com/standard-bank/…
Dave Hillier

11

의존성이없는 단일 클래스와 같은 작은 코드 비트의 경우 코드를 복사하여 프로젝트에 붙여 넣는 경향이 있습니다. 이것은 DRY 위반으로 들리며 때때로 가능할 수 있음을 인정합니다. 그러나 장기적으로 몇 가지 이유로 여러 종류의 다목적 공동 프로젝트를 수행하는 것보다 훨씬 낫습니다.

첫째, 특히 물건을 빌드하고 디버깅 할 때 코드를 편리하게 사용하는 것이 더 간단합니다.

둘째, 항상 해당 프로젝트의 공통 코드를 약간 조정하고 싶을 것입니다. 소스의 로컬 사본이 있다면 조정 만하고 하루에 호출 할 수 있습니다. 공유 라이브러리가있는 경우 해당 라이브러리를 조정 한 다음 다른 모든 앱을 중단하거나 버전 관리 악몽을 만들지 않을 수 있습니다.

따라서 자체 네임 스페이스만큼 충분하지 않은 경우 프로젝트의 적절한 비트로 밀어 넣고 하루를 호출하는 경향이 있습니다.


5
나는이 접근법에 동의하지 않는다. 작은 코드 조각을 관리하는 유지 관리 문제에 감사하지만 @psw가 제안하는 것처럼 일부 공통 라이브러리를 만들 수 있다고 주장합니다. 약간의 수정으로 코드 사본이 중복되면 문제가 발생합니다. 가정이 이루어지고 버그 수정이 누락됩니다.
Andrew T Finnell

2
-1 (답). 모든 사람이 자신의 프로그램 버전의 사본을 소유하게하는 것이 훨씬 쉽습니다. 이것이 80 년대에 소프트웨어가 개발 된 방식입니다. 나는 장기적으로 이것이 혼란에 빠진다는 것을 알게되었습니다. 사람들이 자신의 작업에 대해 훨씬 더 많은 의사 소통을해야하므로 올바른 일을하고 공용 라이브러리를 갖추기가 더 어렵습니다. 글쎄, 그들은해야합니다.
Michael Durrant

3
+1-이 방법을 자주 사용하고 싶지 않더라도이 방법을 언급 할 가치가 있다고 생각합니다. 일부 스 니펫은 디자인 패턴과 비슷합니다. em을 재사용 할 수 있지만, 위치와 언어가 약간 다르고, 다른 언어로도 변경하고 싶을 수도 있습니다. 또한 API를 변경하면 매우 위험하다는 점에서 광범위하게 재사용되는 라이브러리는 융통성이 없습니다. 마지막으로이 접근 방식을 대체로 사용하면 실험적 라이브러리를 조금 더 오래 유지함으로써 공유 라이브러리의 품질이 향상됩니다.
Eamon Nerbonne 2016 년

6

당신이 설명하는 두 번째 해결책은 그렇게 나쁘지 않습니다. .NET에서는 단일 클래스 만 사용하더라도 GAC의 어셈블리를 참조합니다. '무관 한 코드 끌기'는 생각하는 것처럼 문제가되지 않습니다. 이 경우 최소한 관련 네임 스페이스에서 관련 메소드와 클래스를 깔끔하게 정리하는 것이 중요합니다. 또한이 솔루션이 혼란스러워지지 않도록 API 설계에 대한 우수 사례를 적용해야합니다.

아주 작은 코드 조각에 대해서는 다음과 같은 접근 방식이 일반적인 프로젝트를 보완하는 좋은 방법이라고 생각합니다. 다른 솔루션에서 복제 할 수 있습니다. 모범 사례처럼 다루십시오. 문서화하고 팀에 전달하십시오.


1
비표준 라이브러리의 경우를 제외하고는 단일 또는 소수의 사용으로 인해 대규모 어셈블리를 배송해야 함을 의미합니다. 어쨌든 표준 제품에는 문제가되지 않지만, 좋은 방법으로 분할 할 수 있다면 대부분 사용되지 않는 대형 어셈블리를 운송하지 않는 것이 좋습니다.
찌를

6

나는 이런 종류의 일이 문제가되었고 매번 채택 된 두 번째 옵션이 될 때마다 "기업"환경에서만 일했습니다. 대부분의 경우 응용 프로그램 설치 공간에 대한 제약이 없으므로 정상적으로 작동합니다.

그러나 지난주에 자체 Nuget 서버를 실행하는 신생 기업과 함께 보낸 것은 가능한 대안으로 제안하는 경향이 있습니다. 물론 내가 등장 할 것으로 예상되는 문제는 발견 가능성에 관한 것입니다.

프로젝트가 적절하게 세분화되고 네임 스페이스가 합리적이라면 이것이 인기있는 접근 방식이되는 것을 볼 수 있습니다.


어떤 의미에서 당신은 그들이 발견되지 않을 것으로 기대합니까? 우리는 그런 방식으로 점점 더 많은 수의 너겟 패키지를 사용합니다. 가장 큰 문제는 버전 관리 및 종속성 관리와 관련이 있습니다.
pdr

아. 넵. 그들도. 발견 가능성에 관한 문제로, 특정 기능을 가진 충분한 수의 작은 패키지가 주어지면 각각을 카탈로그 화하고 찾기가 더 어려워 질 수 있음을 의미합니다. 예를 들어, 팀은 다양한 기능을 포함하는 패키지를 어떻게 알 수 있습니까? (여기에 너겟 검색 무지를 표시)
Kofi Sarfo

아, 알겠습니다 예, 설명에 원하는 것을 넣을 수 있고 검색 가능해 지지만 문제가되지 않을 정도로 패키지를 충분히 그룹화했다고 생각합니다.
pdr

@sarfeast Nuget 서버가 무엇이든간에 링크를 공유하고 그것에 대해 조금 이야기하면 좋을 것입니다.
Hans-Peter Störr

6

나는 최근에 이것에 대해 생각하고 나에게 일어난 것은 지금까지 언급 된 것처럼 일반적인 방법의 큰 라이브러리 였지만 비 틀었습니다. 라이브러리 프로젝트를 사용하면 BusyBox 프로젝트 와 같은 종류의 조각을 컴파일 타임에 구성 할 수 있습니다 . 이 접근 방식을 사용하면 주방 싱크 스타일 라이브러리 저장소를 사용할 수 있지만 컴파일 할 때 필요한 도구 만 가져옵니다.


5

GitHub에는 코드 스 니펫을 저장하는 데 매우 유용한 도구가 있습니다 https://gist.github.com/

스 니펫을 개인 저장소로 유지하거나 다른 사람과 스 니펫을 공유하는 데 사용할 수있는 자식 저장소로 스 니펫을 저장합니다.


3

팀 / 프로젝트 / 회사의 규모에 따라 이미 환경에 구축되어 있지 않으면 효과적으로 수행하기가 어려울 것입니다. 구현하는 모든 솔루션은 비용이 많이 듭니다. 더 안전 할 수 있지만 쉽게 측정 할 수는 없습니다. 가격이 가치가 있는지 확인해야합니다. 재사용 가능한 솔루션은 추상적이되는 경향이 있으며 종종 최적의 상태가 아닌 많은 상황에 적합합니다.

어쨌든 여러 사람이 만든 코드에 대해이 작업을 수행하려면 먼저 모든 사람과 협력에 대한 인식이 필요합니다. 여기에는 개발자와 관리자가 포함됩니다.

그런 다음이 작업을 수행 할 범위를 알아야합니다. 팀? 계획? 부서? 회사? 답에 따라 그러한 솔루션에 넣을 코드의 종류는 dll을 조정하는 세분성에 따라 달라집니다. 일단 당신이 이것을 결정하면 (바람직하게 아이디어에 대한 열정을 가지고-당신은?) 앉아서 앉아서 이것에 어떤 구조를 시작해야합니다.

그러나 그러한 dll을 만드는 것만으로는 트릭을 수행하기에 충분하지 않습니다. 그것들을 유용하게 사용하려면 (사용자 및 기고자에게) 광고하고 다른 소프트웨어와 같이 유지해야합니다. 일반적으로 오랫동안 누군가를 담당해야합니다. 신뢰할 수있는 문서도 필요하며, 유지 관리도 필요합니다. 행운과 협력을 통해 모범 사례를 얻을 수는 있지만 관련 팀의 규모와 수에 따라 자체 프로젝트로 쉽게 발전 할 수 있습니다. 그리고이를 위해서는 여전히 관리 지원이 필요합니다.


3

나는 많은 문제를 겪었고 선호하는 해결책은 코드를 github / pubic web-enabled 저장소에 게시하는 것입니다. 많은 문제를 해결합니다-

  1. 쉽게 액세스하고 공유 할 수 있습니다. cvs / svn / enterprise-repos는 프로젝트를 여러 IDE 작업 영역으로 체크 아웃하는 것을 의미하며 때로는 작은 코드 스 니펫을 참조하기 위해 작업 영역이나 컴퓨터를 전환해야합니다.
  2. 이러한 코드 스 니펫이 독점 / 분류 된 코드 조각이 아니며 공개적으로 사용할 수있는 지식의 변형이며 github와 같은 공개 저장소에 게시하면 다른 사람들이 그것을보고 기여할 수도 있음을 의미합니다.
  3. 공개 도메인에 귀하의 이름으로 무언가를 게시하면 평판이 더 높아집니다. 프로그래머로서의 능력을 반영하기 때문에 사물을 다시 확인하고 업데이트합니다.
  4. 업데이트. 리포지토리에서 코드 스 니펫을 유지 관리하는 것은 스 니펫을 오랫동안 사용하지 않은 경우 오래되지 않을 수 있습니다 (오래된 apis / libs 포함). 예-파일을 읽는 Java 코드 스 니펫 2009 년에이 작업을 수행하는 가장 좋은 방법을 알아 냈을 수도 있지만 2014 년에는 모든 것을 변경하는 새로운 파일 API가 나타납니다. 스 니펫? 공개 리포지토리에서는 사용자 (총알 3이기 때문에), 팀원 또는 일반 프로그래머 집단의 구성원에 의해 상황이 업데이트되며 그 과정에서 문제를 해결하기위한 제안을받을 수도 있습니다. 오랫동안 잘못했을 수도 있습니다.

스 니펫을 어디에 보관하든 관계없이 사용하기 전에 항상 Google 콘텐츠를 올리십시오. 일이 항상 바뀝니다. 저장된 스 니펫은 시간을 절약 할뿐만 아니라 만족도를 높 입니다.


2

이 작은 방법들을 테스트와 함께 저장하는 별도의 프로젝트 "유틸리티"가 있습니다.

프로젝트에 유틸리티가 필요한 경우 "링크로 추가"를 사용하여 필요한 방법으로 소스 파일을 추가하면됩니다.

즉, 포함 된 파일에 필요하지 않은 한 런타임 종속성이 추가되지 않습니다.

이 시스템은 잘 작동했지만 다른 시스템과 마찬가지로 유틸리티 란 무엇입니까? 높은 테스트 범위를 요구하는 것은 우리에게 잘 작동했으며 테스트도 좋은 사용법 문서입니다. 디스커버리는 여전히 해결되지 않은 문제입니다.

유틸리티 프로젝트의 한 가지 복잡성은 항목의 가시성 수준을 결정하는 것입니다. 일반적으로 메서드는 내부 및 데이터 구조가 공개되어야합니다.


2

우리 회사는 인트라넷 로컬 웹 서비스를 사용합니다. 우리는 일반적인 내부 웹 서비스로 설정된 몇 가지 웹 서비스를 가지고 있으며, 다른 프로젝트가 서비스 중 하나에 액세스해야하는 경우 정의 된 인터페이스로 http 요청을 보냅니다. 동일한 서버 팜에있는 인트라넷에 있기 때문에 이러한 요청은 매우 빠릅니다.

분명히 이것은 인터넷 응용 프로그램에서만 작동하며 (동일한 로컬 네트워크에서 밀리 초 만 작동 함) 실제로 장점이 있습니다.


0

최근 Snip2Code ( http://www.snip2code.com ) 서비스를 제안했습니다 .

스 니펫 (전체 라이브러리가 아님) 만 팀과 공유하는 흥미로운 방법입니다. 다른 프로젝트에서 참조 해야하는 공통 라이브러리를 만드는 것은 일반적인 요점을 어 기고 이것은 내 의견으로는 이것이 귀중한 비전입니다.

또한 공통 라이브러리의 사용이 단순히 적용되지 않는 시나리오가 많이 있습니다. 예를 들어 Singleton, Strategy 또는 Observer와 같은 일부 디자인 패턴을 고려하십시오. 이러한 패턴을 지원하기 위해 라이브러리를 만들 수 있지만 여전히 100 % 적용 범위는 없습니다.

실제로 필요한 것은 팀간에 공통의 관행을 공유 할 수있는 도구를 갖추는 것입니다. 나는 Github의 요점을 사용하려고 시도했지만 (실제로 열악한) 검색과 내 팀간에 공유 할 수 없으며 다른 사람들과 공유 할 수 없다는 사실에 갇혀 있습니다 ...

(면책 조항 : 저는 Snip2Code의 창립자 중 한 사람이며 공동 창립자와 함께-얼마 전에 같은 생각을 가지고있었습니다. 이것이 우리 가이 프로젝트를 시작하기로 결정한 이유입니다!)

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