In software engineeringDon't Repeat Yourself (DRY) is a principle of software development aimed at reducing repetition of information of all kinds, especially useful in multi-tier architectures. The DRY principle is stated as "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system." The principle has been formulated by Andy Hunt and Dave Thomas in their book The Pragmatic Programmer. They apply it quite broadly to include "database schemas, test plans, the build system, evendocumentation."[1] When the DRY principle is applied successfully, a modification of any single element of a system does not require a change in other logically unrelated elements. Additionally, elements that are logically related all change predictably and uniformly, and are thus kept in sync. Besides using methods and subroutines in their code, Thomas and Hunt rely on code generators, automatic build systems, and scripting languages to observe the DRY principle across layers.

Contents

  [hide

[edit]Applying DRY

Also known as Single Source of Truth, this philosophy is prevalent in model-driven architectures, in which software artifacts are derived from a central object model expressed in a form such as UML. DRY code is created by data transformation and code generators, which allows the software developer to avoid copy and paste operations. DRY code usually makes large software systems easier to maintain, as long as the data transformations are easy to create and maintain. Tools such as XDoclet and XSLT are examples of DRY coding techniques. Examples of systems that require duplicate information are Enterprise Java Beans version 2, which requires duplication not just in Java code but also in configuration files. Examples of systems that attempt to reduce duplicate information include the Symfonyweb2pyYiiPlay Framework and Django web frameworks, Ruby on Railsapplication development environment, Microsoft Visual Studio LightSwitch and Enterprise Java Beans version 3.

[edit]DRY vs WET solutions

Violations of DRY are typically referred to as WET solutions, which stands for "Write Everything Twice".[2] With hyperbole, WET becomes WETTT, which stands for "Write Everything Ten Thousand Times". Alternatively you could call it WETWET.

[edit]See also

[edit]References

  1. ^ Dave Thomas, interviewed by Bill Venners (2003-10-10). "Orthogonality and the DRY Principle". Retrieved 2006-12-01.
  2. ^ Alex Papadimoulis (2011-12-08). "The WET Cart". Retrieved 2012-05-21.

[edit]External links



Don't repeat yourself (DRY) 또는 Single Point of Truth는 특히 컴퓨팅 의 영역에서 중복을 방지 생각이다. 이 철학은 정보 의 중복 수정의 어려움을 증가 투명성을 감소시켜 불일치를 일으킬 될 수 있으므로 중복해야한다고 강조한다.

DRY는 Andy Hunt 및 Dave Thomas 의 저서 The Pragmatic Programmer (邦題: 달인 프로그래머)에서 중심이되는 원칙이다. 그들은이 원칙을 데이터베이스 스키마, 테스트 계획 , 빌드 시스템 과 문서 에 이르기까지 매우 폭넓게 적용하고있다 [1] .

DRY 원칙이 잘 적용되면 시스템에 대한 어떠한 요소의 변경도 논리적으로 관련이없는 다른 요소의 변경으로 이어지지는 않는다. 또한 논리적으로 관련된 요소는 예측 가능한 형태로 통일적으로 변경되고 따라서 그 변화는 동기화 가 잡힌 것이된다.

목차

  [ 숨기기 ] 

Once and Only Once 원칙과 대비 편집 ]

DRY는 응용 프로그램에 필요한 정보 (보통 설정 정보)에 대해 언급하고 있다는 점에서 Once and Only Once (OAOO) 원칙과는 구별된다. 비교하면 OAOO 코드의 기능적인 행동에 대해 언급하고, 구조체 및 객체 지향 언어에서 상속 의 실현이 필요한 이유이다.

예를 들어, DRY는 파일 집합의 위치는 응용 프로그램에서 한 곳에 저장되어야한다고 주장하지만,이 파일에서 데이터를 추출 처리를 응용 프로그램의 다른 부분에서 설명하는 횟수는 관용이다. OAOO 원칙은 이에 대해 파일에서 데이터를 검색하는 코드는 한 번만 작성하도록 요구하지만, 응용 프로그램에서 이러한 파일을 저장할 장소가 몇 군데인지는 관용이다.

또한 혼란을하는 응용 프로그램에서 개체 변수로 저장된 객체는 정보의 일부로 볼 수 있다는 점이며, 따라서 DRY는 객체에 적용되는 ( 인스턴스 를 하나만 갖는 ) 반면 OAOO는 클래스 에 적용된다. (응용 프로그램에서 개체의 클래스 템플릿 에 동일한 목적을 가진 다른 코드가없는)라는 점이다.

