분류 전체보기 (358)

Creational Patterns ( 생성 패턴 )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

생성패턴은 객체의 생성로직을 숨기고 new 명령어를 통하지 않고 객체를 생성하는 방법들을 제공한다. 이는 특정 상황에서 어떤 방법으로 객체를 생성해야할지를 결정하는데 있어서 유연성을 제공한다. 


 Structural Patterns ( 구조적 패턴 )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

구조적 패턴들은 클래스와 객체의 구성에 관여한다.

 

 Behavioral Patterns ( 행위적 패턴 )

These design patterns are specifically concerned with communication between objects.

이 패턴들은 객체들 사이의 커뮤니케이션에 관심을 가진다.

 

오늘 살펴볼  Chain of Responsibility (책임 전가 )패턴은 Behavioral 패턴에 속한다.  

책임 전가란 뭐냐? 책임을 다른 놈한테 넘긴다는 말이다. 그게 무슨 말이냐고?

제 조업을 하는 공장을 예로 들어보겠습니다. 이 공장은 자동차를 만듭니다. 자동차를 만드는 과정은 내부에서부터 차근 차근 조립해 나가는 거죠. 차체 바닥을 깔고 그 위에 의자를 올리고 엔진을 끼워넣고 이런식으로 부품(책임)을 계속 조립해 넣습니다. 그러다가 마지막에 완성된 차가 나오게 되는거죠.  

이 글을 읽고있는 독자께서는 맡은 부분이 있겠죠. 예를 들면 바퀴를 끼워넣는 일을 해야한다고 합시다. 그러면 독자님은 그냥 바퀴만 끼우고 나머지는 옆사람한테 넘기면 되는 겁니다. 간단히 말하면 이런 맥락입니다.이해가 되시나요?  

 

Chain of Responsibility Pattern Structure

 

 

A typical object structure might look like this:

일반적인 객체 구조는 아래와 비슷합니다.


         

패턴의 목적 ( Intent ) :  

Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

이 패턴의 목적은 말이죠, A라는 객체가 요청1을 B객체에 보낼 때 중간에서 이 요청을 핸들링 할 다른 객체들을 두어서 A 와 B 사이의 커플링 관계를 피하기 위함입니다. A 와 B 사이의 각 핸들러들은 자신이 처리할 수 있으면 처리를 하고 처리할 수 없으면 다음 핸들러로 요청을 넘기게 됩니다.


패턴이 나오게 된 동기 ( Motivation ) :

 GoF 의 디자인패턴에서는 애플리케이션에 있는 도움말기능을 예로 듭니다. 도움말( 일반적으로 물음표 )은 컨텍스트별로 다르게 됩니다. 쉽게말하자면 메뉴별로 어떤 메뉴인지에 대한 도움말이 있을 수도 있고 버튼마다 어떤 기능을 실행하는지에 대해서 도움말이 존재하겠죠. 그런데 도움말을 실행할 때 이게 어떤 녀석이 도움말에 대한 정보를 처리해야하는지에 대한 정보는 도움말을 요청하는 객체가 모른다는게 문제라고 합니다. 누가 처리해야하는지도 모르는 것을 어떻게 처리해야하나 고민하다가 나온 패턴이바로 이 책임전가 패턴입니다. 도움말객체가 "A에 대한 도움말 주세요" 라고 chain에 요청을 합니다. 여기서 체인은 핸들러들이 순서대로 연결되어있는 곳입니다. 이 핸들러들 중에서 한놈은 A에 대한 도움말을 주도록 되어있고 또 다른 놈은 B에 대한 도움말을 주도록 되어있는 거죠. 그래서 체인의 시작점으로 요청을 날리면 A에 대한 도움말을 반환하는 핸들러가 나올때까지 옆의 핸들러로 계속 전달합니다. 그러다가 요청을 처리할 수 있는 핸들러를 만나면 요청을 처리하고 결과를 반환하는 거죠. 여기서 중요한 것은 이 체인의 가장 첫 핸들러는 가장 specific한 놈이어야 하고 체인의 제일 끝에 있는 핸들러는 가장 일반적인(공통적인) 놈이어야 한다는 것입니다. 그래서 결국 도움말을 찾지 못하면 일반적인 도움말을 그냥 내보내도록 하는 것이죠. 

 

 

 

유용성 ( Applicability ) :

 

Use Chain of Responsibility when  

책임 전가 패턴은 이럴때 사용하면 됩니다.

    • more than one object may handle a request, and the handler isn't known a priority. The handler should be ascertained automatically. 하나 이상의 객체가 요청을 처리해야 할 때. 그리고 핸들러의 우선순위가 없을 때. 핸들러는 자동적으로 선택되어져야 한다.
       

    • you want to issue a request to one of several objects without specifying the receiver explicitly.
      리시버를 명시하지 않고 여러 객체들 중 하나에 요청을 날리고 싶을 때 

    • the set of objects that can handle a request should be specified dynamically.
      요청을 처리할 수 있는 객체들의 set이 동적으로 지정되어야 할 때 


등장 인물 ( Participants ) :


Handler (HelpHandler)

o defines an interface for handling requests. 요청을 처리하기 위한 인터페이스를 정의한다. 

o (optional) implements the successor link.(선택) successor 링크를 구현한다. 

• ConcreteHandler (PrintButton, PrintDialog)

o handles requests it is responsible for. 책임져야할 부분에 대해서만 요청을 처리한다.
o can access its successor. successor에 접근할 수 있다.
o if the ConcreteHandler can handle the request,it does so; otherwise it forwards the request to its successor.
ConcreteHandler가 처리할 수 있는 요청은 처리를 하지만 그렇지 않은 경우 successor로 요청을 포워딩한다. 

Client

o initiates the request to a ConcreteHandler object on the chain.
체인에 속한 ConcreteHandler 객체로 요청을 날린다. 


원리 ( Collaborations ) :

 

When a client issues a request, the request propagates along the chain until a ConcreteHandler object takes responsibility for handling it.
클라이언트가 요청을 날리면, 그 요청을 처리할 수 있는 ConcreteHandler가 요청을 받고 처리를 할 때 까지 체인을 타고 다른 핸들러로 요청( 핸들러 입장에서는 처리해야할 책임이라고 보면 됩니다 )이 이동합니다. 

 


패턴 사용의 장단점 ( Consequences ): 

 

Chain of Responsibility has the following benefits and liabilities:  


1. Reduced coupling.The pattern frees an object from knowing which other object handles a request. An object only has to know that a request will be handled "appropriately." Both the receiver and the sender have no explicit knowledge of each other, and an object in the chain doesn't have to know about the chain's structure.

As a result, Chain of Responsibility can simplify object inter connections. Instead of objects maintaining references to all candidate receivers, they keep a single reference to their successor.
책임 전가 패턴을 사용하면 커플링을 줄일 수 있습니다. 각 핸들러는 체인의 구조를 알 필요도 없고 단지 다음 핸들러에 대한 reference만 가지고 있다가 요청이 들어왔을 때 자신이 해결 할 수 없는 일이면 다음 핸들러로 요청을 넘기는 일만 하면 되는 것이죠.  

 

2. Added flexibility in assigning responsibilities to objects. Chain of Responsibility gives you added flexibility in distributing responsibilities among objects. You can add or change responsibilities for handling a request by adding to or otherwise changing the chain at run-time. You can combine this with subclassing to specialize handlers statically.  


3. Receipt isn't guaranteed. Since a request has no explicit receiver, there's no guarantee it'll be handledthe request can fall off the end of the chainwithout ever being handled. A request can also go unhandled when thechain is not configured properly.

 

관련 패턴들 : 

 

Chain of Responsibility is often applied in conjunction with Composite. There, a component's parent can act as its successor.책임 전가 패턴은 종종 컴포지트 패턴과 함께 쓰입니다.

 

추가 정보 :   

    • Chain of Responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs. Chain of Responsibility passes a sender request along a chain of potential receivers. 책임전가, 커맨드, 중재자, 관찰자 패턴은 모두 sender와 receiver사이의 커플링을 줄여주지만 각기 다른 방식을 사용하므로, 디커플링 함으로써 들어가야 하는 비용(단점) 또한 다릅니다.
    • Chain of Responsibility can use Command to represent requests as objects.

 


 

출처 :  http://sourcemaking.com/design_patterns/chain_of_responsibility

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )  


 Creational Patterns ( 생성 패턴 )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

생성패턴은 객체의 생성로직을 숨기고 new 명령어를 통하지 않고 객체를 생성하는 방법들을 제공한다. 이는 특정 상황에서 어떤 방법으로 객체를 생성해야할지를 결정하는데 있어서 유연성을 제공한다. 


 Structural Patterns ( 구조적 패턴 )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

구조적 패턴들은 클래스와 객체의 구성에 관여한다.

 

 Behavioral Patterns ( 행위적 패턴 )

These design patterns are specifically concerned with communication between objects.

이 패턴들은 객체들 사이의 커뮤니케이션에 관심을 가진다.

 

오늘 살펴볼  Visitor 패턴은 Behavioral 패턴에 속한다.  

 


 

Visitor Pattern Structure

 


 


패턴의 목적 ( Intent ) : 

Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

 

 

패턴이 나오게 된 동기 ( Motivation ) :

Consider a compiler that represents programs as abstract syntax trees. It will need to perform operations on abstract syntax trees for "static semantic" analyses like checking that all variables are defined. Itwill also need to generate code. So it might define operations for type-checking, code optimization, flow analysis, checking for variables being assigned values before they're used, and so on.
Moreover, we could use the abstract syntax trees for pretty-printing, program restructuring, code instrumentation, and computing various metrics of aprogram.
Most of these operations will need to treat nodes that represent assignment statements differently from nodes that represent variables orarithmetic expressions. Hence there will be one class for assignment statements, another for variable accesses, another for arithmetic expressions, and so on. The set of node classes depends on the language being compiled, of course, but it doesn't change much for a given language.


 


 This diagram shows part of the Node class hierarchy. The problem here is that distributing all these operations across the various node classes leads to a system that's hard to understand, maintain, and change. It will be confusing to have type-checking code mixed with pretty-printing code or flow analysis code. Moreover, adding a new operation usually requires recompiling all of these classes. It would be better if each new operation could be added separately, and the node classes were independent of the operations that apply to them.
We can have both by packaging related operations from each class in a separate object, called a visitor, and passing it to elements of the abstract syntax tree as it's traversed. When an  element "accepts" the visitor, it sends a request to the visitor that encodes the element's class. It also includes the element as an argument. The visitor will then execute the operation for that element —the operation that used to be in the class of the element.

 

For example, a compiler that didn't use visitors might type-check a procedure by calling the TypeCheck operation on its abstract syntax tree. Each of the nodes would implement TypeCheck by calling TypeCheck on its components (see the preceding class diagram). If the compiler type-checked a procedure using visitors, then it would create a TypeCheckingVisitor object and call the Accept operation on the abstract syntax tree with that object as an argument. Each of the nodes would implement Accept by calling back on the visitor: anassignment node calls
VisitAssignment operation on the visitor, while a variable reference calls VisitVariableReference. What used to be the TypeCheck operation in class AssignmentNode is now the VisitAssignment operation on TypeCheckingVisitor.  

To make visitors work for more than just type-checking, we need an abstract parent class NodeVisitor for all visitors of an abstract syntax tree. NodeVisitor must declare an operation for each node class. An application that needs to compute program metrics will define new subclasses of NodeVisitor and will no longer need to add application-specific code to the node classes. The Visitor pattern encapsulates the operations for each compilation phase in a Visitor associated with that phase.

 





  

With the Visitor pattern, you define two class hierarchies: one for the elements being operated on (the Node hierarchy) and one for the visitors that define operations on the elements (the  NodeVisitor hierarchy). You create a new operation by adding a new subclass to the visitor class hierarchy. As long as the grammar that the compiler accepts doesn't change (that is, we don't have to add new Node subclasses), we can add new functionality simply by defining new NodeVisitor subclasses.

 

 

유용성 ( Applicability ) :

Use the Visitor pattern when

Visitor 패턴은 이럴때 사용하자!!


· an object structure contains many classes of objects with differing interfaces, and you want to  perform operations on these objects that depend on their concrete classes.
· many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by defining them in one class. When the object structure is shared by many applications, use Visitor to put operations in just those applications that need them.
· the classes defining the object structure rarely change, but you often want to define new operations over the structure. Changing the object structure classes requires redefining the interface to all visitors,which is potentially costly. If the object structure classes change often, then it's probably better to define the operations in those classes.

 

 

등장 인물 ( Participants ) :
· Visitor (NodeVisitor)
o declares a Visit operation for each class of ConcreteElement in the object structure. The operation's name and signature identifies the class that sends the Visit request to the visitor. That lets the visitor determine the concrete class of the element being visited. Then the visitor can access the element directly through its particular interface.


· ConcreteVisitor (TypeCheckingVisitor)
o implements each operation declared by Visitor. Each operation implements a fragment of the algorithm defined for the corresponding class of object in the structure. ConcreteVisitor provides the context for the algorithm and stores its local state. This state often accumulates results during the traversal of the structure.


· Element (Node)
o defines an Accept operation that takes a visitor as an argument.


· ConcreteElement (AssignmentNode,VariableRefNode)
o implements an Accept operation that takes a visitor as an argument.


· ObjectStructure (Program)
o can enumerate its elements.
o may provide a high-level interface to allow the visitor to visit its elements.
o may either be a composite (see Composite ) or a collection such as a list or a set.

 

원리 ( Collaborations ) :

· A client that uses the Visitor pattern must create a ConcreteVisitor object and then traverse the object structure, visiting each element with the visitor.
· When an element is visited, it calls the Visitor operation that corresponds to its class. The element supplies itself as an argument to this operation to let the visitor access its state, if necessary.
The following interaction diagram illustrates the collaborations between an object structure, a visitor, and two elements:





