Posts

design pattern #10 Structural pattern - Facade

복잡하고 많은 class 들을 사용하여 작업을 하는 경우, client 에게 필요한 기능만을 따로 빼고 나머지는 감춰서 제공하는 class 가 facade class 이다. 사용자 입장에서 복잡도를 낮추고, 필요한 기능만 제공한다는 장점이 있고, 변경이나 라이브러리 대체가 필요한 경우, 이 facade 만 수정 혹은 대체하면 된다는 장점이 있다. facade class 가 어디서든 다 사용되는 god class 가 되어 의존도가 높아지거나, facade class 자체가 커질 위험이 있다는 단점이 있다. 아래 예제를 보면 main  함수에서는 VideoConversionFacade 클래스만 사용하고 있고, 나머지 codec, sound, 등등은 facade 클래스가 처리 한다. public class VideoFile { private String name ; private String codecType ; public VideoFile(String name) { this . name = name; this . codecType = name.substring(name.indexOf( "." ) + 1 ); } public String getCodecType() { return codecType ; } public String getName() { return name ; } } public interface Codec { } public class MPEG4CompressionCodec implements Codec { public String type = "mp4" ; } public class OggCompressionCodec implements Codec { public String type = "ogg" ; } public class CodecFactory { pu...

design pattern #9 Structural pattern - Decorator

이름은 낯설지만, wrapper class 형태로 씌우는것을 말한다 wrapper 로 감싸고, 추가적인 기능을 덧붙인다 추가적인 기능을 덧붙이는데, 상속이 편히 쓸 수 있는 방법인데, 이와같은 wrapper 형식을 통하면, reference 를 가지고 있으며 추가 기능을 붙이고, 필요한 일을 delegate 시킬 수 있다. File 을 Decorate 한다고 치자. interface 로 DataSource 를 만들고, DataSource 를 implement 한 FileDataSource 가 있다. DataSource Decorator  (DataSource Wrapper 라고 이해했다)역시 DataSource 를 implement 한다. Decorator 안에 wrappee 가 있고, 이게 datasource 가 된다. DataSourceDecorator 를 보면, DataSource 를 implement 했는데, wrappee 도 type이 DataSource 이다. 그리고 이 wrapper 를 상속하여 구체 decorator 를 만든게 EncryptDecorator, CompressDecorator 다. 만일 이렇게 하지 않고 상속 한다면, FileDataSource 를 상속 받아, EcryptFileDataSource, CompressFileDataSource 이런식으로 했겠지.  wrapper의 또 장점은,  예제에서처럼,  wrapper 를 한번 더 다른 wrapper 로 감싸는 식으로 할수 있다.  public interface DataSource { void writeData(String data); String readData(); } public class FileDataSource implements DataSource { private String name ; public FileDataSource(String name) { this . name = na...

design pattern #8 Structural pattern - Composite

tree 구조를 ds 가 아닌 object pattern  에서 나타낼때 쓰인다 box 안에 product 가 있거나, box 가 있고 또 그 안에 product 가 있는 경우를 예로 들 수 있다 hierarchy  구조를 표현하는데 유용할 수 있다 디자인패턴의 원리가 그렇듯, client  입장에서 내부 구조를 알 필요가 없다는 장점이 있다 예시에서는, 도형과, 도형 모음을 예로 들고 있다.  일단 공통 기능이 Shape interface 로 묶여있고, 이를 구현 한것이 BasicShape 인데, abstract class 로 되어 있다. BasicShape 을 상속해서 Rect, Circle  등을 만든다. CompoundShape 역시 BasicShape 을 상속 했는데, List<Shape> 을 가지고 있다. 예제에는 ImageEditor 라는 class 가 별도로 있고, 여기서 CompoundShape 을 가지고 있어, main 에서 쓰고 있다. 한눈에  와 닿지는 않지만, interface 를 abstract basic class 로 implement  하고, 이를  상속받아 구체적인 class 를 쓰는 경우는 좀 본것 같다. public interface Shape { int getX(); int getY(); int getWidth(); int getHeight(); void move( int x, int y); boolean isInsideBounds( int x, int y); void select(); void unSelect(); boolean isSelected(); void paint(Graphics graphics); } abstract class BaseShape implements Shape { public int x ; public int y ; public...

49. Group Anagrams

첫번째에 accept 되었지만, map 을 다루는 과정에서 compile 에러가 나왔고,  (getOrDefault, put) map 에서 value 들을 가져올때는, map.getValues()  가  아니고  map.values()  였다. time complexity 는, string 개수를 N개라고 할 때 각 단어들에 대해 interate 돌기 때문에, O(N) string 각각의 길이를 k 라고 하면, 매 단어마다  char 로 쪼개서 정렬을 다시 했기 때문에 klogk가 든다. 따라서 O(Nklogk) 가 되는것 같다. anagram 으로 묶을때 같은 group 인지 체크하는 함수를, char array 로 바꿔서 정렬해서 확인하지 않고, 뭔가 다른방법으로 해야 성능을 높일 수 있을 것 같다.

973. K Closest Points to Origin

며칠전 풀었던 문제와 비슷하게, closest K 가 조건인 만큼, PQ 를 이용하면  될것 같아서 접근했고, compile 에러 ( pq.size() 에서 () 빼먹음, cnt++;  에서 ; 빼먹음)  을 빼면 한번에 accept 되었다.  closest K 를 구하는 만큼, max heap 을 이용하는 것이 포인트 이다.  time complexity 는 PQ 에 point  개수 N 개 만큼 insert 했으므로, O(NlogN) 이 되는것 같다. 하지만 내 풀이는 28ms 로, 매우 오래 걸렸다.

design pattern #7 Structural pattern - Bridge

한 클래스가 두가지의 기능을 하는 경우, 예를 들어 도형에 관한 클래스 인데, shape 도, color 도 관리할 경우 종류가 많아지면 복잡해진다. 이럴때 shape 과 color  를 따로 빼서, shape  이  color 를 소유하는 식으로 하면 복잡도를 줄이고, single responsibility 를 지킬 수 있다.  GoF 에서는 absctraction, implementation ( java 에서 말하는것이 아닌 concept 차원) 라고 설명하는거 같은데, 더 이해가 안된다. 예제에서는 Device 와 Remote 가 각각 interface 가 되고, Device 를 구현한 Radio, Tv 가 존재한다.  그리고 Remote  를 구현한 BasicRemote, 그걸 상속받은 AdvancedRemote 가 있는데,  BasicRemote 를 보면 device 를 protected 필드로 가지고 있다.  이렇게 함으로써 Remote 대로,  Device 대로, 각각 개발 따로 개발 할 수가 있는 것이다.  Design pattern 을 살펴보며 느끼는건,  하나의 클래스는 하나만 관리하며, 서로 loose 하게 coupled 되어 있어야 한쪽이 바뀌었을때 타격이 적고, 그래야 다른 쪽을 신경쓰지 않고 개발 할 수 있으며, 점점 커지면 쪼개야 할 가능성이 높다는 것, 그래서 필요한만큼만 보여주고 나머지는 감추는 것 이다. public interface Device { int getVolume(); void setVolume( int percent); int getChannel(); void setChannel( int channel); } public class Radio implements Device { private boolean on = false ; private int volume = 30 ; ...

design pattern #6 Structural pattern - Adapter

예제 처럼  US  power plug 가 German power outlet 에 맞지 않아 adapter 를 끼우는 것이다. 두 object 사이에 wrapper 역할을 한다. legacy code 를 처리하는데도 씌인다. 예제에서는 SqurePeg 이 RoundHole 에 fit  한지를 체크하기 위해 Adapter 를 도입한다. Adapter 는 RoundPeg  을 extend 해서 getRadius  를 Override 한다. public class RoundHole { private double radius ; public RoundHole( double radius) { this . radius = radius; } public double getRadius() { return radius ; } public boolean fits(RoundPeg peg) { boolean result; result = ( this .getRadius() >= peg.getRadius()); return result; } } public class RoundPeg { private double radius ; public RoundPeg( double radius) { this . radius = radius; } public double getRadius() { return radius ; } } public class SquarePeg { private double width ; public SquarePeg( double width) { this . width = width; } public double getWidth() { return width ; } ...