DRY 원칙이 유용하지 않을 경우 편집 ]

  • 중복 및 미러링 .
  • 소규모의 맥락에서, DRY에 따라 디자인하는 노력은 두 개의 독립된 데이터 복사본을 유지 관리하는 노력보다 훨씬 커진다.
  • DRY 원칙을 준수하도록 표준의 강요는 wiki 등의 커뮤니티 참여에 높은 가치가 같은 맥락에서 사회 참여를 저해 해 버린다.
  • 구성 관리 및 버전 관리 는 DRY 원칙을 일탈하지 않고 같은 코드의 복사를 허용한다. 예를 들어, 좋은 예로 개발 환경, 테스트 용 환경, 제품 판 코드를위한 환경을 구축하고 지속적인 개발과 테스트가 제품의 코드에 영향을주지 않도록하는 방법이있다.
  • 인간이 읽을 수있는 문서 (코드 코멘트에서 인쇄 된 설명서까지)는 일반적으로 코드의 내부까지 읽고 이해하는 능력이나 시간이없는 사람을위한 정교하고 설명 코드의 내부에있는 물건을 다시 작성하고있다. 그러나 DRY는 인간이 읽을 수있는 문서 형식의 변경을 제외하면 아무 가치도없고, 즉 기술되는 것이 아니라 생성되어야하고있다.
  • 소스 코드 생성 - 중복 금지는 소스 코드 생성에 도움이 있지만, 그것은 출력 결과가 아니라 중복 된 정보가 인간과 다른 코드에 의해 변경되지 않을 뿐이다.
  • 단위 테스트 - 소스 코드와의 충돌을 찾아내는 것이 목적이며 [2] , 소스 코드에서 자동으로 생성해서는 아니다. 그러나 소스 코멘트 나 문서에서 자동으로 생성하는 것은있을 수있다. [3]
  • Abel Avram는 DRY을 과도하게 추구하는 것으로 느슨하게 결합 원칙 을 위반 예, DRY는 어디 까지나 다른 원칙과 균형 하에서 지켜 져야한다고 말했다. [2]

관련 항목 편집 ]



Posted by linuxism
,


@Configuration을 사용한 웹 설정 파일 테스트 작성시 난감함…

package cantabille.config;

import cantabille.modules.ModulesPackageMarker;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

/**
* @author Keesun Baik
*/
@Configuration
@ComponentScan(
basePackageClasses = ModulesPackageMarker.class,
useDefaultFilters = false,
includeFilters = @ComponentScan.Filter(Controller.class))
public class WebConfig extends WebMvcConfigurationSupport {

@Override
protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}

@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/static");
}

@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}

}

이렇게 코딩을 해두고.. 이 설정 파일에서 빈으로 등록되는 것들이 제대로 등록되나 궁금하니까 테스트를 작성해볼 수 있겠죠.

package cantabille.config;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

/**
* @author Keesun Baik
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = WebConfig.class)
public class WebConfigTest {

@Autowired RequestMappingHandlerMapping rmhm;

@Test
public void di(){

}

}

이런식으로 말이죠. di() 메서드 아무것도 안해도 사실상 제가 원하는 테스트는 저정도면 충분하거든요. 그리고 이정도 테스트는 XML 기반으로 설정할 때도 잘 통과했었는데…. 흠.. 잘 안됩니다. ApplicationContext를 제대로 만들지 못합니다. 특정 빈을 만들지 못하기 때문이죠. DefaultServlet을 사용하려면 ServletContext가 필요하다는 에러가 나면서 Assert.notNull()에서 걸리고 말죠… 어찌하면 좋을까나…

스프링 TestContext를 포기할 수밖에 없는건가…

그리고 그게 꼭 필요한거면 XML 기반으로 동일한 설정을 할때도 안됐어여 하는거 아닌가..

흠.. 고민이로세.

아.. 그냥 테스트하지 말까.. 너무 당연한거니깐?? ㅋㅋㅋ


출처 - http://whiteship.me/?p=13555



위 설정에서 resolver.setViewClass(JstlView.class); 를 설정하지 않으면 다음과 같은 로그 발생

11월 21, 2012 6:31:09 오후 org.apache.jasper.compiler.TldLocationsCache tldScanJar

정보: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.




Posted by linuxism
,


spring code-based configuration에서 

"At least one base package must be specified" 예외 발생

@ComponetScan annotation에서 base package를 설정하지 않았기 때문






Posted by linuxism
,