패턴 사용의 장단점 ( Consequences ): 


Some of the benefits and liabilities of the Visitor pattern are as follows:


1. Visitor makes adding new operations easy. Visitors make it easy to add operations that depend on the components ofcomplex objects. You can define a new operation over an object  structure simply by adding a new visitor.
In contrast, if you spread functionality over many classes, then you must change each class to  define a newoperation.

2. A visitor gathers related operations and separates unrelated ones. Related behavior isn't spread over the classes defining the object structure; it's localized in a visitor. Unrelated sets of behavior are partitioned in their own visitor subclasses. That simplifies both the classes defining the elements and the algorithms defined in the visitors. Any algorithm-specific
data structures can be hidden in thevisitor.


3. Adding new ConcreteElement classes is hard. The Visitor pattern makes it hard to add new subclasses of Element. Each new ConcreteElement gives rise to a new abstract operation on Visitor and a corresponding implementation in every ConcreteVisitor class. Sometimes a default implementation can be provided in Visitor that can be inherited by most of the ConcreteVisitors, but this is the exception rather than the rule. So the key consideration in applying the Visitor pattern is whether you are mostly likely to change the algorithm applied over an object structure or the classes of objects that make up the structure. TheVisitor class hierarchy can be difficult to maintain when new ConcreteElement classes are added frequently. In such cases, it's probably easier just to define operations on the classes that make up the structure. If the Element class hierarchy is stable, but you are continually adding operations or changing algorithms, then the Visitor pattern will help you manage the changes.


4. Visiting across class hierarchies. An iterator (see Iterator ) can visit the objects in a structure as it traverses them by calling their operations. But an iterator can't work across object structures with different types of elements.  


5. Accumulating state. Visitors can accumulate state as they visit each element in the object structure. Without a visitor, this state would be passed as extra arguments to the operations that perform the traversal, or they might appear as global variables.


6. Breaking encapsulation. Visitor's approach assumes that the ConcreteElement interface is powerful enough to let visitors do their job.
As a result, the pattern oftenforces you to provide public operations that
access an element's internal state, which may compromise its encapsulation.


관련 패턴들 : 

Composite :Visitors can be used to apply an operation over an object structure defined by the Composite pattern.
Interpreter
:Visitor may be applied to do the interpretation.

 

추가 정보 :     

  • The abstract syntax tree of Interpreter is a Composite (therefore Iterator and Visitor are also applicable).
  • Iterator can traverse a Composite. Visitor can apply an operation over a Composite.
  • The Visitor pattern is like a more powerful Command pattern because the visitor may initiate whatever is appropriate for the kind of object it encounters.
  • The Visitor pattern is the classic technique for recovering lost type information without resorting to dynamic casts.

 

 

 

출처 : http://sourcemaking.com/design_patterns/visitor

         Design Patterns : Element of Reusab

Creational Patterns ( 생성 패턴 )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

생성패턴은 객체의 생성로직을 숨기고 new 명령어를 통하지 않고 객체를 생성하는 방법들을 제공한다. 이는 특정 상황에서 어떤 방법으로 객체를 생성해야할지를 결정하는데 있어서 유연성을 제공한다. 


 Structural Patterns ( 구조적 패턴 )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

구조적 패턴들은 클래스와 객체의 구성에 관여한다.

 

 Behavioral Patterns ( 행위적 패턴 )

These design patterns are specifically concerned with communication between objects.

이 패턴들은 객체들 사이의 커뮤니케이션에 관심을 가진다.

 

오늘 살펴볼  Builder 패턴은 Creational 패턴에 속한다.   


빌더 패턴은 팩토리 메소드 또는 추상 팩토리 패턴의 문제점을 해결하기 위해 나온 패턴이다. 팩토리 메소드 또는 추상 팩토리 패턴에는 객체가 많은 속성을 가지고 있을 경우 두가지 중요한 문제가 발생한다. 

 

첫 째로, 클라이언트가 팩토리 클래스로 넘겨주는 인자가 많아지게되면( 팩토리가 많은 속성을 가지고 있으면 이에 대해 설정을 하기위해 많은 인자를 받아야 한다 ) 잘못된 인자를 넘겨주는 일도 빈번하게 일어날 뿐 아니라 관리하기도 힘들어진다.

둘째로, 몇몇 인자들은 optional일 수 있지만 팩토리 패턴에서는 모든 인자를 넘겨주어야 한다. ( optional 인자는 null로 넘긴다. 이건 귀찮은 일이다. )

 

빌더 패턴은 단계별로 객체를 생성하고 마지막 객체를 반환하는 메소드를 제공함으로써 위와 같은 문제들을 해결해준다. 


 

Builder Pattern Structure



 


패턴의 목적 ( Intent ) : 

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴


패턴이 나오게 된 동기 ( Motivation ) :


 

예 를들어 RTF포맷 형태의 파일을 ASCIIText나 TeXText 또는 다른 TextWidget의 형태로 변환하는 프로그램을 만든다고 하자. 이때 변환되어 나오는 포맷을 쉽게 추가할 수 있어야 할 것이다. 그래서 나온 패턴이 바로 이 빌더 패턴이다. 위 다이어그램에서 각각의 컨버터 클래스들은 모두 builder이며 reader는 director라 한다. 그리고 변형되어 나오는 Text객체들은 product라고 보면 된다. 

 


유용성 ( Applicability ) :

Use the Builder pattern when
· the algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled.
· the construction process must allow different representations for the object that's constructed.

 

등장 인물 ( Participants ) : 

· Builder
o specifies an abstract interface for creating parts of a Product object.
· ConcreteBuilder
o constructs and assembles parts of the product by implementing the Builder interface.
o defines and keeps track of the representation it creates.
o provides an interface for retrieving the product.
· Director
o constructs an object using the Builder interface.
· Product
o represents the complex object under construction. ConcreteBuilder builds the product's internal representation and defines the process by which it's assembled.
o includes classes that define the constituent parts, including interfaces for assembling the parts into the final result.


원리 ( Collaborations ) :

· The client creates the Director object and configures it with the desired Builder object.
· Director notifies the builder whenever a part of the product should be built.
· Builder handles requests from the director and adds parts to the product.
· The client retrieves the product from the builder.

 

The following interaction diagram illustrates how Builder and Director cooperate with a client.

 

 


패턴 사용의 장단점 ( Consequences ): 

Here are key consequences of the Builder pattern:


1. It lets you vary a product's internal representation. The Builder object provides the director with an abstract interface for constructing the product. The interface lets the builder hide the representation and internal structure of the product. It also hides how the product gets assembled. Because the product is constructed through an abstract interface, all you have to do to change the product's internal representation is define a new kind of builder.


2. It isolates code for construction and representation. The Builder pattern improves modularity by encapsulating the way a complex object is constructed and represented. Clients needn't know anything about the classes that define the product's internal structure; such classes don't appear in Builder's interface. Each ConcreteBuilder contains all the code to create and assemble a particular kind of product. The code is written once; then different Directors can reuse it to build Product variants from the same set of parts.
In the earlier RTF example, we could define a reader for a format other than RTF, say, an SGMLReader, and use the same TextConverters to generate ASCIIText, TeXText, and TextWidget renditions of SGML documents.


3. It gives you finer control over the construction process. Unlike creational patterns that construct products in one shot, the Builder pattern constructs the product step by step under the director's control. Only when the product is finished does the director retrieve it from the builder. Hence the Builder interface reflects the process of constructing the product more than other creational patterns. This gives you finer control over the construction process and consequently the internal structure of the resulting product. 

 

관련 패턴들 : 

 Abstract Factory is similar to Builder in that it ​constructs too may complex objects. The primary difference is that the Builder pattern focuses on constructing a complex object step by step. Abstract Factory's emphasis is on families of product objects (either simple or complex). Builder returns the product as a final step, but as far as the Abstract Factory pattern is concerned, the product gets returned immediately.
A Composite is what the builder often builds.

 

추가 정보 :     

  • Sometimes creational patterns are complementory: Builder can use one of the other patterns to implement which components get built. Abstract Factory, Builder, and Prototype can use Singleton in their implementations.
  • Builder focuses on constructing a complex object step by step. Abstract Factory emphasizes a family of product objects (either simple or complex). Builder returns the product as a final step, but as far as the Abstract Factory is concerned, the product gets returned immediately.
  • Builder often builds a Composite.
  • Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed.

 

 

출처 :  http://sourcemaking.com/design_patterns/builder

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )  

http://www.journaldev.com/1425/builder-design-pattern-in-java

 


Creational Patterns ( 생성 패턴 )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

생성패턴은 객체의 생성로직을 숨기고 new 명령어를 통하지 않고 객체를 생성하는 방법들을 제공한다. 이는 특정 상황에서 어떤 방법으로 객체를 생성해야할지를 결정하는데 있어서 유연성을 제공한다. 


 Structural Patterns ( 구조적 패턴 )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

구조적 패턴들은 클래스와 객체의 구성에 관여한다.

 

 Behavioral Patterns ( 행위적 패턴 )

These design patterns are specifically concerned with communication between objects.

이 패턴들은 객체들 사이의 커뮤니케이션에 관심을 가진다.

 

오늘 살펴볼  Flyweight 패턴은 Structural 패턴에 속한다.  

 

이 패턴을 적용해야 하는 상황은 아래와 같다.

1. 애플리케이션에서 생성되는 객체의 수가 엄청나게 클 때

2. 객체의 생성이 메모리에 많은 부하를 주고 시간이 오래 걸릴 때


좀 더 자세히 이 패턴에 대해서 짚어보자.

 

Flyweight Pattern Structure

  


 
The following object diagram shows how flyweights are shared:

 

 


패턴의 목적 ( Intent ) : 

Use sharing to support large numbers of fine-grained objects efficiently.

플라이웨이트 패턴은 많은 수의 객체를 효율적으로 제공하기위해 공유개념을 이용한다.  

 

패턴이 나오게 된 동기 ( Motivation ) :

 Flyweight 패턴은 동일한 클래스에 대한 많은 객체를 생성해야 할 때 사용될 수 있다. 각 객체마다 메모리와 공간을 잡아먹기 때문에 사양이 낮은 컴퓨터나 모바일 기기에서는 메모리와 공간에 대한 제약을 피할 수 없는데 만약 내가 만드는 프로그램이 엄청 많은 객체를 생성한다면 이 패턴을 공부해서 적용해보기 바란다. 플라이웨이트 패턴은 객체를 공유함으로써 메모리 부하를 줄일 수 있기 때문이다. 


유용성 ( Applicability ) :

The Flyweight pattern's effectiveness depends heavily on how and where it's used.

플라이웨이트 패턴의 효과는 어떻게 어디서 사용되느냐에 따라 심하게 좌지우지 된다.


Apply the Flyweight pattern when all of the following are true:

아래 내용과 모두 맞아 떨어지는 상황에서만 이 패턴을 적용하면 된다.


· An application uses a large number of objects.

애플리케이션이 정말 많은 객체를 사용할 때
· Storage costs are high because of the sheer quantity of objects.

저장비용이 높을 때( 객체 개수가 많아서 )
· Most object state can be made extrinsic.

대부분의 객체의 상태가 부대적인 것일 때
· Many groups of objects may be replaced by relatively few shared objects once extrinsic state is removed.

부대적인 상태가 제거됐을 때에는 적은 수의 공유 객체로 많은 수의 객체를 대체할 수 있을 때
· The application doesn't depend on object identity. Since flyweight objects may be shared, identity tests will return true for conceptually distinct objects.

애플리케이션이 객체의 identity에 의존적이지 않을 때 


등장 인물 ( Participants ) :

· Flyweight
o declares an interface through which flyweights can receive and act
on extrinsic state.
· ConcreteFlyweight (Character)
o implements the Flyweight interface and adds storage for intrinsic state, if any. A ConcreteFlyweight object must be sharable. Any state it stores must be intrinsic; that is, it must be independent of the ConcreteFlyweight object's context.
· UnsharedConcreteFlyweight (Row, Column)
o not all Flyweight subclasses need to be shared. The Flyweight interface enables sharing; it doesn't enforce it. It's common for
UnsharedConcreteFlyweight objects to have ConcreteFlyweight objects as children at some level in the flyweight object structure
(as the Row and Column classes have).
· FlyweightFactory
o creates and manages flyweight objects.
o ensures that flyweights are shared properly. When a client requests a flyweight, the FlyweightFactory object supplies an existing
instance or creates one, if none exists.  

· Client
o maintains a reference to flyweight(s).
o computes or stores the extrinsic state of flyweight(s).


원리 ( Collaborations ) :

· State that a flyweight needs to function must be characterized as either intrinsic or extrinsic. Intrinsic state is stored in the ConcreteFlyweight object; extrinsic state is stored or computed by Client objects. Clients pass this state to the flyweight when they invoke its operations.
· Clients should not instantiate ConcreteFlyweights directly. Clients must obtain ConcreteFlyweight objects exclusively from the FlyweightFactory object to ensure they are shared properly.


패턴 사용의 장단점 ( Consequences ): 

 
Flyweights may introduce run-time costs associated with transferring, finding, and/or computing extrinsic state, especially if it was formerly stored as intrinsic state. However, such costs are offset by space savings, which increase as more
flyweights are shared.


Storage savings are a function of several factors:


· the reduction in the total number of instances that comes from sharing
· the amount of intrinsic state per object
· whether extrinsic state is computed or stored.


The more flyweights are shared, the greater the storage savings. The savings increase with the amount of shared state. The greatest savings occur when the objects use substantial quantities of both intrinsic and extrinsic state, and the extrinsic state can be computed rather than stored. Then you save on storage in two ways: Sharing reduces the cost of intrinsic state, and you trade extrinsic state for computation time.
The Flyweight pattern is often combined with the Composite (183) pattern to represent a hierarchical structure as a graph with shared leaf nodes. A consequence of sharing is that flyweight leaf nodes cannot store a pointer to their parent. Rather, the parent pointer is passed to the flyweight as part of its extrinsic state. This has a major impact on how the objects in the hierarchy  communicate with each other. 

 

관련 패턴들 : 

The Flyweight pattern is often combined with the Composite pattern to implement a logically hierarchical structure in terms of a directed-acyclic graph with shared leaf nodes.

It's often best to implement State and Strategy objects as flyweights. 


추가 정보 :   

  • Whereas Flyweight shows how to make lots of little objects, Facade shows how to make a single object represent an entire subsystem.
  • Flyweight is often combined with Composite to implement shared leaf nodes.
  • Terminal symbols within Interpreter's abstract syntax tree can be shared with Flyweight.
  • Flyweight explains when and how State objects can be shared.
  • Flyweight pattern introduces complexity and if number of shared objects are huge then there is a trade of between memory and time, so we need to use it judiciously based on our requirements.
  • Flyweight pattern implementation is not useful when the number of intrinsic properties of Object is huge, making implementation of Factory class complex.

 

 

 

출처 :  http://sourcemaking.com/design_patterns/flyweight

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )  

http://www.journaldev.com/1562/flyweight-pattern-in-java-example-tutorial

 


 Creational Patterns ( 생성 패턴 )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

생성패턴은 객체의 생성로직을 숨기고 new 명령어를 통하지 않고 객체를 생성하는 방법들을 제공한다. 이는 특정 상황에서 어떤 방법으로 객체를 생성해야할지를 결정하는데 있어서 유연성을 제공한다. 


 Structural Patterns ( 구조적 패턴 )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

구조적 패턴들은 클래스와 객체의 구성에 관여한다.

 

 Behavioral Patterns ( 행위적 패턴 )

These design patterns are specifically concerned with communication between objects.

이 패턴들은 객체들 사이의 커뮤니케이션에 관심을 가진다.

 

오늘 살펴볼  Singleton 패턴은 Creational 패턴에 속한다.  

 

Singleton Pattern Structure


 

패턴의 목적 ( Intent ) : 

Ensure a class only has one instance, and provide a global point of access to it.

프로그램상에서 단 하나의 인스턴스만을 요구하는 클래스를 만들 필요가 있어서 나온 패턴이다. global하게 access가능한 단 인스턴스 생성이 이 패턴의 목적이다. 

 

패턴이 나오게 된 동기 ( Motivation ) :

Application needs one, and only one, instance of an object. Additionally, lazy initialization and global access are necessary.

목적에서 말한 바와 같이 단 하나의 유일한 객체를 생성하고 이를 사용할 목적으로 나오게 된 패턴이다. 한번 생성하면 그 이후에는 생성된 객체를 이용만 할 뿐이다. 


유용성 ( Applicability ) :

Use the Singleton pattern when
· there must be exactly one instance of a class, and it must be accessible to clients from a well-known access point.
· when the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code.

 

등장 인물 ( Participants ) :

· Singleton
o defines an Instance operation that lets clients access its unique instance. Instance is a class operation (that is, a class method in Smalltalk and a static member function in C++).
o may be responsible for creating its own unique instance.


원리 ( Collaborations ) :

· Clients access a Singleton instance solely through Singleton's Instance operation.

클라이언트들은 이 싱글턴객체에서 제공하는  getter메소드에 의해 오직 혼자만 접근한다.


패턴 사용의 장단점 ( Consequences ): 

The Singleton pattern has several benefits:
1. Controlled access to sole instance. Because the Singleton class encapsulates its sole instance, it can have strict control over how and when clients access it.
2. Reduced name space. The Singleton pattern is an improvement over global variables. It avoids polluting the name space with global variables that store sole instances.
3. Permits refinement of operations and representation. The Singleton class may be subclassed, and it's easy to configure an application with an instance of this extended class. You can configure the application with an instance of the class you need at run-time.
4. Permits a variable number of instances. The pattern makes it easy to change your mind and allow more than one instance of the Singleton class. Moreover, you can use the same approach to control the number of instances that the application uses. Only the operation that grants access to the Singleton instance needs to change.
5. More flexible than class operations. Another way to package a singleton's functionality is to use class operations (that is, static member functions in C++ or class methods in Smalltalk). But both of these language techniques make it hard to change a design to allow more than one instance of a class. Moreover, static member functions in C++ are never virtual, so subclasses can't override them polymorphically.

 

소스 예제 : 


1. 일반적인 경우 ( synchronizing할 필요가 없는 싱글턴 객체의 경우, 싱글쓰레드(single thread) )

 

// 싱글턴객체가 필요할 때는 인스턴스를 직접 만드는게 아니고 인스턴스를 달라고 요청을 하는 것이다.
public class Singleton {
  private static Singleton uniqueInstance;
 
  private Singleton() {}  // <---  생성자는 private -- 외부에서 new 를 사용하여 객체를 생성할 수 없다...
 
  public static Singleton getInstance() {  // 객체를 생성하는 static 메소드 하나
    if ( uniqueInstance == null ) {        // 이 부분은 객체를 처음 생성할 때만 필요하다~~
      uniqueInstance = new Singleton();
    }
    return uniqueInstance;
  }
}

2. 여러명이 동시접근할 수도 있는
싱글턴 객체의 경우 ( 멀티쓰레드, multi thread )

A. 위 코드의 문제점 )
public class Singleton {
  private static Singleton uniqueInstance;
 
  private Singleton() {}
 
  public static Singleton getInstance() {  
    if ( uniqueInstance == null ) {          // A Thread가 이 코드를 실행할 때
      uniqueInstance = new Singleton();      // B Thread가 객체 생성을 완료하지 않은 경우 
    }                                        // 두개의 객체가 생성될 수 있다.
 
    return uniqueInstance;
  }
}

B.Method synchronizing 으로 문제 해결 가능 

 

public class Singleton {
  private static Singleton uniqueInstance;
 
  private Singleton() {}

  // 메소드 자체에 synchronized 를 거는 방법 
  public static synchronized Singleton getInstance() {  
    if ( uniqueInstance == null ) {          
      uniqueInstance = new Singleton(); 
    }                                        
 
    return uniqueInstance;
  }
}

이 방법의 문제점 )
  • 이 방법은 성능에 영향을 끼칠 수 있다.
    ( 메소드를 동기화하면 성능이 100배 정도 저하된다고 책에 적혀있습니다. )
  • synchronized가 필요한 경우는 객체가 생성되는 처음 뿐이고 그 이후에는 쓸데없이 성능을 저하시키는 요인이다.

C. Double-checking Locking

public class Singleton { private volatile static Singleton uniqueInstance; private Singleton() {} // 부분적으로 synchronized를 걸어 객체가 생성된 이후에는 synchronized 구문을 수행하지 않는다. public static Singleton getInstance() { if ( uniqueInstance == null ) { synchronized( Singleton.class ) { if ( uniqueInstance == null ) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } }

관련 패턴들 : 

 Many patterns can be implemented using the Singleton pattern. See Abstract Factory, Builder, and Prototype.

 

추가 정보 :     

  • Abstract Factory, Builder, and Prototype can use Singleton in their implementation.
  • Facade objects are often Singletons because only one Facade object is required.
  • State objects are often Singletons.
  • The advantage of Singleton over global variables is that you are absolutely sure of the number of instances when you use Singleton, and, you can change your mind and manage any number of instances.
  • The Singleton design pattern is one of the most inappropriately used patterns. Singletons are intended to be used when a class must have exactly one instance, no more, no less. Designers frequently use Singletons in a misguided attempt to replace global variables. A Singleton is, for intents and purposes, a global variable. The Singleton does not do away with the global; it merely renames it.
    싱글턴 패턴은 가장 부적절하게 사용되는 패턴중 하나이다. 원래 싱글턴 패턴의 목적은 더도말고 덜도말고 오로지 단 하나의 인스턴스를 갖기 위함이었으나 일부 개발자들은 단순히 전역변수를 대체하기위해 사용할 때가 있다.
  • When is Singleton unnecessary? Short answer: most of the time. Long answer: when it's simpler to pass an object resource as a reference to the objects that need it, rather than letting objects access the resource globally. The real problem with Singletons is that they give you such a good excuse not to think carefully about the appropriate visibility of an object. Finding the right balance of exposure and protection for an object is critical for maintaining flexibility.
  • Our group had a bad habit of using global data, so I did a study group on Singleton. The next thing I know Singletons appeared everywhere and none of the problems related to global data went away. The answer to the global data question is not, "Make it a Singleton." The answer is, "Why in the hell are you using global data?" Changing the name doesn't change the problem. In fact, it may make it worse because it gives you the opportunity to say, "Well I'm not doing that, I'm doing this" – even though this and that are the same thing.

 

 

 

출처 :  http://sourcemaking.com/design_patterns/singleton

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 ) 

http://www.javajigi.net/display/SWD/ch05_singletonpattern

Creational Patterns ( 생성 패턴 )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

생성패턴은 객체의 생성로직을 숨기고 new 명령어를 통하지 않고 객체를 생성하는 방법들을 제공한다. 이는 특정 상황에서 어떤 방법으로 객체를 생성해야할지를 결정하는데 있어서 유연성을 제공한다. 


 Structural Patterns ( 구조적 패턴 )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

구조적 패턴들은 클래스와 객체의 구성에 관여한다.

 

 Behavioral Patterns ( 행위적 패턴 )

These design patterns are specifically concerned with communication between objects.

이 패턴들은 객체들 사이의 커뮤니케이션에 관심을 가진다.

 

오늘 살펴볼  Prototype 패턴은 Creational 패턴에 속한다.  

 

Prototype Pattern Structure



패턴의 목적 ( Intent ) : 

- Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. 

하나의 프로토타입 인스턴스를 만들고 필요할때마다 프로토타입 인스턴스를 복사해서 객체를 생성하기 위함 

- Co-opt one instance of a class for use as a breeder of all future instances. 

- The new operator considered harmful.

new 키워드를 이용하는 것이 안좋은 상황일 때 프로토타입 패턴을 이용하자. 

 

패턴이 나오게 된 동기 ( Motivation ) :

 

객체 생성 비용이 비싼경우 프로토타입 원형을 만들고 클로닝 기법을 이용해서 객체를 쉽게 생성하고자 하기 위함.


유용성 ( Applicability ) :

Use the Prototype pattern when a system should be independent of how its products are created, composed, and represented; and
· when the classes to instantiate are specified at run-time, for example, by dynamic loading; or

클래스의 동적로딩이 필요할 때
· to avoid building a class hierarchy of factories that parallels the class hierarchy of products; or

제품의 클래스 계층과 동일한 팩토리 클래스 계층을 만들고 싶지 않을 때
· when instances of a class can have one of only a few different combinations of state. It may be more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually, each time with the appropriate state.

 

등장 인물 ( Participants ) :

· Prototype
o declares an interface for cloning itself.
· ConcretePrototype
o implements an operation for cloning itself.
· Client
o creates a new object by asking a prototype to clone itself. 


원리 ( Collaborations ) :

· A client asks a prototype to clone itself.


패턴 사용의 장단점 ( Consequences ): 

Prototype has many of the same consequences that Abstract Factory and Builder have: It hides the concrete product classes from the client, thereby reducing the number of names clients know about. Moreover, these patterns let a client work with application-specific classes without modification.


Additional benefits of the Prototype pattern are listed below.


1. Adding and removing products at run-time. Prototypes let you incorporate a new concrete product class into a system simply by registering a prototypical instance with the client. That's a bit more flexible than other creational patterns, because a client can install and remove prototypes at run-time.


2. Specifying new objects by varying values. Highly dynamic systems let you define new behavior through object composition—by specifying values for an object's variables, for example—and not by defining new classes. You effectively define new kinds of objects by instantiating existing classes and registering the instances as prototypes of client objects. A client can exhibit new behavior by delegating responsibility to the prototype. This kind of design lets users define new "classes" without programming. In fact, cloning a prototype is similar to instantiating a class. The Prototype pattern can greatly reduce the number of classes a system needs. In our music editor, one GraphicTool class can create a limitless variety of music objects.


3. Specifying new objects by varying structure. Many applications build objects from parts and subparts. Editors for circuit design, for example, build circuits out of subcircuits.1 For convenience, such applications often let you instantiate complex, user-defined structures, say, to use a specific subcircuit again and again. The Prototype pattern supports this as well. We simply add this subcircuit as a prototype to the palette of available circuit elements. As long as the composite circuit object implements Clone as a deep copy, circuits with different structures can be prototypes.  

 

4. Reduced subclassing. Factory Method often produces a hierarchy of Creator classes that parallels the product class hierarchy. The Prototype pattern lets you clone a prototype instead of asking a factory method to make a new object. Hence you don't need a Creator class hierarchy at all. This benefit applies primarily to languages like C++ that don't treat classes as first-class objects. Languages that do, like Smalltalk and Objective C, derive less benefit, since you can always use a class object as a creator. Class objects already act like prototypes in these languages.


5. Configuring an application with classes dynamically. Some run-time environments let you load classes into an application dynamically. The Prototype pattern is the key to exploiting such facilities in a language like C++. An application that wants to create instances of a dynamically loaded class won't be able to reference its constructor statically. Instead, the run-time environment creates an instance of each class automatically when it's loaded, and it registers the instance with a prototype manager (see the
Implementation section). Then the application can ask the prototype manager for instances of newly loaded classes, classes that weren't linked with the program originally. The ET++ application framework [WGM88] has a run-time system that uses this scheme.
The main liability of the Prototype pattern is that each subclass of Prototype must implement the Clone operation, which may be difficult. For example, adding Clone is difficult when the classes under consideration already exist. Implementing Clone can be difficult when their internals include objects that don't support copying or have circular references.

 

관련 패턴들 : 

 Prototype and Abstract Factory are competing patterns in some ways, as we discuss at the end of this chapter. They can also be used together, however. An Abstract Factory might store a set of prototypes from which to clone and return product objects.
Designs that make heavy use of the Composite and Decorator patterns often can benefit from Prototype as well.

 

추가 정보 :     

  • Sometimes creational patterns are competitors: there are cases when either Prototype or Abstract Factory could be used properly. At other times they are complementory: Abstract Factory might store a set of Prototypes from which to clone and return product objects. Abstract Factory, Builder, and Prototype can use Singleton in their implementations.
  • Abstract Factory classes are often implemented with Factory Methods, but they can be implemented using Prototype.
  • Factory Method: creation through inheritance. Protoype: creation through delegation.
  • Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Protoype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed.
  • Prototype doesn't require subclassing, but it does require an "initialize" operation. Factory Method requires subclassing, but doesn't require Initialize.
  • Designs that make heavy use of the Composite and Decorator patterns often can benefit from Prototype as well.
  • Prototype co-opts one instance of a class for use as a breeder of all future instances.
  • Prototypes are useful when object initialization is expensive, and you anticipate few variations on the initialization parameters. In this context, Prototype can avoid expensive "creation from scratch", and support cheap cloning of a pre-initialized prototype.
  • Prototype is unique among the other creational patterns in that it doesn't require a class – only an object. Object-oriented languages like Self and Omega that do away with classes completely rely on prototypes for creating new objects.

 

 

출처 :  http://sourcemaking.com/design_patterns/prototype

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 ) 

 


Creational Patterns ( 생성 패턴 )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

생성패턴은 객체의 생성로직을 숨기고 new 명령어를 통하지 않고 객체를 생성하는 방법들을 제공한다. 이는 특정 상황에서 어떤 방법으로 객체를 생성해야할지를 결정하는데 있어서 유연성을 제공한다. 


 Structural Patterns ( 구조적 패턴 )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

구조적 패턴들은 클래스와 객체의 구성에 관여한다.

 

 Behavioral Patterns ( 행위적 패턴 )

These design patterns are specifically concerned with communication between objects.

이 패턴들은 객체들 사이의 커뮤니케이션에 관심을 가진다.

 

오늘 살펴볼  Factory Method 패턴은 Creational 패턴에 속한다.  

 

Factory Method Pattern Structure


패턴의 목적 ( Intent ) : 

 Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

팩토리 메소드 패턴은 하나의 객체를 생성하는 인터페이스를 정의하는데 이때 어떤 객체를 생성할 것인지에 대한 결정권은 서브클래스에게 위임한다. 

 

패턴이 나오게 된 동기 ( Motivation ) :


프 레임워크는 일반적으로 추상클래스로 객체 사이의 관계를 정의하는데, 종종 객체를 생성해야 할 때도 있다. 아래 다이어그램은 다양한 종류의 문서를 사용자에게 보여줄 수 있는 프레임워크의 클래스 다이어그램이다. 아래 다이어그램에서 관계를 맺고 있는 추상클래스들은 Document와 Application이다. 사용자가 그림그리기 애플리케이션을 만들려면 두 추상클래스를 상속받아 DrawingApplication과 DrawingDocument 클래스를 정의해야하고, Application클래스는 필요에따라 Document 클래스를 생성 혹은 열기가 가능해야 한다. 

자, 그런데 문제는 특정 문서는 특정 애플리케이션에 의존적이라는 점이다. 예를 들어, docx는 워드에서 생성하는 문서이지 한글에서 생성하는 문서가 아닌 것과 같은 현상이라고 보면 된다. 따라서 Application의 CreateDocument()를 추상메소드로 정의하고 이를 서브클래스에서 구현하도록 하여 각각의 Application마다 각각의 Document를 생성하도록 한 것이다. 이때 CreateDocument()를 팩토리 메소드라고 부른다. 

 

 

유용성 ( Applicability ) :

 Use the Factory Method pattern when


· a class can't anticipate the class of objects it must create.
· a class wants its subclasses to specify the objects it creates.
· classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.


등장 인물 ( Participants ) :

· Product (Document)
o defines the interface of objects the factory method creates.
· ConcreteProduct (MyDocument)
o implements the Product interface.
· Creator (Application)
o declares the factory method, which returns an object of type Product. Creator may also define a default implementation of the factory method that returns a default ConcreteProduct object.
o may call the factory method to create a Product object.
· ConcreteCreator (MyApplication)
o overrides the factory method to return an instance of a ConcreteProduct.


원리 ( Collaborations ) :

· Creator relies on its subclasses to define the factory method so that it returns an instance of the appropriate ConcreteProduct.


패턴 사용의 장단점 ( Consequences ): 

 Factory methods eliminate the need to bind application-specific classes into your code. The code only deals with the Product interface; therefore it can work with any user-defined ConcreteProduct classes. A potential disadvantage of factory methods is that clients might have to subclass the Creator class just to create a particular ConcreteProduct object. Subclassing is fine when the client has to subclass the Creator class anyway, but otherwise the client now must deal with another point of evolution. 

 

Here are two additional consequences of the Factory Method pattern:


1. Provides hooks for subclasses. Creating objects inside a class with a factory method is always more flexible than creating an object directly. Factory Method gives subclasses a hook for providing an extended version of an object.
In the Document example, the Document class could define a factory method called CreateFileDialog that creates a default file dialog object for opening an existing document. A Document subclass can define an application-specific file dialog by overriding this factory method. In this  case the factory method is not abstract but provides a reasonable default implementation.


2. Connects parallel class hierarchies. In the examples we've considered so far, the factory method is only called by Creators. But this doesn't have to be the case; clients can find factory methods useful, especially in the case of parallel class hierarchies.
Parallel class hierarchies result when a class delegates some of its responsibilities to a separate class. Consider graphical figures that can be manipulated interactively; that is, they can be stretched, moved, or rotated using the mouse. Implementing such interactions isn't always easy.
It often requires storing and updating information that records the state of the manipulation at a given time. This state is needed only during manipulation; therefore it needn't be kept in the figure object. Moreover, different figures behave differently when the user manipulates them. For example, stretching a line figure might have the effect of moving an endpoint, whereas stretching a text figure may change its line spacing. With these constraints, it's better to use a separate Manipulator object that implements the interaction and keeps track of any manipulation-specific state that's needed. Different figures will use different Manipulator subclasses to handle particular interactions. The resulting Manipulator class hierarchy parallels (at least partially) the Figure class hierarchy:


The Figure class provides a CreateManipulator factory method that lets clients create a Figure's corresponding Manipulator. Figure subclasses override this method to return an instance of the Manipulator subclass that's right for them. Alternatively, the Figure class may implement CreateManipulator to return a default Manipulator instance, and Figure subclasses may simply inherit that default. The Figure classes that do so need no corresponding Manipulator subclass—hence the hierarchies are only partially parallel.
Notice how the factory method defines the connection between the two class hierarchies. It localizes knowledge of which classes belong together.

 

관련 패턴들 : 

 Abstract Factory is often implemented with factory methods. The Motivation example in the Abstract Factory pattern illustrates Factory Method as well.
Factory methods are usually called within Template Methods. In the document example above, NewDocument is a template method.
Prototypes don't require subclassing Creator. However, they often require an Initialize operation on the Product class. Creator uses Initialize to initialize the object. Factory Method doesn't require such an operation.

 

추가 정보 :     

 
  • Abstract Factory classes are often implemented with Factory Methods, but they can be implemented using Prototype.
  • Factory Methods are usually called within Template Methods.
  • Factory Method: creation through inheritance. Prototype: creation through delegation.
  • Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed.
  • Prototype doesn't require subclassing, but it does require an Initialize operation. Factory Method requires subclassing, but doesn't require Initialize.
  • The advantage of a Factory Method is that it can return the same instance multiple times, or can return a subclass rather than an object of that exact type.
  • Some Factory Method advocates recommend that as a matter of language design (or failing that, as a matter of style) absolutely all constructors should be private or protected. It's no one else's business whether a class manufactures a new object or recycles an old one.
  • The new operator considered harmful. There is a difference between requesting an object and creating one. The new operator always creates an object, and fails to encapsulate object creation. A Factory Method enforces that encapsulation, and allows an object to be requested without inextricable coupling to the act of creation.

 

출처 :  http://sourcemaking.com/design_patterns/factory_method

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 ) 


Creational Patterns ( 생성 패턴 )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

생성패턴은 객체의 생성로직을 숨기고 new 명령어를 통하지 않고 객체를 생성하는 방법들을 제공한다. 이는 특정 상황에서 어떤 방법으로 객체를 생성해야할지를 결정하는데 있어서 유연성을 제공한다. 


 Structural Patterns ( 구조적 패턴 )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

구조적 패턴들은 클래스와 객체의 구성에 관여한다.

 

 Behavioral Patterns ( 행위적 패턴 )

These design patterns are specifically concerned with communication between objects.

이 패턴들은 객체들 사이의 커뮤니케이션에 관심을 가진다.

 

오늘 살펴볼  Abstract Factory 패턴은 Creational 패턴에 속한다.  

 

Abstract Factory Pattern Structure


패턴의 목적 ( Intent ) : 

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

추상 팩토리 패턴은 구상클래스를 명시하지 않아도 연관있거나 의존적인 객체의 그룹을 생성하기위한 인터페이스를 제공하는 패턴이다.

참고로 Factory는 싱글턴 패턴을 사용하는 것이 일반적이다. ( 동일한 제품을 생산하는 두개의 다른 공장을 하나의 애플리케이션에서 가지고 있을 필요는 없기 때문이다. ) 

 

패턴이 나오게 된 동기 ( Motivation ) :



 GOF의 디자인 패턴에서 예로 든 내용을 좀 꾸며서 얘기해보겠다.  

자, 우리 회사는 여러개의 위젯을 제공하는데 위젯마다 Look and Feel ( 이하 LNF )이 다르다. 지금까지 Window와 ScrollBar를 내가 만들어 놨는데 신입개발자가 이를 이용해서 위젯을 만들 수 있도록 해주고 싶다. 그래서 나는 WidgetFactory를 만들어 신입개발자가 사용할 수 있도록 할 것이다. 내가 만든 Window와 ScrollBar의 구상 클래스를 몰라도 WidgetFactory에서 알아서 생성해 줄 테니 신입개발자는 WidgetFactory 사용법만 알면 되겠지. 신입개발자가 PMWidget을 만들고 싶으면 PMWidgetFactory를 이용하면되고 MotifWidget을 만들고 싶으면 MotifWidgetFactory를 사용하면 되는거다. 


유용성 ( Applicability ) :

Use the Abstract Factory pattern when


· a system should be independent of how its products are created, composed, and represented.
· a system should be configured with one of multiple families of products.  

· a family of related product objects is designed to be used together, and you need to enforce this constraint.
· you want to provide a class library of products, and you want to reveal just their interfaces, not their implementations.

 

등장 인물 ( Participants ) :

· AbstractFactory (WidgetFactory)
o declares an interface for operations that create abstract product objects.
· ConcreteFactory (MotifWidgetFactory, PMWidgetFactory)
o implements the operations to create concrete product objects.
· AbstractProduct (Window, ScrollBar)
o declares an interface for a type of product object.
· ConcreteProduct (MotifWindow, MotifScrollBar)
o defines a product object to be created by the corresponding concrete factory.
o implements the AbstractProduct interface.
· Client
o uses only interfaces declared by AbstractFactory and AbstractProduct classes.


원리 ( Collaborations ) :

· Normally a single instance of a ConcreteFactory class is created at run-time.
This concrete factory creates product objects having a particular implementation. To create different product objects, clients should use a different concrete factory.
· AbstractFactory defers creation of product objects to its ConcreteFactory subclass.

 



패턴 사용의 장단점 ( Consequences ): 

The Abstract Factory pattern has the following benefits and liabilities:


1. It isolates concrete classes. The Abstract Factory pattern helps you control the classes of objects that an application creates. Because a factory encapsulates the responsibility and the process of creating product objects, it isolates clients from implementation classes. Clients manipulate instances through their abstract interfaces. Product class names are isolated in the implementation of the concrete factory; they do not appear in client code.  

 

2. It makes exchanging product families easy. The class of a concrete factory appears only once in an application—that is, where it's instantiated. This makes it easy to change the concrete factory an application uses. It can use different product configurations simply by changing the concrete factory. Because an abstract factory creates a complete family of products, the whole product family changes at once. In our user interface example, we can switch from Motif widgets to Presentation Manager widgets simply by switching the corresponding factory objects and recreating the interface.


3. It promotes consistency among products. When product objects in a family are designed to work together, it's important that an application use objects from only one family at a time. AbstractFactory makes this easy to enforce.


4. Supporting new kinds of products is difficult. Extending abstract factories to produce new kinds of Products isn't easy. That's because the AbstractFactory interface fixes the set of products that can be created. Supporting new kinds of products requires extending the factory interface, which involves changing the AbstractFactory class and all of its subclasses

새 로운 종류의 제품을 생산하는 것이 힘들다. 새로운 제품을 만들기 위해 AbstractFactory가 변경이 되면 이를 구현하는 구상클래스(concrete classes)들이 모두 변경되야 하기 때문이다. 이런 문제를 보완하기 위해서 Prototype-based Factory ( 프로토타입 패턴을 이용한 Factory )를 이용하는 방법도 있다.  

 

 

 

관련 패턴들 : 

 AbstractFactory classes are often implemented with factory methods (Factory Method), but they can also be implemented using Prototype.
A concrete factory is often a singleton.

 

추가 정보 :     

  • Sometimes creational patterns are competitors: there are cases when either Prototype or Abstract Factory could be used profitably. At other times they are complementary: Abstract Factory might store a set of Prototypes from which to clone and return product objects, Builder can use one of the other patterns to implement which components get built. Abstract Factory, Builder, and Prototype can use Singleton in their implementation.
  • Abstract Factory, Builder, and Prototype define a factory object that's responsible for knowing and creating the class of product objects, and make it a parameter of the system. Abstract Factory has the factory object producing objects of several classes. Builder has the factory object building a complex product incrementally using a correspondingly complex protocol. Prototype has the factory object (aka prototype) building a product by copying a prototype object.
  • Abstract Factory classes are often implemented with Factory Methods, but they can also be implemented using Prototype.
  • Abstract Factory can be used as an alternative to Facade to hide platform-specific classes.
  • Builder focuses on constructing a complex object step by step. Abstract Factory emphasizes a family of product objects (either simple or complex). Builder returns the product as a final step, but as far as the Abstract Factory is concerned, the product gets returned immediately.
  • Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed.

 

 

출처 :  http://sourcemaking.com/design_patterns/abstract_factory

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 ) 


 Creational Patterns ( 생성 패턴 )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

생성패턴은 객체의 생성로직을 숨기고 new 명령어를 통하지 않고 객체를 생성하는 방법들을 제공한다. 이는 특정 상황에서 어떤 방법으로 객체를 생성해야할지를 결정하는데 있어서 유연성을 제공한다. 


 Structural Patterns ( 구조적 패턴 )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

구조적 패턴들은 클래스와 객체의 구성에 관여한다.

 

 Behavioral Patterns ( 행위적 패턴 )

These design patterns are specifically concerned with communication between objects.

이 패턴들은 객체들 사이의 커뮤니케이션에 관심을 가진다.

 

오늘 살펴볼 Template Method 패턴은 Behavioral 패턴에 속한다.  

 

템 플릿하면 뭐가 떠오르는가? 사전적 의미는 형판, 견본이다. 우리가 일상적으로 쓸 때 템플릿이라 하면 뭔가의 기본구조(?)라고 생각을 할 수 있을 것이다. 이 템플릿 메소드는 바로 그런 형판, 견본, 기본구조의 역할을 하는 메소드이다. 그리고 이런 메소드를 이용하는 패턴을 템플릿 메소드 패턴이라고 이해하면 된다. 자 아래 그림을 살펴보자.

 


 

 

위 그림은 소방관, 목수, 우체부, 관리자 등 다양한 직업의 사람들을 객체로 만들었다. 이 사람들은 공통적으로 일하는 사람들이므로 Worker라는 클래스의 하위로 만들었고 모든 사람들은 동일한 일과 순서가 있다. 이 일과 순서는 DailyRoutine()내에 정의되어있고 Worker 클래스를 이용하는 클라이언트에서는 DailyRoutine()만 호출한다. 그러면 이 Worker가 소방관이냐, 우체부냐에 따라 work()에서 하는 일이 달라진다. 위 그림에서보면 모든 사람들이 work()를 오버라이드해서 재정의하고있기 때문이다. 여기서 DailyRoutine() 메소드가 템플릿 메소드가 되는 것이고 이런 식의 패턴을 템플릿 메소드 패턴이라 하는 것이다. 

 

Template Method Pattern Structure

 


 


패턴의 목적 ( Intent ) :
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.


어떤 작업을 수행하는 알고리즘의 뼈대를 정의하고 과정은 하위클래스가 정의하게끔 한다. 템플릿 메소드는 하위클래스들이 알고리즘의 구조에 변화를 주지 않는 선에서 알고리즘 내의 특정 과정만 재정의 할 수 있게끔 해준다.

 

패턴이 나오게 된 동기 ( Motivation ) :



 워 드 프로세서를 예를들어 설명하자면 Document(문서)파일과 Application(워드프로세서)가 있는데 이 워드프로세서가 문서를 열어본다는 시나리오를 생각해보자. OpenDocument()는 문서가 열수 있는 문서인지(읽어들일 수 있는지) 검사를 할 것이고, 워드프로세서내에서 정의한 Document객체를 생성하고 파일로부터 문서를 읽어들여 객체에 저장할 것이다.  

We call OpenDocument a template method. A template method defines an algorithm in terms of abstract operations that subclasses override to provide concrete behavior. Application subclasses define the steps of the algorithm that check if the document can be opened (CanOpenDocument) and that create the Document (DoCreateDocument). Document classes define the step that reads the document (DoRead). The template method also defines an operation that lets Application subclasses know when the document is about to be opened (AboutToOpenDocument), in case they care.  

By defining some of the steps of an algorithm using abstract operations, the template method fixes their ordering, but it lets Application and Document subclasses vary those steps to suit their needs.

 

여기서 이 OpenDocument()는 하나의 템플릿 메소드이다. 템플릿 메소드는 말그대로 특정 동작을 하기위한 골격만 제공한다. 골격내부의 구성은 하위클래스들이 하도록 하는 것이다. 

 

 

유용성 ( Applicability ) :

The Template Method pattern should be used

· to implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary.

템플릿 메소드 패턴은 변하지 않을 알고리즘의 구조만 정의하고 구체적인 구현은 하위클래스들에게 위임하고자 할 때 사용한다. 

 

· when common behavior among subclasses should be factored and localized in a common class to avoid code duplication. This is a good example of"refactoring to generalize" as described by Opdyke and Johnson.

You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations.

템플릿 메소드 패턴은 여러 하위 클래스들 중에서 중복된 부분을 제거하기 위해서도 사용될 수 있다.


· to control subclasses extensions. You can define a template method that calls "hook" operations (see Consequences) at specific points, thereby permitting extensions only at those points.

템플릿 메소드 패턴은 하위 클래스들의 확장을 컨트롤하고자 할 때 이용할 수도 있다. 우리는 템플릿 메소드에 특정시점에 hook를 호출하도록 정의하여 그 특정 시점에만 확장을 허용하도록 할 수도 있다. ( 무슨 말인지 모르겠다. 아래쪽에 Consequences에서 hook가 뭔지 더 알아보자 ) 

 

 

등장 인물 ( Participants ) :
· AbstractClass (Application)
o defines abstract primitive operations that concrete subclasses define to implement steps of an algorithm.
o implements a template method defining the skeleton of an algorithm.The template method calls primitive operations as well as operationsdefined in AbstractClass or those of other objects.
· ConcreteClass (MyApplication)
o implements the primitive operations to carry out subclass-specific steps of the algorithm.

 

원리 ( Collaborations ) :

ConcreteClass relies on AbstractClass to implement the invariant steps of the algorithm.


패턴 사용의 장단점 ( Consequences ): 

Template methods are a fundamental technique for code reuse. They are particularly important in class libraries, because they are the means for factoring out common behavior in library classes.
Template methods lead to an inverted control structure that's sometimes referred to as "the Hollywood principle," that is, "Don't call us, we'll call you" .
This refers to how a parent class calls the operations of a subclass and not the other way around.

Template methods call the following kinds of operations:
· concrete operations (either on the ConcreteClass or onclient classes);
· concrete AbstractClass operations (i.e., operations that are generally useful to subclasses);
· primitive operations (i.e., abstract operations);
· factory methods (see Factory Method); and
· hook operations, which provide default behavior that subclasses can extend if necessary. A hook operation often doesnothing by default. It's important for template methods to specify which operations arehooks (may be overridden) and which are abstract operations(must be  overridden). To reuse an abstract class effectively,subclass writers must understand which operations are designed foroverriding.
A subclass can extend a parent class operation's behavior byoverriding the operation and calling the parent operation explicitly:


void DerivedClass::Operation () {
// DerivedClass extended behavior
ParentClass::Operation();
}

 

Unfortunately, it's easy to forget to call the inherited operation.We can transform such an operation into a template method to give the parent control over how subclasses extend it. The idea is to call a hook operation from a template method in the parent class.Then subclasses can then override this hook operation:


void ParentClass::Operation () {
// ParentClass behavior
HookOperation();
}


HookOperation does nothing in ParentClass:


void ParentClass::HookOperation () { }


Subclasses override HookOperation to extend its behavior:


void DerivedClass::HookOperation () {
// derived class extension
}


관련 패턴들 : 

Factory Methods are often called by template methods. In the Motivation example, the factory method DoCreateDocument is called by the template method OpenDocument.
Strategy : Template methods use inheritance to vary part of an algorithm. Strategies use delegation to vary the entire algorithm.

 

추가 정보 :     

  • Strategy is like Template Method except in its granularity.
  • Template Method uses inheritance to vary part of an algorithm. Strategy uses delegation to vary the entire algorithm.
  • Strategy modifies the logic of individual objects. Template Method modifies the logic of an entire class.
  • Factory Method is a specialization of Template Method.

 

 

 

출처 : http://sourcemaking.com/design_patterns/template_method

         Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )


Creational Patterns ( 생성 패턴 )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

생성패턴은 객체의 생성로직을 숨기고 new 명령어를 통하지 않고 객체를 생성하는 방법들을 제공한다. 이는 특정 상황에서 어떤 방법으로 객체를 생성해야할지를 결정하는데 있어서 유연성을 제공한다. 


 Structural Patterns ( 구조적 패턴 )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

구조적 패턴들은 클래스와 객체의 구성에 관여한다.

 

 Behavioral Patterns ( 행위적 패턴 )

These design patterns are specifically concerned with communication between objects.

이 패턴들은 객체들 사이의 커뮤니케이션에 관심을 가진다.

 

오늘 살펴볼 State 패턴은 Behavioral 패턴에 속한다. 

 

State Pattern Structure

 

패턴의 목적 ( Intent ) : 

Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.

State 패턴의 목적은 내부 상태의 변화에 따라 객체의 행위를 변경할 수 있도록 하기 위함이다.


 위 다이어그램을 예제로 들면 TCPConnection은 TCPState객체를 가지고 있는 클래스다. 그리고 이 TCPState객체는 상태를 나타내는 클래스로 크게 세가지 상태로 나뉘는데 ( Established, Listen, Closed ) 이 상태의 변화에 따라 TCPConnection에서 호출하는 open()메소드가 TCPEstablished객체의 open()이 될 수도 있고 TCPListen나  TCPClosed 객체의 open()이 될 수도 있다.  

 

유용성 ( Applicability ) :

· An object's behavior depends on its state, and it must change its behavior at run-time depending on that state.

객체의 행위가 상태에 따라 동적으로 변해야 할 때
· Operations have large, multipart conditional statements that depend on the object's state. This state is usually represented by one or more enumerated constants. Often, several operations will contain this same conditional structure. The State pattern puts each branch of the conditional in a
separate class. This lets you treat the object's state as an object in its own right that can vary independently from other objects.

어떤 작업이 객체의 상태에 의존하는 여러개의 큰 조건문을 가지고 있다고 해보자( 쉽게 말해 객체의 상태를 나타내는 상수값이 조건문의 조건절에 들어가 있다고 생각해보자 ). 일반적으로 상태라는 것은 최소 하나 이상의 상수값에 의해 표현이 될 수 있는데, 이를 상태패턴을 이용하여 클래스에 담아버리는 것이다. 즉, 객체의 상태값을 나타내는 객체를 만들어 버리는 것이다.

 

등장 인물 :
· Context (TCPConnection)
o defines the interface of interest to clients.
o maintains an instance of a Concrete State subclass that defines the current state.

· State (TCPState)
o defines an interface for encapsulating the behavior associated with a particular state of the Context. 

 

· ConcreteState subclasses (TCPEstablished, TCPListen, TCPClosed)
o each subclass implements a behavior associated with a state of the Context.

 

원리 ( Collaborations ) :

· Context delegates state-specific requests to the current ConcreteState object.

Context는 상태에 따른 메소드 호출을 ConcreteState객체에 위임한다.
· A context may pass itself as an argument to the State object handling the request. This lets the State object access the context if necessary.

상태객체가 Context를 필요로한다면 Context객체는 자신을 argument로 넘겨주어 상태객체에서 접근할 수 있도록 할 수 있다.
· Context is the primary interface for clients. Clients can configure a context with State objects. Once a context is configured, its clients don't have to deal with the State objects directly.

클라이언트는 상태객체를 이용해서 context를 설정할 수 있는데 한번 설정하면 그 다음부터는 상태객체에 직접적으로 접근할 필요가 없다.
· Either Context or the ConcreteState subclasses can decide which state succeeds another and under what circumstances.

Context 또는 ConcreteState의 하위 클래스들은 상태의 순서를 결정할 수 있다.


패턴 사용의 장단점 ( Consequences ):
1. It localizes state-specific behavior and partitions behavior for different states.The State pattern puts all behavior associated with a particular state into one object. Because all state-specific code lives in a State subclass, new states and transitions can be added easily by defining new subclasses.
An alternative is to use data values to define internal states and have Context operations check the data explicitly. But then we'd have look-alike conditional or case statements scattered throughout Context's implementation. Adding a new state could require changing several operations, which complicates maintenance.

The State pattern avoids this problem but might introduce another, because the pattern distributes behavior for different states across several State subclasses. This increases the number of classes and is less compact than a single class. But such distribution is actually good if there are many states, which would otherwise necessitate large conditional statements.
Like long procedures, large conditional statements are undesirable.They're monolithic and tend to make the code less explicit, which in turn makes them difficult to modify and extend. The State pattern offers a better way to structure state-specific code. The logic that determines the state transitions doesn't reside in monolithic if or switch statements but instead is partitioned between the State  subclasses. Encapsulating each state transition and action in a class elevates the idea of an execution state to full object status. That imposes structure on the code and makes its intent clearer. 

 

2. It makes state transitions explicit.When an object defines its current state solely in terms of internal data values, its state transitions have no explicit representation;they only show up as assignments to some variables. Introducing separate objects for different states makes the transitions more explicit. Also, State objects can protect the Context from inconsistent internal states, because state transitions are atomic from the Context's perspective—they happen by rebinding one variable (the Context's State object variable), not several. 

 

3. State objects can be shared.If State objects have no instance variables—that is, the state they represent is encoded entirely in their type—then contexts can sharea State object. When states are shared in this way, they are essentially flyweights (see Flyweight) with nointrinsic state, only behavior.


관련 패턴들 : 

The Flyweight pattern explains when and how State objects can be shared.

Flyweight 패턴은 언제 어떻게 상태 객체들이 공유되는지 설명해준다.

State objects are often Singletons.

상태 객체들은 대부분 싱글턴이다.



추가 정보 :

  • State objects are often Singletons.
  • Flyweight explains when and how State objects can be shared.
  • Interpreter can use State to define parsing contexts.
  • Strategy has 2 different implementations, the first is similar to State. The difference is in binding times (Strategy is a bind-once pattern, whereas State is more dynamic).
  • The structure of State and Bridge are identical (except that Bridge admits hierarchies of envelope classes, whereas State allows only one). The two patterns use the same structure to solve different problems: State allows an object's behavior to change along with its state, while Bridge's intent is to decouple an abstraction from its implementation so that the two can vary independently.
  • The implementation of the State pattern builds on the Strategy pattern. The difference between State and Strategy is in the intent. With Strategy, the choice of algorithm is fairly stable. With State, a change in the state of the "context" object causes it to select from its "palette" of Strategy objects.

 

출처 : http://sourcemaking.com/design_patterns/state

         Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 ) 


 Creational Patterns ( 생성 패턴 )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

생성패턴은 객체의 생성로직을 숨기고 new 명령어를 통하지 않고 객체를 생성하는 방법들을 제공한다. 이는 특정 상황에서 어떤 방법으로 객체를 생성해야할지를 결정하는데 있어서 유연성을 제공한다. 


 Structural Patterns ( 구조적 패턴 )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

구조적 패턴들은 클래스와 객체의 구성에 관여한다.

 

 Behavioral Patterns ( 행위적 패턴 )

These design patterns are specifically concerned with communication between objects.

이 패턴들은 객체들 사이의 커뮤니케이션에 관심을 가진다.

 

오늘 살펴볼 Strategy패턴은 Behavioral 패턴에 속한다.  

 

우선 쉬운 이해를 위해서 아래 예제부터 보자.

Example

공항으로 가는 교통수단이 세가지가 있다.  버스, 자동차, 그리고 택시. 우리가 어떤 것을 타고갈 지는 가격, 이동하는데 걸리는 시간, 배차시간, 기름값 등등이 될 것이다. 이런것을 로직으로 구현한다고 생각해보자. 전략패턴을 공부하는 시간이니 전략이란 말을 써서 각각의 교통수단을 하나의 전략이라고 할 수 있을 것이다. 그리고 각 전략의 공통분모를 모아서 Strategy라는 클래스안에 넣었다. 이를 아래와 같이 그림으로 나타낼 수 있을 것이다. TransportationToAirport클래스는 당신의 두뇌라고 생각할 수 있을 것이다. 어떤 전략을 선택할 지 결정짓는 로직이 들어있는 곳이 될테니 말이다. 전략패턴을 간단하게 말하자면 이런 식의 패턴인거다. 좀 더 자세한 이론적인 얘기들은 아래에서 살펴보자. 

 

 

Strategy Pattern Structure

 

패턴의 목적 ( Intent ) : 

Define a family of algorithms, encapsulate each one, and make them interchangeable.
Strategy lets the algorithm vary independently from clients that use it.


전략 패턴은 교체가 가능한 알고리즘 그룹을 정의하고 각각의 알고리즘을 캡슐화하는 것이다.

다.



패턴이 나오게 된 동기 ( Motivation ) :

 

Suppose a Composition class is responsible for maintaining and updating the linebreaks of text displayed in a text viewer. Linebreaking strategies aren't implemented by the class Composition. Instead, they are implemented separately by subclasses of the abstract Compositor class. Compositor subclasses implement different strategies:

· SimpleCompositor implements a simple strategy that determines linebreaks one at a time.
·​ TeXCompositor implements the TeX algorithm for finding linebreaks. This strategy tries to optimize linebreaks globally, that is, one paragraph at a time.
· ArrayCompositor implements a strategy that selects breaks so that each row has a fixed number of items. It's useful for breaking a collection of icons into rows, for example. 

 

A Composition maintains a reference to a Compositor object. Whenever a Composition reformats its text, it forwards this responsibility to its Compositor object. The client of Composition specifies which Compositor should be used by installing the Compositor it desires into the Composition.

 

 

유용성 ( Applicability ) :

· many related classes differ only in their behavior. Strategies provide a way to configure a class with one of many behaviors.

연관된 많은 클래스들이 행하는 행위에 있어서만 다를 때


· you need different variants of an algorithm. For example, you might define algorithms  reflecting different space/time trade-offs.Strategies can be used when these variants are  implemented as a class hierarchy of algorithms.

클래스계층으로 이루어진 다양한 알고리즘이 필요할 때 전략패턴을 이용할 수 있다.


· an algorithm uses data that clients shouldn't know about. Use the Strategy pattern to avoid exposing complex, algorithm-specific data structures.

복잡하고 알고리즘에 특화된 데이타구조를 노출시키고 싶지 않으면 전략패턴을 이용할 수 있다.


· a class defines many behaviors, and these appear as multiple conditional statements in its operations. Instead of many conditionals, move related conditional branches into their own Strategy class.

한 클래스가 여러 행위를 정의하고 수많은 조건절에 의해 특정 행위를 해야할 때가 있다. 이럴 때는 많은 조건절대신에 연관있는 조건절들을 전략 클래스로 묶어버려라. 

 

 

등장 인물 ( Participants ) :
· Strategy (Compositor)
o declares an interface common to all supported algorithms. Context uses this interface to call the algorithm defined by a ConcreteStrategy.

지원가능한 모든 알고리즘의 공통 인터페이스를 정의한다. Context가 ConcreteStrategy에 의해 정의된 알고리즘을 호출하기 위해서 이 인터페이스를 이용한다. 

 

· ConcreteStrategy (SimpleCompositor, TeXCompositor,ArrayCompositor)  

o implements the algorithm using the Strategy interface.

Strategy 인터페이스를 이용해서 알고리즘을 구현한다.


· Context (Composition)
o is configured with a ConcreteStrategy object.

o maintains a reference to a Strategy object.  

Strategy객체로의 레퍼런스를 유지한다.
o may define an interface that lets Strategy access its data.  

Strategy가 Context의 데이타로 접근할 수 있도록 인터페이스를 정의할 수도 있다.

 

원리 ( Collaborations ) :

· Strategy and Context interact to implement the chosen algorithm. A context may pass all data required by the algorithm to the strategy when the algorithm is called. Alternatively, the context can pass itself as an argument to Strategy operations. That lets the strategy call back on the context as required.
· A context forwards requests from its clients to its strategy. Clients usually create and pass a ConcreteStrategy object to the context; thereafter, clients interact with the context exclusively. There is often a family of ConcreteStrategy classes for a client to choose from.


패턴 사용의 장단점 ( Consequences ): 

1. Families of related algorithms. Hierarchies of Strategy classes define a family of algorithms  or behaviors for contexts to reuse. Inheritance can help factor out common functionality of the algorithms.

전략패턴은 연관된 알고리즘그룹을 상속을 통해 클래스계층으로 만들어 이를 재사용할 수 있도록 한다.  

 

2. An alternative to subclassing. Inheritance offers another way to support a variety of algorithms or behaviors. You can subclass a Context class directly to give it different behaviors. But this hard-wires the behavior into Context. It mixes the algorithm implementation with Context's, making Context harder to understand, maintain, and extend. And you can't vary the algorithm dynamically. You wind up with many related classes whose only difference is the algorithm or behavior they employ. Encapsulating the algorithm in separate Strategy classes lets you vary the algorithm independently of its context, making it easier to switch, understand, and extend.


3. Strategies eliminate conditional statements. The Strategy pattern offers an alternative to conditional statements for selecting desired behavior. When different behaviors are lumped into one class, it's hard to avoid using conditional statements to select the right behavior. Encapsulating the behavior in separate Strategy classes eliminates these conditional statements.
Code containing many conditional statements often indicatesthe need to apply the Strategy pattern.


4. A choice of implementations. Strategies can provide different implementations of the  same behavior. The client can choose among strategies with different time and space trade-offs.


5. Clients must be aware of different Strategies.The pattern has a potential drawback in that a client must understand how Strategies differ before it can select the appropriate one. Clients might be exposed to implementation issues. Therefore you should use the Strategy pattern only when the variation in behavior is relevant to clients.


6. Communication overhead between Strategy and Context. The Strategy interface is shared by all ConcreteStrategy classes whether the algorithms they implement are trivial or complex. Hence it's likely that some ConcreteStrategies won't use all the information passed to them through this interface; simple ConcreteStrategies may use none of it! That means there will be times when the context creates and initializes parameters that never get used. If this is an issue, then you'll need tighter coupling between Strategy and Context.


7. Increased number of objects. Strategies increase the number of objects in an application. Sometimes you can reduce this overhead by implementing strategies as stateless objects that contexts can share. Any residual state is maintained by the context, which passes it in each request to the Strategy object. Shared strategies should not maintain state across invocations. The Flyweight pattern describes this approach in more detail.


관련 패턴들 : 

Flyweight

 

추가 정보 :   

  • Strategy is like Template Method except in its granularity.
    Strategy 패턴은 Template Method 패턴과 비슷하다. ( granularity를 제외하면 )
    ( granularity를 테크놀로지컬하게 뭐라고 해석해야할 지 모르겠네요.)

  • State is like Strategy except in its intent.
    State 패턴은 Strategy 패턴과 비슷하다. ( intent를 제외하면 )
  • Strategy lets you change the guts of an object. Decorator lets you change the skin.
    Strategy 패턴을 이용해서 객체내부를 변경할 수 있다면, Decorator 패턴은 객체껍데기를 변경할 수 있게 해준다.
  • State, Strategy, Bridge (and to some degree Adapter) have similar solution structures. They all share elements of the 'handle/body' idiom. They differ in intent - that is, they solve different problems.
    State, Strategy, Bridge 패턴들은 모두 비슷한 구조를 갖고 있지만, 패턴의 목적(intent)가 다르다. 즉, 서로 다른 문제를 해결하기 위해서 나온 패턴들이라는 얘기다.
  • Strategy has 2 different implementations, the first is similar to State. The difference is in binding times (Strategy is a bind-once pattern, whereas State is more dynamic).
    Strategy 패턴이 정적으로 한번 바인딩하는 반면 State 패턴은 동적으로 바인딩한다.
  • Strategy objects often make good Flyweights.
    Strategy 객체들은 보통 좋은 Filyweights를 만든다. ( Flyweight 패턴을 공부하면 무슨 말인지 이해가 될 듯 싶네요 )

 

 

 

출처 : http://sourcemaking.com/design_patterns/strategy

         Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )


- 현든 file

find . -type f|wc -l




- 현재 디렉토리 하위의 모든 디렉토리에서 가 class
find . -name '*.class' | wc -l

💻 Programming/Linux

[리눅스] 정규표현식을 이용한 파일 삭제

1. 타입이 파일인 것들 중 특정 정규식에 해당되는 파일 조회하기

find . -type f -regex '/ex/'



2. 

find . -type f -regex '/ex/' -exec rm {} \;



3. 가 class 

find . -type f ! -name '*.class' -exec rm {} \;



4. 확장자가 class가 아니고 java도 아닌 파일 타입 삭제하기

find ./online/ -type f ! -name '*.class' ! -name '*.java' -exec rm {} \;



💻 Programming/Linux

TOP 명령어, 필드 정보 및 옵션

깔끔하게 정리되어있는 자료가 있어서 공유합니다.


top 명령 실행시 추가할 수 있는 옵션

    * (top) -d [sec]: 설정된 초단위로 Refresh
    * (top) -c      : command뒤에 인자값 표시

top 명령 실행 후 사용할 수 있는 옵션

    * shift + t     : 실행된 시간이 큰 순서로 정렬
    * shift + m     : 메모리 사용량이 큰 순서로 정렬
    * shift + p     : cpu 사용량이 큰 순서로 정렬
    * k             : Process 종료
       o k 입력 후 종료할 PID를 입력한다
       o signal을 입력하라 표시되면 9를 넣어준다
    * c             : 명령 인자 표시 / 비표시
    * l(소 문자엘)   : uptime line(첫번째 행)을 표시 / 비표시
    * space bar     : Refresh
    * u             : 입력한 유저 소유의 Process만 표시
       o which user: 와 같이 유저를 입력하라 표시될때 User를 입력
       o blank(공백) 입력시 모두 표시
    * shift + b     : 상단의 uptime 및 기타 정보값을 블락선택해 표시
    * f             : 화면에 표시될 프로세스 관련 항목 설정


top 명령 실행 후 화면

 top.PNG


세부 정보 필드별 항목


  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND

    * PID : 프로세스 ID (PID)
    * USER : 프로세스를 실행시킨 사용자 ID
    * PRI : 프로세스의 우선순위 (priority)
    * NI : NICE 값. 일의 nice value값이다. 마이너스를 가지는 nice value는 우선순위가 높음.
    * VIRT : 가상 메모리의 사용량(SWAP+RES)
    * RES : 현재 페이지가 상주하고 있는 크기(Resident Size)
    * SHR : 분할된 페이지, 프로세스에 의해 사용된 메모리를 나눈 메모리의 총합.
    * S : 프로세스의 상태 [ S(sleeping), R(running), W(swapped out process), Z(zombies) ]
    * %CPU : 프로세스가 사용하는 CPU의 사용율
    * %MEM : 프로세스가 사용하는 메모리의 사용율
    * COMMAND : 실행된 명령어




출처 : http://faq.hostway.co.kr/?mid=Linux_ETC&page=7&document_srl=1441


💻 Programming

[Android/안드로이드] Fragment 사용하기

안녕하세요 케이치입니다. 


오랜만에 포스팅을 하게되네요. 오늘은 안드로이드 스튜디오에서 프래그먼트를 이용한 화면전환을 해보도록 하겠습니다.


이 포스팅을 하게된 이유는 Do It 안드로이드의 동영상 강좌 소스(롤리팝 기준 Day 10 - 2)가 현재 안스에서 생성해주는 기본소스와 다르기 때문입니다.


일단 개발환경부터 보시죠.




자, 일단 안스에서 새로운 프로젝트를 생성해보도록 합시다. 

아래 스크린샷대로 따라서 해보시고 생성된 소스가 동일한지 확인하세요.













자, 이제 우리는 여기에 새로운 프래그먼트 클래스를 만들고 그 프래그먼트의 레이아웃을 추가할 것입니다.

새로 생성될 파일은 두개입니다.

MenuFragment.java와 fragment_menu.xml 입니다.

MenuFragment.java는 MainActivityFragment.java를 복사해서 생성하시면되고

fragment_menu.xml은 fragment_main.xml을 복사해서 생성하시면 됩니다.


자, 이렇게 두개를 추가하셨으면 기존 소스를 아래처럼 변경해주세요.


MenuFragment.java


fragment_menu.xml


MainActivityFragment.java


fragment_main.xml



MainActivity.java


activity_main.xml


변경된 소스를 보시면 메인액티비티 쪽이 좀 크게 바뀌었습니다. activity_main.xml에서 Fragment가 아예 빠져버리고 그 자리를 RelativaLayout이 차지했습니다.


그리고 MainActivity.java에서 setContentView 다음에 한 라인이 추가되었는데 이 라인이 하는 일은 프래그먼트 메니저가 메인 레이아웃 즉 RelativeLayout에 메인프래그먼트(MainActivityFragment)를 추가하는 것입니다. 

그리고 버튼 클릭 리스너에는 프래그먼트메니저가 메인프래그먼트와 메뉴프래그먼트를 교체해주는 기능을 구현했습니다.


이렇게 함으로써 각 프래그먼트에서 다른 프래그먼트를 호출(버튼을 클릭함으로써 호출)할 때 서로 교체가 가능하도록 했습니다.


activity_main.xml에서 Fragment를 뺀 이유는, 해보시면 아시겠지만, 메인 레이아웃을 아예 Fragment로 지정함으로써 엑티비티에 올라간 프래그먼트가 프래그먼트 관리자의 replace메소드가 호출이 되었을 때 destroy 되지 않기 때문입니다. 정확한 이유는 제가 아직 초보자라 잘 모르겠지만 관리자의 손을 떠난 다고 해야하나, 프래그먼트가 그냥 하나의 액티비티가 되어버린것 같은 느낌이 듭니다. 그래서 처음에 화면이 중복되어 나오길래 방안을 찾아서 한 것이 위와 같은 방법이었습니다.


그냥 혼자 공부하면서 끄적이는 거라 정리가 잘 안된것 같긴 한데 조금이라도 도움이 되셨으리라 생각하고 이만 줄이겠습니다. 


이상 케이치였습니다. 


건강조심하시고 즐프하세요 ^-^ ( 전 여름 감기에 걸려서 죽을맛이네요 ㅠㅠ )



💻 Programming/Java

자바 객체를 byte[] 로 변환하기

안녕하세요 케이치입니다. 


오늘은 자바 객체를 바이트 배열로 변환하는 방법에 대해서 포스팅합니다.



1. Object to byte[]


ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = null;
try {
  out = new ObjectOutputStream(bos);   
  out.writeObject(yourObject);
  byte[] yourBytes = bos.toByteArray();
  ...
} finally {
  try {
    if (out != null) {
      out.close();
    }
  } catch (IOException ex) {
    // ignore close exception
  }
  try {
    bos.close();
  } catch (IOException ex) {
    // ignore close exception
  }
}


2. byte[] to Object


ByteArrayInputStream bis = new ByteArrayInputStream(yourBytes);
ObjectInput in = null;
try {
  in = new ObjectInputStream(bis);
  Object o = in.readObject(); 
  ...
} finally {
  try {
    bis.close();
  } catch (IOException ex) {
    // ignore close exception
  }
  try {
    if (in != null) {
      in.close();
    }
  } catch (IOException ex) {
    // ignore close exception
  }
}


기본적인 자바를 이용하면 저렇게 하시면 되는데 아파치 유틸을 이용하면 좀 더 편하게 할 수 있습니다.


ApacheUtils 라이브러리를 다운 받아서 사용하시면 됩니다.



To Serialize:

byte[] data = SerializationUtils.serialize(yourObject);

To Deserialize:

YourObject yourObject = (YourObject) SerializationUtils.deserialize(byte[] data)
달랑 한줄로 Object -> byte[] 도 가능하고 역으로도 가능하네요.

참 간단하쥬잉~?

이상 케이치였습니다.

즐프하세요~ 




💻 Programming/Computer General

cmd창의 코드 페이지 변경하기

1. cmd의 바로가기 오른쪽 클릭. 속성>옵션>현재 코드 페이지 변경

2. cmd창에서 chcp 실행

MS949로 변경하고자 할 경우 --> chcp 949

utf-8로 변경하고자 할 경우 --> chcp 65001


기타 다른 코드 페이지에 대해서는 아래 위키페이지를 참고하세요.
http://en.wikipedia.org/wiki/Code_page


설치환경

윈도우 8

이클립스 Luna

 

목차 

1. SonarQube 이클립스 플러그인 설치

2. SonarQube Download 및 서버 실행

3. 분석하고자하는 프로젝트와 SonarQube 프로젝트 연동하기

4. 분석 결과 보기

 

 

1. SonarQube 이클립스 플러그인 설치

플러그인 설치는 쉬우니까 아래 영문 가이드 보시면서 하시면 될것 같네요.

 

SonarQube 공식 이클립스 설치 가이드 문서

http://docs.sonarqube.org/display/SONAR/Installing+SonarQube+in+Eclipse

 

  1. Go to Help > Eclipse Marketplace... and search for "SonarQube"
    or
    Use offline update site: https://bintray.com/artifact/download/sonarsource/Distribution/org.sonar.ide.eclipse.site-3.5.0.20150804-1512-RELEASE.zip
    or
    Go to Help > Install New Software... This should display the Install dialog box. Paste the Update Site URL (http://downloads.sonarsource.com/eclipse/eclipse/) into the field Work with and press Enter. This should display the list of available plugins and components:



  2. Check the component you wish to install (see Features details).
  3. Click Next. Eclipse will then check to see if there is any issue which would prevent a successful installation.
  4. Click Finish to begin the installation process. Eclipse will then download and install the necessary components.
  5. Once the installation process is finished, Eclipse will ask if you want to restart the IDE. It is strongly recommended that you restart the IDE.

 

2. SonarQube Download 및 서버 실행 

아래 링크로 가시면 zip 파일을 다운로드 하실 수 있습니다.

 

http://www.sonarqube.org/downloads/

 

다운받은 zip파일을 바탕화면(원하는 곳)에 압축을 풀어주세요.

 

폴더 들어가면 bin폴더가 있고 그 안에 StartSonar.bat라는 파일이 있습니다.

 

이 파일을 실행시켜서 서버를 띄워주세요.

 

만약 서버 실행시 에러가 발생하면 아래 링크를 참조해주세요.

 

http://blog.naver.com/stork838/220442651809

 

마지막으로 서버가 제대로 실행 되었는지 확인

http://localhost:9000 ( 다른 설정을 건드리지 않았다면 기본적으로 이 주소로 접속이 가능해야 함 )

 

3. 분석하고자하는 프로젝트와 SonarQube 프로젝트 연동하기

a. 일단 서버에 접속이 잘 되는지 확인이 됐다면 admin으로 로그인 합니다.

( admin / admin 으로 접속 가능 )

 

b. Go to Settings -> System -> Provisioning

c. Create new project (Create 버튼은 우상단에 위치해있습니다. )

d. 프로젝트 생성시 key와 프로젝트명을 적절하게 아무거나 써주시면 됩니다. 나중에 이클립스에서 연동할 때 이 이름이 쓰입니다.

 

e. 이클립스에서 프로젝트에서 우클릭 -> Configure -> Associate with SonaQube

 

f. Sona Project 입력란에 아까 생성한 Sona 프로젝트명을 입력하면 자동완성기능으로 드랍다운 옵션이 보입니다.

g. 소나 프로젝트를 선택하고 완료하면 자동으로 분석을 시작합니다.

 

4. 분석 결과 보기

분석이 진행되는 동안 아래와 같은 메시지가 이클립스 콘솔창에 나옵니다.

 

Retrieve remote issues of project myproject...
Project not found on remote SonarQube server [myproject]      ---- A
Start SonarQube analysis on myproject...
INFO: SonarQube Server 5.1.2
11:20:19.564 INFO  - Incremental mode
11:20:19.935 INFO  - Load global repositories
11:20:20.786 INFO  - Load global repositories (done) | time=857ms
11:20:20.791 INFO  - Server id: 20150806110249
11:20:20.797 INFO  - User cache: C:\Users\user\.sonar\cache
11:20:20.813 INFO  - Install plugins
11:20:20.863 INFO  - Include plugins:
11:20:20.864 INFO  - Exclude plugins: devcockpit, jira, pdfreport, views, report, buildstability, buildbreaker
11:20:20.866 INFO  - Download sonar-core-plugin-5.1.2.jar
11:20:20.946 INFO  - Download sonar-email-notifications-plugin-5.1.2.jar
11:20:21.249 INFO  - Download sonar-java-plugin-3.0.jar
11:20:21.745 INFO  - Download sonar-scm-git-plugin-1.0.jar
11:20:21.963 INFO  - Download sonar-l10n-en-plugin-5.1.2.jar
11:20:21.987 INFO  - Download sonar-scm-svn-plugin-1.0.jar
11:20:23.923 INFO  - Load project repositories
11:20:24.658 INFO  - Load project repositories (done) | time=735ms
11:20:24.659 INFO  - Load project settings
11:20:25.575 INFO  - Apply project exclusions
11:20:25.613 INFO  - -------------  Scan myproject
11:20:25.624 INFO  - Load module settings
11:20:26.068 INFO  - Base dir: E:\ㅁㄴㅇㄹ
11:20:26.068 INFO  - Working dir: E:\ㅁㄴㅇㄹ
11:20:26.072 INFO  - Source paths: src
11:20:26.073 INFO  - Test paths: src
11:20:26.079 INFO  - Binary dirs: build/classes
11:20:26.079 INFO  - Source encoding: UTF-8, default locale: ko_KR
11:20:26.084 INFO  - Index files
11:20:26.098 INFO  - Excluded sources:
11:20:26.099 INFO  -   **/*Test.*
11:20:26.099 INFO  -   **/test/**/*
11:20:26.099 INFO  - Included tests:
11:20:26.099 INFO  -   **/*Test.*
11:20:26.099 INFO  -   **/test/**/*
11:20:27.123 INFO  - 370 files indexed
11:20:27.124 INFO  - 430 files ignored because of inclusion/exclusion patterns
11:20:27.150 INFO  - Quality profile for java: Sonar way
11:20:27.226 INFO  - Sensor JavaSquidSensor
11:20:30.695 INFO  - Java Main Files AST scan...
11:20:30.695 INFO  - 370 source files to be analyzed
11:20:40.706 INFO  - 26/370 files analyzed, current is E:\sdf.java
11:20:50.706 INFO  - 84/370 files analyzed, current is E:\dfg.java
11:21:00.706 INFO  - 187/370 files analyzed, current is E:\fgh.java
11:21:10.708 INFO  - 281/370 files analyzed, current is E:\rtyService.java
11:21:20.711 INFO  - 329/370 files analyzed, current is E:\erwtDao.java
11:21:27.080 INFO  - Java Main Files AST scan done: 56385 ms
11:21:27.080 INFO  - 370/370 source files analyzed
11:21:27.098 INFO  - Java bytecode scan...
11:21:29.109 INFO  - Java bytecode scan done: 2011 ms
11:21:29.109 INFO  - Java Test Files AST scan...
11:21:29.109 INFO  - 0 source files to be analyzed
11:21:29.110 INFO  - Java Test Files AST scan done: 1 ms
11:21:29.111 INFO  - 0/0 source files analyzed
11:21:29.121 INFO  - Package design analysis...
11:21:29.655 INFO  - Package design analysis done: 534 ms
11:21:30.485 INFO  - Sensor JavaSquidSensor (done) | time=63259ms
11:21:30.486 INFO  - Sensor Lines Sensor
11:21:30.576 INFO  - Sensor Lines Sensor (done) | time=90ms
11:21:30.576 INFO  - Sensor SurefireSensor
11:21:30.579 INFO  - parsing E:\sdf\surefire-reports
11:21:30.580 WARN  - Reports path not found: E:\dfg\surefire-reports     ------ B
11:21:30.580 INFO  - Sensor SurefireSensor (done) | time=4ms
11:21:31.576 INFO  - Export issues to E:\dfg\sonar-report.json
11:21:32.193 INFO  - ANALYSIS SUCCESSFUL

 

위 빨간 줄로 보이는 부분은 무시하셔도 됩니다. 아래를 좀 더 읽어보시면 그 이유가 나옵니다.

 

5. 수동으로 분석하기 

이클립스 프로젝트가 Sona 프로젝트와 연동이 되면 프로젝트 우클릭 메뉴에 SonaQube 메뉴가 뜨게됩니다.

해당 메뉴로 들어가면 Analysis가 있으니 이를 이용하시면 됩니다.

 

참고로 저는 진행하는 동안 아래와 같은 오류메시지를 보았습니다.

콘솔창에는 ANALYSIS SUCCESSFUL이라고 떴지만 동시에 팝업창으로

An internal error occurred during: "SonarQube Analysis".
Unable to create markers

라고 나오네요.

 

원인을 찾아서 다시 이어서 글을 쓰도록 하겠습니다.

 

 

그럼 다들 즐프~

 

------------- updated 2015-08-07 -------------

이클립스에서는 preview 나 incremental 분석만 가능하다고 합니다.

자세한 내용은 아래 링크를 참고하세요.

http://docs.sonarqube.org/display/SONAR/Working+with+SonarQube+in+Eclipse.

 

그 말인 즉슨, 분석이 로컬로 이루어지고 SonarQube DB에 저장되지 않는다는 말입니다.

자세한 내용은 아래 링크를 참고하시기 바래요.

http://docs.sonarqube.org/display/SONAR/Concepts#Concepts-AnalysisModes

 

SonarQube 서버에 데이터를 저장하고 웹페이지에서 결과를 보려면 SonarQube Runner를 다운 받아서 실행해야 합니다.

자세한 내용은 아래 링크를 참고하세요.

http://docs.sonarqube.org/display/SONAR/Analyzing+with+SonarQube+Runner

 

 

5. 수동으로 분석하기 - 2

지난 번 포스팅에서 수동으로 분석하기를 할때 단순히 이클립스에서 Analyze했었는데 그렇게 하면 서버에 기록도 남지 않는다는 것을 알았죠. 그래서 좀 더 조사를 해서 진도를 좀 빼 보았습니다.

 

우선 요기 바로 위에 세개의 링크 중에서 마지막 링크로 가셔서 소나큐브 러너를 다운받으시고 원하는 위치에 압축을 풀어주세요.

그 리고 내컴퓨터 > 속성 >  고급시스템설정 > 환경변수 로 이동하셔서 ( 윈도우 8 기준입니다. ) 아래처럼 SONAR_RUNNER_HOME 변수를 새로만들기를 이용해서 등록해주시고, Path에 사진에 보이시는 것처럼 등록해주세요.

 

 

 

 

그리고 소나 서버가 기동되어있다는 가정하에, 분석하고자하는 프로젝트의 루트 디렉토리로 이동해주세요.

예를들면 d:\eclipse\workspace\myproject 가 되겠죠?

 

그리고 파일을 하나 생성합니다.

 

sonar-project.properties 라는 파일을 생성하고 아래 내용을 넣어주세요. 본인의 설정에 맞게 projectKey와 projectName 그리고 제일 아래의 소스 인코딩 값을 바꿔주세요.

 

 

# must be unique in a given SonarQube instance
sonar.projectKey=myproject

# this is the name displayed in the SonarQube UI
sonar.projectName=myproject project
sonar.projectVersion=1.0
 
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# Since SonarQube 4.2, this property is optional if sonar.modules is set.
# If not set, SonarQube starts looking for source code from the directory containing
# the sonar-project.properties file.
sonar.sources=.
 
# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8

 

 

이제 저장을 하고 나와서 cmd창을 열어서 프로젝트 루트 디렉토리로 이동합니다.

 

그리고 소나 러너를 실행시킵니다.

 

기본적으로 sonar-runner 라고 하면 되는데 -X 옵션을 주면 debug 모드로 진행상황을 확인하실 수 있습니다.

 

아마 프로젝트가 svn과 연결되어있지 않은 상태라면 ( .svn 디렉토리가 프로젝트 루트디렉토리에 없다면 ) 실행이 잘 될겁니다.

 

실행이 잘 되었다면 로그 마지막 부분에 아래처럼 나오고 소나 러너는 종료됩니다.

 

INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
Total time: 25.866s
Final Memory: 15M/499M
INFO: ------------------------------------------------------------------------

 

이제 소나큐브 웹으로가서 분석된 자료를 확인해보겠습니다.

 

 

 

 

이런식으로 결과를 확인하실 수 있습니다. 각 수치가 뭘 의미하는지에 대해서는 자료를 좀 찾아봐야 할것 같습니다.

 

그부분은 여러분들이 각자 알아서 해보시면 될것 같네요.

 

참고로 저는 svn 연동해놓은 프로젝트도 시도해보았는데 svn 관련 에러가 발생했습니다.

 

이 부분에 대해서는 추후 업데이트 할 때 연이어서 글을 남기도록 하겠습니다.

 

 이상 케이치였습니다.

 

윈도우에서 소나큐브 서버를 실행시키기 위해서

$SonarQube Home$/bin/windows-x86-64/StartSonar.bat 파일을 실행시키면 cmd창에 아래처럼 에러가 뜨는데요


wrapper  | --> Wrapper Started as Console
wrapper  | Launching a JVM...
jvm 1    | Error occurred during initialization of VM
jvm 1    | GC triggered before VM initialization completed. Try increasing NewSize, current value 1536K.
wrapper  | JVM exited while loading the application.
wrapper  | JVM Restarts disabled.  Shutting down.
wrapper  | <-- p="" stopped="" wrapper="">

계속하려면 아무 키나 누르십시오 . . .



처음에는 sonar.properties에서 한참 찾다가 어떤 분이 포스팅한 글을 보고 해결했습니다.


위와 같은 에러나 가오면
$SonarQube Home$/conf/wrapper.conf 에서 아래 설정을 찾아서 값을 올려주면 됩니다.


(default)
wrapper.java.initmemory=3
wrapper.java.maxmemory=32


 

(after changing)

wrapper.java.initmemory=128
wrapper.java.maxmemory=256



그럼 즐프 하세요~ ^-^

💻 Programming/웹프로그래밍

[jQuery] 2. jQuery Basics ( 기본 )

jQuery 는 자바스크립트를 이용해서 만든 프레임워크라고 보시면됩니다. 따라서 자바스크립트 기능을 모두 사용하실 수 있다고 보시면 됩니다.

이번 포스팅에서는 jQuery에서 많이 사용되는 가장 기본적인 개념에 대해서 공부해보도록 하겠습니다.

String:

자바의 스트링처럼 자바스크립트의 스트링또한 동일한 속성을 가집니다. immutable 이란 말이죠. 

JavaScript 에서 스트링은 아래와 같은 형식을 가집니다. 쌍따옴표 또는 홑따옴표안에 있어야 합니다. 

"This is JavaScript String"
'This is JavaScript String'
'This is "really" a JavaScript String'
"This is 'really' a JavaScript String"

Numbers:

JavaScript에서 숫자는 double-precision 64-bit format IEEE 754 값입니다. 스트링과 마찬가지로 immutable입니다.

JavaScript Numbers 예제는 아래와 같습니다.

5350
120.27
0.26

Boolean:

true , false 를 나타내는 객체죠. 숫자가 0이면, false이고 스트링이 비어있어도 false입니다.

예제:

true      // true
false     // false
0         // false
1         // true
""        // false
"hello"   // true

Objects:

자바스크립트의 객체 생성 예제:

var emp = {
   name: "Zara",
   age: 10
};

객체의 속성정보를 읽거나 쓰는 예제:

// Getting object properties
emp.name  // ==> Zara
emp.age   // ==> 10

// Setting object properties
emp.name = "Daisy"  // <== Daisy
emp.age  =  20      // <== 20

Arrays(배열):

배열은 아래처럼 선언할 수 있습니다.

var x = [];
var y = [1, 2, 3, 4, 5];

배열은 길이를 가지고 있습니다. 루프를 돌릴때 유용하게 사용되죠.

var x = [1, 2, 3, 4, 5];
for (var i = 0; i < x.length; i++) {
   // Do something with x[i]
 }

Functions(함수):

자바스크립트의 함수는 named와 anonymous로 나뉘는데요 함수 이름을 직접 준것이 named고 함수 이름이 없는 것이 anonymous입니다. 네임드 함수는 function 키워드를 이용해서 아래처럼 선언할 수 있습니다.

function named(){
  // do some stuff here
}

anonymous 함수는 아래처럼 이름없이 아래처럼 변수에 할당될 수도 있고 다른 함수의 파라미터로 들어갈 수 있습니다.

var handler = function (){
  // do some stuff here
}

JQuery 에서 익명 함수는 아래처럼 자주 사용되어집니다.

$(document).ready(function(){
  // do some stuff here
});

Arguments(아규먼트):

JavaScript variable arguments is a kind of array which has length property. Following example explains it very well:

function func(x){
  console.log(typeof x, arguments.length);
}
func();                //==> "undefined", 0
func(1);               //==> "number", 1
func("1", "2", "3");   //==> "string", 3

The arguments object also has a callee property, which refers to the function you're inside of. For example:

function func() {
   return arguments.callee; 
}
func();                // ==> func

Context(컨텍스트):

JavaScript famous keyword this always refers to the current context. Within a function this context can change, depending on how the function is called:

$(document).ready(function() {
  // this refers to window.document
});

$("div").click(function() {
  // this refers to a div DOM element
});

You can specify the context for a function call using the function-built-in methods call() and apply() methods.

The difference between them is how they pass arguments. Call passes all arguments through as arguments to the function, while apply accepts an array as the arguments.

function scope() {
  console.log(this, arguments.length);
}

scope() // window, 0
scope.call("foobar", [1,2]);  //==> "foobar", 1
scope.apply("foobar", [1,2]); //==> "foobar", 2

Scope(범위):

The scope of a variable is the region of your program in which it is defined. JavaScript variable will have only two scopes.

  • Global Variables: A global variable has global scope which means it is defined everywhere in your JavaScript code.

  • Local Variables: A local variable will be visible only within a function where it is defined. Function parameters are always local to that function.

Within the body of a function, a local variable takes precedence over a global variable with the same name:

var myVar = "global";     // ==> Declare a global variable

function ( ) {
   var myVar = "local";   // ==> Declare a local variable
   document.write(myVar); // ==> local
}

Callback(콜백):

A callback is a plain JavaScript function passed to some method as an argument or option. Some callbacks are just events, called to give the user a chance to react when a certain state is triggered.

jQuery's event system uses such callbacks everywhere for example:

$("body").click(function(event) {
   console.log("clicked: " + event.target);
 });

Most callbacks provide arguments and a context. In the event-handler example, the callback is called with one argument, an Event.

Some callbacks are required to return something, others make that return value optional. To prevent a form submission, a submit event handler can return false as follows:

$("#myform").submit(function() {
   return false;
 });

Closures(클로져):

Closures are created whenever a variable that is defined outside the current scope is accessed from within some inner scope.

Following example shows how the variable counter is visible within the create, increment, and print functions, but not outside of them:

function create() {
  var counter = 0;
  return {
    increment: function() {
      counter++;
    },
    print: function() {
      console.log(counter);
    }
  }
}
var c = create();
c.increment();
c.print();     // ==> 1

This pattern allows you to create objects with methods that operate on data that isn't visible to the outside world. It should be noted that data hiding is the very basis of object-oriented programming.

Proxy Pattern(프록시패턴):

A proxy is an object that can be used to control access to another object. It implements the same interface as this other object and passes on any method invocations to it. This other object is often called the real subject.

A proxy can be instantiated in place of this real subject and allow it to be accessed remotely. We can saves jQuery's setArray method in a closure and overwrites it as follows:

(function() {
  // log all calls to setArray
  var proxied = jQuery.fn.setArray;

  jQuery.fn.setArray = function() {
    console.log(this, arguments);
    return proxied.apply(this, arguments);
  };
})();

The above wraps its code in a function to hide the proxied variable. The proxy then logs all calls to the method and delegates the call to the original method. Using apply(this, arguments) guarantees that the caller won't be able to notice the difference between the original and the proxied method.

Built-in Functions:

JavaScript comes along with a useful set of built-in functions. These methods can be used to manipulate Strings, Numbers and Dates.

Following are important JavaScript functions:

MethodDescription
charAt()Returns the character at the specified index.
concat()Combines the text of two strings and returns a new string.
forEach()Calls a function for each element in the array.
indexOf()Returns the index within the calling String object of the first occurrence of the specified value, or -1 if not found.
length()Returns the length of the string.
pop()Removes the last element from an array and returns that element.
push()Adds one or more elements to the end of an array and returns the new length of the array.
reverse()Reverses the order of the elements of an array -- the first becomes the last, and the last becomes the first.
sort()Sorts the elements of an array.
substr()Returns the characters in a string beginning at the specified location through the specified number of characters.
toLowerCase()Returns the calling string value converted to lower case.
toString()Returns the string representation of the number's value.
toUpperCase()Returns the calling string value converted to uppercase.

A complete list of built-in function is available here : Built-in Functions.

문서 객체 모델 ( DOM ):

문서객체모델이라는 것은 아래와 같이 다양한 html 요소들의 트리구조를 말합니다.

<html>
<head>
   <title>the title</title>
</head>
<body>
   <div>
      <p>This is a paragraph.</p>
      <p>This is second paragraph.</p>
      <p>This is third paragraph.</p>
   </div>
</body>
</html>

Following are the important points about the above tree structure:

  • The <html> is the ancestor of all the other elements; in other words, all the other elements are descendants of <html>.

  • The <head> and <body> elements are not only descendants, but children of <html>, as well.

  • Likewise, in addition to being the ancestor of <head> and <body>, <html> is also their parent.

  • The <p> elements are children (and descendants) of <div>, descendants of <body> and <html>, and siblings of each other <p> elements.



 그냥 html 기본에 대해서 설명하고 있는거죠. 이정도는 다 아시리라보고 번역안합니다 ㅎ


 

 

 

 

Reference : http://www.tutorialspoint.com/jquery/jquery-basics.htm

 


'💻 Programming > 웹프로그래밍' 카테고리의 다른 글

AJAX란? - 이벤트 종류  (0) 2016.06.12
AJAX란? - 서버로부터 응답받기  (0) 2016.06.12
AJAX란? - 서버로 요청하기  (1) 2016.06.12
Ajax 란? - Ajax 시작하기  (1) 2016.06.12
[jQuery] 1. jQuery 시작하기  (0) 2015.08.06