├── .gitignore ├── AbstractFactory ├── LinkPage.html ├── Main.py └── factory │ ├── __init__.py │ ├── factory.py │ ├── listfactory │ ├── __init__.py │ └── list_factory.py │ └── tablefactory │ ├── __init__.py │ └── table_factory.py ├── Adapter ├── Adapter_1_Inheritance │ ├── Main.py │ └── adapter │ │ ├── __init__.py │ │ ├── banner.py │ │ ├── print.py │ │ └── print_banner.py └── Adapter_2_delegation │ ├── Main.py │ └── adapter │ ├── __init__.py │ ├── banner.py │ ├── print.py │ └── print_banner.py ├── Bridge ├── Main.py ├── bridge │ ├── __init__.py │ ├── function │ │ ├── __init__.py │ │ ├── display_count_func.py │ │ ├── display_func.py │ │ └── display_random_func.py │ └── implement │ │ ├── __init__.py │ │ ├── display_impl.py │ │ ├── display_string_impl.py │ │ └── display_textfile_impl.py └── test.txt ├── Builder ├── Greeting.html ├── Main.py └── builder │ ├── __init__.py │ ├── builder.py │ ├── director.py │ ├── htmlbuilder │ ├── __init__.py │ └── html_builder.py │ └── textbuilder │ ├── __init__.py │ └── text_builder.py ├── Chain_of_Responsibility ├── Main.py ├── support.py └── trouble.py ├── Command ├── Main.py └── command │ └── command.py ├── Composite ├── Main.py └── entry.py ├── Decorator ├── step1 │ ├── Main.py │ └── decorator │ │ ├── __init__.py │ │ ├── border.py │ │ └── display.py ├── step2 │ ├── Main.py │ └── decorator │ │ ├── __init__.py │ │ ├── border.py │ │ └── display.py └── step3 │ ├── Main.py │ └── decorator │ ├── __init__.py │ ├── border.py │ └── display.py ├── Facade ├── Main.py ├── maildata.ini ├── pagemaker │ ├── __init__.py │ ├── database.py │ ├── html_writer.py │ └── page_maker.py ├── welcome1.html └── welcome2.html ├── FactoryMethod ├── Main.py └── framework │ ├── __init__.py │ ├── factory.py │ └── idcardfactory │ ├── __init__.py │ └── id_card_factory.py ├── Flyweight ├── Main.py ├── big0.txt ├── big1.txt ├── big2.txt ├── big3.txt ├── big4.txt ├── big5.txt ├── big6.txt ├── big7.txt ├── big8.txt ├── big9.txt └── flyweight │ ├── __init__.py │ └── big_char_factory.py ├── Iterator ├── step1 │ ├── Main.py │ └── iterator │ │ ├── __init__.py │ │ ├── aggregate.py │ │ ├── book.py │ │ └── iterator.py └── step2 │ ├── Main.py │ └── iterator │ ├── __init__.py │ └── book.py ├── Mediator ├── Main.py └── mediator │ ├── __init__.py │ ├── colleague.py │ └── mediator.py ├── Memento ├── Main.py └── memento │ ├── __init__.py │ ├── gamer.py │ └── memento.py ├── Observer ├── Main.py └── observer │ ├── __init__.py │ ├── generator.py │ └── observer.py ├── Prototype ├── Main.py └── framework │ ├── __init__.py │ ├── decoprototype │ ├── __init__.py │ ├── message_box_prototype.py │ └── underline_pen_prototype.py │ ├── manager.py │ └── prototype.py ├── Proxy ├── Main.py └── proxy │ ├── __init__.py │ └── printer_proxy.py ├── README.md ├── Singleton ├── step1 │ └── Main.py └── step2 │ └── Main.py ├── State ├── Main.py └── state │ ├── __init__.py │ ├── context.py │ └── state.py ├── Strategy ├── Main.py └── strategy │ ├── __init__.py │ ├── hand.py │ ├── player.py │ └── strategy.py ├── TemplateMethod ├── Main.py └── templatemethod │ ├── __init__.py │ └── display.py └── Visitor ├── Main.py └── visitor ├── __init__.py ├── element.py └── visitor.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | __pycache__/ 3 | *.py[co] 4 | log/ 5 | 6 | # Unit test / coverage reports 7 | htmlcov/ 8 | .tox/ 9 | .coverage 10 | .coverage.* 11 | .cache 12 | nosetests.xml 13 | coverage.xml 14 | *.cover 15 | .hypothesis/ 16 | .pytest_cache/ 17 | 18 | # pyenv 19 | .python-version 20 | 21 | #vscode 22 | .vscode 23 | -------------------------------------------------------------------------------- /AbstractFactory/LinkPage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | LinkPage 4 | 5 |

LinkPage

6 |
7 | 8 |
Newspaper
AsahiYomiuri
9 | 10 |
Search Engine
11 | 12 |
Yahoo!
YahooYahoo!Japan
ExciteGoogle

Hiroshi Yuki 13 | 14 | -------------------------------------------------------------------------------- /AbstractFactory/Main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import inspect 3 | import factory 4 | 5 | 6 | def startMain(factoryObject): 7 | asahi = factoryObject.createLink("Asahi", "http://www.asahi.com") 8 | yomiuri = factoryObject.createLink("Yomiuri", "http://www.yomiuri.co.jp") 9 | us_yahoo = factoryObject.createLink("Yahoo", "http://www.yahoo.com") 10 | jp_yahoo = factoryObject.createLink("Yahoo!Japan", "http://www.yahoo.co.jp") 11 | google = factoryObject.createLink("Google", "http://www.google.com") 12 | excite = factoryObject.createLink("Excite", "http://www.excite.co.jp") 13 | 14 | traynews = factoryObject.createTray("Newspaper") 15 | traynews.add(asahi) 16 | traynews.add(yomiuri) 17 | 18 | trayyahoo = factoryObject.createTray("Yahoo!") 19 | trayyahoo.add(us_yahoo) 20 | trayyahoo.add(jp_yahoo) 21 | 22 | traysearch = factoryObject.createTray("Search Engine") 23 | traysearch.add(trayyahoo) 24 | traysearch.add(excite) 25 | traysearch.add(google) 26 | 27 | page = factoryObject.createPage("LinkPage", "Hiroshi Yuki") 28 | page.add(traynews) 29 | page.add(traysearch) 30 | page.output() 31 | 32 | 33 | if __name__ == '__main__': 34 | for _, plugin in inspect.getmembers(factory, inspect.isclass): 35 | if plugin.__name__ == sys.argv[1]: 36 | startMain(plugin()) 37 | -------------------------------------------------------------------------------- /AbstractFactory/factory/__init__.py: -------------------------------------------------------------------------------- 1 | from factory.listfactory.list_factory import ListFactory 2 | from factory.tablefactory.table_factory import TableFactory 3 | 4 | __all__ = [ 5 | "ListFactory", 6 | "TableFactory" 7 | ] -------------------------------------------------------------------------------- /AbstractFactory/factory/factory.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from abc import ABCMeta, abstractmethod 3 | 4 | 5 | class Factory(metaclass=ABCMeta): 6 | @abstractmethod 7 | def createLink(self, caption, url): 8 | pass 9 | 10 | @abstractmethod 11 | def createTray(self, caption): 12 | pass 13 | 14 | @abstractmethod 15 | def createPage(self, title, author): 16 | pass 17 | 18 | 19 | class Item(metaclass=ABCMeta): 20 | def __init__(self, caption): 21 | self.caption = caption 22 | 23 | @abstractmethod 24 | def makeHtml(self): 25 | pass 26 | 27 | 28 | class Link(Item, metaclass=ABCMeta): 29 | def __init__(self, caption, url): 30 | super().__init__(caption) 31 | self.url = url 32 | 33 | 34 | class Tray(Item, metaclass=ABCMeta): 35 | def __init__(self, caption): 36 | super().__init__(caption) 37 | self.tray = [] 38 | 39 | def add(self, item): 40 | self.tray.append(item) 41 | 42 | 43 | class Page(metaclass=ABCMeta): 44 | def __init__(self, title, author): 45 | self.title = title 46 | self.author = author 47 | self.content = [] 48 | 49 | def add(self, item): 50 | self.content.append(item) 51 | 52 | def output(self): 53 | try: 54 | filename = self.title + '.html' 55 | writer = open(filename, 'w') 56 | writer.write(self.makeHtml()) 57 | writer.close() 58 | print("[" + filename + "]" + " was created.") 59 | except Exception as e: 60 | print(e) 61 | sys.exit(1) 62 | 63 | @abstractmethod 64 | def makeHtml(self): 65 | pass 66 | -------------------------------------------------------------------------------- /AbstractFactory/factory/listfactory/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/AbstractFactory/factory/listfactory/__init__.py -------------------------------------------------------------------------------- /AbstractFactory/factory/listfactory/list_factory.py: -------------------------------------------------------------------------------- 1 | from factory.factory import Factory, Link, Tray, Page 2 | 3 | 4 | class ListFactory(Factory): 5 | def createLink(self, caption, url): 6 | return ListLink(caption, url) 7 | 8 | def createTray(self, caption): 9 | return ListTray(caption) 10 | 11 | def createPage(self, title, author): 12 | return ListPage(title, author) 13 | 14 | 15 | class ListLink(Link): 16 | def __init__(self, caption, url): 17 | super().__init__(caption, url) 18 | 19 | def makeHtml(self): 20 | return '
  • {}
  • \n'.format(self.url, self.caption) 21 | 22 | 23 | class ListTray(Tray): 24 | def __init__(self, caption): 25 | super().__init__(caption) 26 | 27 | def makeHtml(self): 28 | buf = [] 29 | buf.append('
  • \n') 30 | buf.append(self.caption + '\n') 31 | buf.append('\n') 37 | buf.append('
  • \n') 38 | return ''.join(buf) 39 | 40 | 41 | class ListPage(Page): 42 | def __init__(self, title, author): 43 | super().__init__(title, author) 44 | 45 | def makeHtml(self): 46 | buf = [] 47 | buf.append(''' 48 | 49 | {} 50 | '''.format(self.title)) 51 | buf.append('\n') 52 | buf.append('

    {}

    '.format(self.title)) 53 | buf.append('') 59 | buf.append('
    {}'.format(self.author)) 60 | buf.append('\n\n') 61 | return ''.join(buf) 62 | -------------------------------------------------------------------------------- /AbstractFactory/factory/tablefactory/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/AbstractFactory/factory/tablefactory/__init__.py -------------------------------------------------------------------------------- /AbstractFactory/factory/tablefactory/table_factory.py: -------------------------------------------------------------------------------- 1 | from factory.factory import Factory, Link, Tray, Page 2 | 3 | 4 | class TableFactory(Factory): 5 | def createLink(self, caption, url): 6 | return TableLink(caption, url) 7 | 8 | def createTray(self, caption): 9 | return TableTray(caption) 10 | 11 | def createPage(self, title, author): 12 | return TablePage(title, author) 13 | 14 | 15 | class TableLink(Link): 16 | def __init__(self, caption, url): 17 | super().__init__(caption, url) 18 | 19 | def makeHtml(self): 20 | return '{}'.format(self.url, self.caption) 21 | 22 | 23 | class TableTray(Tray): 24 | def __init__(self, caption): 25 | super().__init__(caption) 26 | 27 | def makeHtml(self): 28 | buf = [] 29 | buf.append('') 30 | buf.append('') 31 | buf.append(''.format(len(self.tray), self.caption)) 32 | buf.append('\n') 33 | buf.append('\n') 34 | 35 | for item in self.tray: 36 | buf.append(item.makeHtml()) 37 | 38 | buf.append('
    {}
    ') 39 | buf.append('') 40 | return ''.join(buf) 41 | 42 | 43 | class TablePage(Page): 44 | def __init__(self, title, author): 45 | super().__init__(title, author) 46 | 47 | def makeHtml(self): 48 | buf = [] 49 | buf.append(''' 50 | 51 | {} 52 | '''.format(self.title)) 53 | buf.append('\n') 54 | buf.append('

    {}

    '.format(self.title)) 55 | buf.append('\n') 56 | 57 | for item in self.content: 58 | buf.append('{}'.format(item.makeHtml())) 59 | 60 | buf.append('
    ') 61 | buf.append('
    {}'.format(self.author)) 62 | buf.append('\n\n') 63 | return ''.join(buf) 64 | -------------------------------------------------------------------------------- /Adapter/Adapter_1_Inheritance/Main.py: -------------------------------------------------------------------------------- 1 | from adapter.print_banner import PrintBanner 2 | 3 | 4 | def startMain(): 5 | p = PrintBanner("Hello") 6 | p.printWeak() 7 | p.printStrng() 8 | 9 | 10 | if __name__ == '__main__': 11 | startMain() 12 | -------------------------------------------------------------------------------- /Adapter/Adapter_1_Inheritance/adapter/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Adapter/Adapter_1_Inheritance/adapter/__init__.py -------------------------------------------------------------------------------- /Adapter/Adapter_1_Inheritance/adapter/banner.py: -------------------------------------------------------------------------------- 1 | class Banner(object): 2 | def __init__(self, string): 3 | self.__string = string 4 | 5 | def showWithParen(self): 6 | print("({0})".format(self.__string)) 7 | 8 | def showWithAster(self): 9 | print("*{0}*".format(self.__string)) 10 | -------------------------------------------------------------------------------- /Adapter/Adapter_1_Inheritance/adapter/print.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Print(metaclass=ABCMeta): 5 | @abstractmethod 6 | def printWeak(self): 7 | pass 8 | 9 | @abstractmethod 10 | def printStrng(self): 11 | pass 12 | -------------------------------------------------------------------------------- /Adapter/Adapter_1_Inheritance/adapter/print_banner.py: -------------------------------------------------------------------------------- 1 | from adapter.banner import Banner 2 | from adapter.print import Print 3 | 4 | 5 | class PrintBanner(Banner, Print): 6 | def __init__(self, string): 7 | super(PrintBanner, self).__init__(string) 8 | 9 | def printWeak(self): 10 | self.showWithParen() 11 | 12 | def printStrng(self): 13 | self.showWithAster() 14 | -------------------------------------------------------------------------------- /Adapter/Adapter_2_delegation/Main.py: -------------------------------------------------------------------------------- 1 | from adapter.print_banner import PrintBanner 2 | 3 | 4 | def startMain(): 5 | p = PrintBanner("Hello") 6 | p.printWeak() 7 | p.printStrng() 8 | 9 | 10 | if __name__ == '__main__': 11 | startMain() 12 | -------------------------------------------------------------------------------- /Adapter/Adapter_2_delegation/adapter/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Adapter/Adapter_2_delegation/adapter/__init__.py -------------------------------------------------------------------------------- /Adapter/Adapter_2_delegation/adapter/banner.py: -------------------------------------------------------------------------------- 1 | class Banner(object): 2 | def __init__(self, string): 3 | self.__string = string 4 | 5 | def showWithParen(self): 6 | print("({0})".format(self.__string)) 7 | 8 | def showWithAster(self): 9 | print("*{0}*".format(self.__string)) 10 | -------------------------------------------------------------------------------- /Adapter/Adapter_2_delegation/adapter/print.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Print(metaclass=ABCMeta): 5 | @abstractmethod 6 | def printWeak(self): 7 | pass 8 | 9 | @abstractmethod 10 | def printStrng(self): 11 | pass 12 | -------------------------------------------------------------------------------- /Adapter/Adapter_2_delegation/adapter/print_banner.py: -------------------------------------------------------------------------------- 1 | from adapter.banner import Banner 2 | from adapter.print import Print 3 | 4 | 5 | class PrintBanner(Print): 6 | def __init__(self, string): 7 | self.__banner = Banner(string) 8 | 9 | def printWeak(self): 10 | self.__banner.showWithParen() 11 | 12 | def printStrng(self): 13 | self.__banner.showWithAster() 14 | -------------------------------------------------------------------------------- /Bridge/Main.py: -------------------------------------------------------------------------------- 1 | from bridge.function.display_func import DisplayFunc 2 | from bridge.function.display_count_func import DisplayCountFunc 3 | from bridge.function.display_random_func import DisplayRandomFunc 4 | from bridge.implement.display_string_impl import DisplayStringImpl 5 | from bridge.implement.display_textfile_impl import DisplayTextfileImpl 6 | 7 | 8 | def startMain(): 9 | d1 = DisplayFunc(DisplayStringImpl("Hello Japan")) 10 | d2 = DisplayCountFunc(DisplayStringImpl("Hello Japan")) 11 | d3 = DisplayCountFunc(DisplayStringImpl("Hello Universe")) 12 | d4 = DisplayRandomFunc(DisplayStringImpl("Hello Universe")) 13 | d5 = DisplayFunc(DisplayTextfileImpl("test.txt")) 14 | d1.display() 15 | d2.display() 16 | d3.display() 17 | d3.multiDisplay(5) 18 | d4.randomDisplay(5) 19 | d5.display() 20 | 21 | 22 | if __name__ == '__main__': 23 | startMain() 24 | -------------------------------------------------------------------------------- /Bridge/bridge/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Bridge/bridge/__init__.py -------------------------------------------------------------------------------- /Bridge/bridge/function/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Bridge/bridge/function/__init__.py -------------------------------------------------------------------------------- /Bridge/bridge/function/display_count_func.py: -------------------------------------------------------------------------------- 1 | from bridge.function.display_func import DisplayFunc 2 | 3 | 4 | class DisplayCountFunc(DisplayFunc): 5 | def __init__(self, impl): 6 | super(DisplayCountFunc, self).__init__(impl) 7 | 8 | def multiDisplay(self, times): 9 | self.open() 10 | for _ in range(times): 11 | self.print_body() 12 | self.close() 13 | -------------------------------------------------------------------------------- /Bridge/bridge/function/display_func.py: -------------------------------------------------------------------------------- 1 | class DisplayFunc(object): 2 | def __init__(self, impl): 3 | self.impl = impl 4 | 5 | def open(self): 6 | self.impl.rawOpen() 7 | 8 | def print_body(self): 9 | self.impl.rawPrint() 10 | 11 | def close(self): 12 | self.impl.rawClose() 13 | 14 | def display(self): 15 | self.open() 16 | self.print_body() 17 | self.close() 18 | -------------------------------------------------------------------------------- /Bridge/bridge/function/display_random_func.py: -------------------------------------------------------------------------------- 1 | import random 2 | from bridge.function.display_func import DisplayFunc 3 | 4 | 5 | class DisplayRandomFunc(DisplayFunc): 6 | def __init__(self, impl): 7 | super(DisplayRandomFunc, self).__init__(impl) 8 | 9 | def randomDisplay(self, times): 10 | self.open() 11 | t = random.randint(0, times) 12 | for _ in range(t): 13 | self.print_body() 14 | self.close() 15 | -------------------------------------------------------------------------------- /Bridge/bridge/implement/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Bridge/bridge/implement/__init__.py -------------------------------------------------------------------------------- /Bridge/bridge/implement/display_impl.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class DisplayImpl(metaclass=ABCMeta): 5 | @abstractmethod 6 | def rawOpen(self): 7 | pass 8 | 9 | @abstractmethod 10 | def rawPrint(self): 11 | pass 12 | 13 | @abstractmethod 14 | def rawClose(self): 15 | pass -------------------------------------------------------------------------------- /Bridge/bridge/implement/display_string_impl.py: -------------------------------------------------------------------------------- 1 | from bridge.implement.display_impl import DisplayImpl 2 | 3 | 4 | class DisplayStringImpl(DisplayImpl): 5 | def __init__(self, string): 6 | self.string = string 7 | self.width = len(string) 8 | 9 | def rawOpen(self): 10 | self.printLine() 11 | 12 | def rawPrint(self): 13 | print("|{0}|".format(self.string)) 14 | 15 | def rawClose(self): 16 | self.printLine() 17 | print("") 18 | 19 | def printLine(self): 20 | line = '-' * self.width 21 | print("+{0}+".format(line)) 22 | -------------------------------------------------------------------------------- /Bridge/bridge/implement/display_textfile_impl.py: -------------------------------------------------------------------------------- 1 | from bridge.implement.display_impl import DisplayImpl 2 | 3 | 4 | class DisplayTextfileImpl(DisplayImpl): 5 | def __init__(self, filename): 6 | self.filename = filename 7 | 8 | def rawOpen(self): 9 | filename = self.filename 10 | self.f = open(filename, "r") 11 | 12 | def rawPrint(self): 13 | data = self.f.read() 14 | data = data.split('\n') 15 | for l in data: 16 | print(l) 17 | 18 | def rawClose(self): 19 | self.f.close() 20 | -------------------------------------------------------------------------------- /Bridge/test.txt: -------------------------------------------------------------------------------- 1 | aaa 2 | bbb 3 | ccc 4 | ddd 5 | eee 6 | fff 7 | ggg -------------------------------------------------------------------------------- /Builder/Greeting.html: -------------------------------------------------------------------------------- 1 | Greeting

    Greeting

    From the morning to the afternoon

    In the evening

    -------------------------------------------------------------------------------- /Builder/Main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from builder.director import Director 4 | from builder.textbuilder.text_builder import TextBuilder 5 | from builder.htmlbuilder.html_builder import HTMLBuilder 6 | 7 | 8 | def startMain(opt): 9 | if opt == "plain": 10 | builder = TextBuilder() 11 | director = Director(builder) 12 | director.construct() 13 | result = builder.getResult() 14 | print(result) 15 | elif opt == "html": 16 | builder = HTMLBuilder() 17 | director = Director(builder) 18 | director.construct() 19 | result = builder.getResult() 20 | print("[" + result + "]" + " was created.") 21 | 22 | 23 | if __name__ == "__main__": 24 | startMain(sys.argv[1]) 25 | -------------------------------------------------------------------------------- /Builder/builder/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Builder/builder/__init__.py -------------------------------------------------------------------------------- /Builder/builder/builder.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Builder(metaclass=ABCMeta): 5 | @abstractmethod 6 | def makeTitle(self, title): 7 | pass 8 | 9 | @abstractmethod 10 | def makeString(self, str): 11 | pass 12 | 13 | @abstractmethod 14 | def makeItems(self, items): 15 | pass 16 | 17 | @abstractmethod 18 | def close(self): 19 | pass 20 | -------------------------------------------------------------------------------- /Builder/builder/director.py: -------------------------------------------------------------------------------- 1 | class Director(object): 2 | def __init__(self, builder): 3 | self.__builder = builder 4 | 5 | def construct(self): 6 | self.__builder.makeTitle("Greeting") 7 | self.__builder.makeString("From the morning to the afternoon") 8 | self.__builder.makeItems(["Good morning", "Hello"]) 9 | self.__builder.makeString("In the evening") 10 | self.__builder.makeItems(["Good evening", "Good night", "Good bye"]) 11 | self.__builder.close() 12 | -------------------------------------------------------------------------------- /Builder/builder/htmlbuilder/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Builder/builder/htmlbuilder/__init__.py -------------------------------------------------------------------------------- /Builder/builder/htmlbuilder/html_builder.py: -------------------------------------------------------------------------------- 1 | from builder.builder import Builder 2 | 3 | 4 | class HTMLBuilder(Builder): 5 | def __init__(self): 6 | self.buffer = [] 7 | self.filename = "" 8 | self.f = None 9 | self.makeTitleCalled = False 10 | 11 | def makeTitle(self, title): 12 | self.filename = title+".html" 13 | self.f = open(self.filename, "w") 14 | self.f.write(""+title+"") 15 | self.f.write("

    "+title+"

    ") 16 | self.makeTitleCalled = True 17 | 18 | def makeString(self, str): 19 | if not self.makeTitleCalled: 20 | raise RuntimeError 21 | self.f.write("

    "+str+"

    ") 22 | 23 | def makeItems(self, items): 24 | if not self.makeTitleCalled: 25 | raise RuntimeError 26 | self.f.write("") 30 | 31 | def close(self): 32 | if not self.makeTitleCalled: 33 | raise RuntimeError 34 | self.f.write("") 35 | self.f.close() 36 | 37 | def getResult(self): 38 | return self.filename 39 | -------------------------------------------------------------------------------- /Builder/builder/textbuilder/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Builder/builder/textbuilder/__init__.py -------------------------------------------------------------------------------- /Builder/builder/textbuilder/text_builder.py: -------------------------------------------------------------------------------- 1 | from builder.builder import Builder 2 | 3 | 4 | class TextBuilder(Builder): 5 | def __init__(self): 6 | self.buffer = [] 7 | 8 | def makeTitle(self, title): 9 | self.buffer.append("======================\n") 10 | self.buffer.append(title + "\n") 11 | self.buffer.append("\n") 12 | 13 | def makeString(self, str): 14 | self.buffer.append("*** " + str + " ***" + "\n") 15 | 16 | def makeItems(self, items): 17 | for i in items: 18 | self.buffer.append("- " + i + "\n") 19 | 20 | def close(self): 21 | self.buffer.append("======================\n") 22 | 23 | def getResult(self): 24 | return ''.join(self.buffer) -------------------------------------------------------------------------------- /Chain_of_Responsibility/Main.py: -------------------------------------------------------------------------------- 1 | from support import NoSupport, LimitSupport, SpecialSupport, OddSupport 2 | from trouble import Trouble 3 | 4 | 5 | def startMain(): 6 | alice = NoSupport("Alice") 7 | bob = LimitSupport("Bob", 100) 8 | charlie = SpecialSupport("Charlie", 429) 9 | diana = LimitSupport("Diana", 200) 10 | elmo = OddSupport("Elmo") 11 | fred = LimitSupport("Fred", 300) 12 | 13 | alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred) 14 | 15 | for i in range(0, 500, 33): 16 | alice.support(Trouble(i)) 17 | 18 | 19 | if __name__ == '__main__': 20 | startMain() 21 | -------------------------------------------------------------------------------- /Chain_of_Responsibility/support.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Support(metaclass=ABCMeta): 5 | def __init__(self, name): 6 | self.__name = name 7 | self.__next = None 8 | 9 | def setNext(self, next): 10 | self.__next = next 11 | return next 12 | 13 | def support(self, trouble): 14 | if self.resolve(trouble): 15 | self.done(trouble) 16 | elif self.__next is not None: 17 | self.__next.support(trouble) 18 | else: 19 | self.fail(trouble) 20 | 21 | def __str__(self): 22 | return "[{0}]".format(self.__name) 23 | 24 | @abstractmethod 25 | def resolve(self, trouble): 26 | pass 27 | 28 | def done(self, trouble): 29 | print("{0} is resolved by {1}.".format(trouble, self)) 30 | 31 | def fail(self, trouble): 32 | print("{0} cannot be resolved.".format(trouble)) 33 | 34 | 35 | class NoSupport(Support): 36 | def __init__(self, name): 37 | super(NoSupport, self).__init__(name) 38 | 39 | def resolve(self, trouble): 40 | return False 41 | 42 | 43 | class LimitSupport(Support): 44 | def __init__(self, name, limit): 45 | super(LimitSupport, self).__init__(name) 46 | self.__limit = limit 47 | 48 | def resolve(self, trouble): 49 | return True if trouble.getNumber() < self.__limit else False 50 | 51 | 52 | class OddSupport(Support): 53 | def __init__(self, name): 54 | super(OddSupport, self).__init__(name) 55 | 56 | def resolve(self, trouble): 57 | return True if trouble.getNumber() % 2 == 1 else False 58 | 59 | 60 | class SpecialSupport(Support): 61 | def __init__(self, name, number): 62 | super(SpecialSupport, self).__init__(name) 63 | self.__number = number 64 | 65 | def resolve(self, trouble): 66 | return True if trouble.getNumber() == self.__number else False 67 | -------------------------------------------------------------------------------- /Chain_of_Responsibility/trouble.py: -------------------------------------------------------------------------------- 1 | class Trouble: 2 | def __init__(self, number): 3 | self.__number = number 4 | 5 | def getNumber(self): 6 | return self.__number 7 | 8 | def __str__(self): 9 | return '[Trouble {0}]'.format(self.__number) 10 | -------------------------------------------------------------------------------- /Command/Main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from command.command import FileOperator, CompositeCommand, FileTouchCommand, ChmodCommand 3 | 4 | 5 | def startMain(filename, permission): 6 | recv = FileOperator() 7 | cc = CompositeCommand() 8 | cc.append_cmd(FileTouchCommand(filename, recv)) 9 | cc.append_cmd(ChmodCommand(filename, permission, recv)) 10 | cc.execute() 11 | cc.display() 12 | 13 | 14 | if __name__ == "__main__": 15 | startMain(sys.argv[1], int(sys.argv[2], 8)) 16 | -------------------------------------------------------------------------------- /Command/command/command.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from abc import ABCMeta, abstractmethod 3 | 4 | 5 | class Command(metaclass=ABCMeta): 6 | @abstractmethod 7 | def execute(self): 8 | pass 9 | 10 | @abstractmethod 11 | def display(self): 12 | pass 13 | 14 | 15 | class FileOperator(object): 16 | def createFile(self, filename): 17 | Path(filename).touch() 18 | 19 | def changeFileMode(self, filename, permission): 20 | Path(filename).chmod(permission) 21 | 22 | 23 | class CompositeCommand(Command): 24 | def __init__(self): 25 | self.__cmds = [] 26 | 27 | def append_cmd(self, cmd): 28 | self.__cmds.append(cmd) 29 | 30 | def execute(self): 31 | for cmd in self.__cmds: 32 | cmd.execute() 33 | 34 | def display(self): 35 | for cmd in self.__cmds: 36 | cmd.display() 37 | 38 | 39 | class FileTouchCommand(Command): 40 | def __init__(self, filename, receiverObj): 41 | self.__filename = filename 42 | self.__receiver = receiverObj 43 | 44 | def execute(self): 45 | self.__receiver.createFile(self.__filename) 46 | 47 | def display(self): 48 | print("% touch {0}".format(self.__filename)) 49 | 50 | 51 | class ChmodCommand(Command): 52 | def __init__(self, filename, permission, receiverObj): 53 | self.__filename = filename 54 | self.__permission = permission 55 | self.__receiver = receiverObj 56 | 57 | def execute(self): 58 | self.__receiver.changeFileMode(self.__filename, self.__permission) 59 | 60 | def display(self): 61 | permission = format(self.__permission, 'o') 62 | print("% chmod {0} {1}".format(permission, self.__filename)) 63 | -------------------------------------------------------------------------------- /Composite/Main.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | from entry import Directory, File, FileTreatmentException 3 | 4 | 5 | def startMain(): 6 | try: 7 | print("Making root entries...") 8 | rootdir = Directory("root") 9 | bindir = Directory("bin") 10 | tmpdir = Directory("tmp") 11 | usrdir = Directory("usr") 12 | 13 | rootdir.add(bindir) 14 | rootdir.add(tmpdir) 15 | rootdir.add(usrdir) 16 | 17 | bindir.add(File("vi", 10000)) 18 | bindir.add(File("latex", 20000)) 19 | rootdir.printList() 20 | 21 | print("") 22 | print("Making user entries...") 23 | yuki = Directory("yuki") 24 | hanako = Directory("hanako") 25 | tomura = Directory("tomura") 26 | 27 | usrdir.add(yuki) 28 | usrdir.add(hanako) 29 | usrdir.add(tomura) 30 | 31 | yuki.add(File("diary.html", 100)) 32 | yuki.add(File("Composite.java", 200)) 33 | hanako.add(File("memo.tex", 300)) 34 | tomura.add(File("game.doc", 400)) 35 | tomura.add(File("junk.mail", 500)) 36 | rootdir.printList() 37 | 38 | print("") 39 | print("Occurring Exception...") 40 | tmpfile = File("tmp.txt", 100) 41 | bindir = Directory("bin") 42 | tmpfile.add(bindir) 43 | except FileTreatmentException as ex: 44 | print(ex.message) 45 | 46 | 47 | if __name__ == '__main__': 48 | startMain() 49 | -------------------------------------------------------------------------------- /Composite/entry.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Entry(metaclass=ABCMeta): 5 | @abstractmethod 6 | def getName(self): 7 | pass 8 | 9 | @abstractmethod 10 | def getSize(self): 11 | pass 12 | 13 | def add(self, entry): 14 | raise FileTreatmentException 15 | 16 | def printList(self): 17 | self._printList() 18 | 19 | @abstractmethod 20 | def _printList(self, prefix=''): 21 | pass 22 | 23 | def __str__(self): 24 | return "{0} ({1})".format(self.getName(), self.getSize()) 25 | 26 | 27 | class File(Entry): 28 | def __init__(self, name, size): 29 | self.name = name 30 | self.size = size 31 | 32 | def getName(self): 33 | return self.name 34 | 35 | def getSize(self): 36 | return self.size 37 | 38 | def _printList(self, prefix=''): 39 | print("{0}/{1}".format(prefix, self)) 40 | 41 | 42 | class Directory(Entry): 43 | def __init__(self, name): 44 | self.name = name 45 | self.directory = [] 46 | 47 | def getName(self): 48 | return self.name 49 | 50 | def getSize(self): 51 | size = 0 52 | for d in self.directory: 53 | size += d.getSize() 54 | return size 55 | 56 | def add(self, entry): 57 | entry.path = self.name 58 | self.directory.append(entry) 59 | 60 | def _printList(self, prefix=''): 61 | print(prefix + "/" + str(self)) 62 | for e in self.directory: 63 | e._printList(prefix + '/' + self.name) 64 | 65 | 66 | class FileTreatmentException(Exception): 67 | def __init__(self,*args,**kwargs): 68 | self.message = "FileTreatmentException" 69 | -------------------------------------------------------------------------------- /Decorator/step1/Main.py: -------------------------------------------------------------------------------- 1 | from decorator.display import StringDisplay 2 | from decorator.border import SideBorder, FullBorder 3 | 4 | 5 | def startMain(): 6 | b1 = StringDisplay('Hello, world.') 7 | b2 = SideBorder(b1, '#') 8 | b3 = FullBorder(b2) 9 | b1.show() 10 | b2.show() 11 | b3.show() 12 | print("") 13 | b4 = SideBorder( 14 | FullBorder( 15 | FullBorder( 16 | SideBorder( 17 | FullBorder( 18 | StringDisplay('HELLO') 19 | ), 20 | '*' 21 | ) 22 | ) 23 | ), 24 | '/' 25 | ) 26 | b4.show() 27 | 28 | 29 | if __name__ == '__main__': 30 | startMain() 31 | -------------------------------------------------------------------------------- /Decorator/step1/decorator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Decorator/step1/decorator/__init__.py -------------------------------------------------------------------------------- /Decorator/step1/decorator/border.py: -------------------------------------------------------------------------------- 1 | from decorator.display import Display 2 | 3 | 4 | class Border(Display): 5 | def __init__(self, display): 6 | self.display = display 7 | 8 | 9 | class SideBorder(Border): 10 | def __init__(self, display, ch): 11 | super(SideBorder, self).__init__(display) 12 | self.__borderChar = ch 13 | 14 | def getColumns(self): 15 | return 1 + self.display.getColumns() + 1 16 | 17 | def getRows(self): 18 | return self.display.getRows() 19 | 20 | def getRowText(self, row): 21 | return self.__borderChar + self.display.getRowText(row) + self.__borderChar 22 | 23 | 24 | class FullBorder(Border): 25 | def __init__(self, display): 26 | super(FullBorder, self).__init__(display) 27 | 28 | def getColumns(self): 29 | return 1 + self.display.getColumns() + 1 30 | 31 | def getRows(self): 32 | return 1 + self.display.getRows() + 1 33 | 34 | def getRowText(self, row): 35 | if row == 0: 36 | return '+' + self.__make_line('-', self.display.getColumns()) + '+' 37 | elif row == self.display.getRows() + 1: 38 | return '+' + self.__make_line('-', self.display.getColumns()) + '+' 39 | else: 40 | return '|' + self.display.getRowText(row - 1) + '|' 41 | 42 | def __make_line(self, char, count): 43 | buf = '' 44 | for _ in range(count): 45 | buf += char 46 | return buf 47 | -------------------------------------------------------------------------------- /Decorator/step1/decorator/display.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Display(metaclass=ABCMeta): 5 | @abstractmethod 6 | def getColumns(self): 7 | pass 8 | 9 | @abstractmethod 10 | def getRows(self): 11 | pass 12 | 13 | @abstractmethod 14 | def getRowText(self, row): 15 | pass 16 | 17 | def show(self): 18 | for i in range(self.getRows()): 19 | print(self.getRowText(i)) 20 | 21 | 22 | class StringDisplay(Display): 23 | def __init__(self, string): 24 | self.string = string 25 | 26 | def getColumns(self): 27 | return len(self.string) 28 | 29 | def getRows(self): 30 | return 1 31 | 32 | def getRowText(self, row): 33 | if row == 0: 34 | return self.string 35 | else: 36 | return None 37 | -------------------------------------------------------------------------------- /Decorator/step2/Main.py: -------------------------------------------------------------------------------- 1 | from decorator.display import StringDisplay, className 2 | from decorator.border import FullBorder, SideBorder 3 | 4 | 5 | def startMain(): 6 | @FullBorder 7 | @SideBorder 8 | @StringDisplay 9 | def dummy1(): 10 | className[2].show() 11 | className[1].show() 12 | className[0].show() 13 | dummy1() 14 | print("") 15 | className.clear() 16 | 17 | @SideBorder 18 | @FullBorder 19 | @FullBorder 20 | @SideBorder 21 | @FullBorder 22 | @StringDisplay 23 | def dummy2(): 24 | className[0].show() 25 | dummy2() 26 | 27 | 28 | if __name__ == '__main__': 29 | startMain() 30 | -------------------------------------------------------------------------------- /Decorator/step2/decorator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Decorator/step2/decorator/__init__.py -------------------------------------------------------------------------------- /Decorator/step2/decorator/border.py: -------------------------------------------------------------------------------- 1 | from decorator.display import Display, className 2 | 3 | 4 | class Border(Display): 5 | def __init__(self, display): 6 | self.display = display 7 | super(Border, self).__init__() 8 | 9 | 10 | class SideBorder(Border): 11 | def __init__(self, func): 12 | self.func = func 13 | self.__borderChar = '#' 14 | super(SideBorder, self).__init__(func) 15 | 16 | def getColumns(self): 17 | return 1 + self.display.getColumns() + 1 18 | 19 | def getRows(self): 20 | return self.display.getRows() 21 | 22 | def getRowText(self, row): 23 | return self.__borderChar + self.display.getRowText(row) + self.__borderChar 24 | 25 | def __call__(self): 26 | global className 27 | className.append(self) 28 | return self.func() 29 | 30 | 31 | class FullBorder(Border): 32 | def __init__(self, func): 33 | self.func = func 34 | super(FullBorder, self).__init__(func) 35 | 36 | def getColumns(self): 37 | return 1 + self.display.getColumns() + 1 38 | 39 | def getRows(self): 40 | return 1 + self.display.getRows() + 1 41 | 42 | def getRowText(self, row): 43 | if row == 0: 44 | return '+' + self.__make_line('-', self.display.getColumns()) + '+' 45 | elif row == self.display.getRows() + 1: 46 | return '+' + self.__make_line('-', self.display.getColumns()) + '+' 47 | else: 48 | return '|' + self.display.getRowText(row - 1) + '|' 49 | 50 | def __make_line(self, char, count): 51 | buf = '' 52 | for _ in range(count): 53 | buf += char 54 | return buf 55 | 56 | def __call__(self): 57 | global className 58 | className.append(self) 59 | return self.func() 60 | -------------------------------------------------------------------------------- /Decorator/step2/decorator/display.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | className = [] 4 | 5 | 6 | class Display(metaclass=ABCMeta): 7 | @abstractmethod 8 | def getColumns(self): 9 | pass 10 | 11 | @abstractmethod 12 | def getRows(self): 13 | pass 14 | 15 | @abstractmethod 16 | def getRowText(self, row): 17 | pass 18 | 19 | def show(self): 20 | for i in range(self.getRows()): 21 | print(self.getRowText(i)) 22 | 23 | class StringDisplay(Display): 24 | def __init__(self, func): 25 | self.string = "Hello, world." 26 | self.func = func 27 | super(StringDisplay, self).__init__() 28 | 29 | def getColumns(self): 30 | return len(self.string) 31 | 32 | def getRows(self): 33 | return 1 34 | 35 | def getRowText(self, row): 36 | if row == 0: 37 | return self.string 38 | else: 39 | return None 40 | 41 | def __call__(self): 42 | global className 43 | className.append(self) 44 | return self.func() 45 | -------------------------------------------------------------------------------- /Decorator/step3/Main.py: -------------------------------------------------------------------------------- 1 | from decorator.display import StringDisplay_filter, className 2 | from decorator.border import SideBorder_filter, FullBorder 3 | 4 | 5 | def startMain(): 6 | @FullBorder 7 | @SideBorder_filter('#') 8 | @StringDisplay_filter("Hello, world.") 9 | def dummy1(): 10 | className[2].show() 11 | className[1].show() 12 | className[0].show() 13 | dummy1() 14 | print("") 15 | className.clear() 16 | 17 | @SideBorder_filter('/') 18 | @FullBorder 19 | @FullBorder 20 | @SideBorder_filter('*') 21 | @FullBorder 22 | @StringDisplay_filter("HELLO") 23 | def dummy2(): 24 | className[0].show() 25 | dummy2() 26 | 27 | 28 | if __name__ == '__main__': 29 | startMain() 30 | -------------------------------------------------------------------------------- /Decorator/step3/decorator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Decorator/step3/decorator/__init__.py -------------------------------------------------------------------------------- /Decorator/step3/decorator/border.py: -------------------------------------------------------------------------------- 1 | from decorator.display import Display, className 2 | 3 | 4 | class Border(Display): 5 | def __init__(self, display): 6 | self.display = display 7 | super(Border, self).__init__() 8 | 9 | 10 | class SideBorder(Border): 11 | def __init__(self, func, ch): 12 | self.func = func 13 | self.__borderChar = ch 14 | super(SideBorder, self).__init__(func) 15 | 16 | def getColumns(self): 17 | return 1 + self.display.getColumns() + 1 18 | 19 | def getRows(self): 20 | return self.display.getRows() 21 | 22 | def getRowText(self, row): 23 | return self.__borderChar + self.display.getRowText(row) + self.__borderChar 24 | 25 | def __call__(self): 26 | global className 27 | className.append(self) 28 | return self.func() 29 | 30 | def SideBorder_filter(ch): 31 | def filter(func): 32 | return SideBorder(func, ch) 33 | return filter 34 | 35 | class FullBorder(Border): 36 | def __init__(self, func): 37 | self.func = func 38 | super(FullBorder, self).__init__(func) 39 | 40 | def getColumns(self): 41 | return 1 + self.display.getColumns() + 1 42 | 43 | def getRows(self): 44 | return 1 + self.display.getRows() + 1 45 | 46 | def getRowText(self, row): 47 | if row == 0: 48 | return '+' + self.__make_line('-', self.display.getColumns()) + '+' 49 | elif row == self.display.getRows() + 1: 50 | return '+' + self.__make_line('-', self.display.getColumns()) + '+' 51 | else: 52 | return '|' + self.display.getRowText(row - 1) + '|' 53 | 54 | def __make_line(self, char, count): 55 | buf = '' 56 | for _ in range(count): 57 | buf += char 58 | return buf 59 | 60 | def __call__(self): 61 | global className 62 | className.append(self) 63 | return self.func() 64 | -------------------------------------------------------------------------------- /Decorator/step3/decorator/display.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | className = [] 4 | 5 | 6 | class Display(metaclass=ABCMeta): 7 | @abstractmethod 8 | def getColumns(self): 9 | pass 10 | 11 | @abstractmethod 12 | def getRows(self): 13 | pass 14 | 15 | @abstractmethod 16 | def getRowText(self, row): 17 | pass 18 | 19 | def show(self): 20 | for i in range(self.getRows()): 21 | print(self.getRowText(i)) 22 | 23 | class StringDisplay(Display): 24 | def __init__(self, func, string): 25 | self.string = string 26 | self.func = func 27 | super(StringDisplay, self).__init__() 28 | 29 | def getColumns(self): 30 | return len(self.string) 31 | 32 | def getRows(self): 33 | return 1 34 | 35 | def getRowText(self, row): 36 | if row == 0: 37 | return self.string 38 | else: 39 | return None 40 | 41 | def __call__(self): 42 | global className 43 | className.append(self) 44 | return self.func() 45 | 46 | 47 | def StringDisplay_filter(string): 48 | def filter(func): 49 | return StringDisplay(func, string) 50 | return filter 51 | -------------------------------------------------------------------------------- /Facade/Main.py: -------------------------------------------------------------------------------- 1 | from pagemaker.page_maker import PageMaker 2 | 3 | 4 | def startMain(): 5 | PageMaker.makeWelcomePage("hyuki@hyuki.com", "welcome1.html") 6 | PageMaker.makeWelcomePage("mamoru@hyuki.com", "welcome2.html") 7 | 8 | 9 | if __name__ == '__main__': 10 | startMain() -------------------------------------------------------------------------------- /Facade/maildata.ini: -------------------------------------------------------------------------------- 1 | [MailAddress] 2 | hyuki@hyuki.com = Hiroshi Yuki 3 | hanako@hyuki.com = Hananko Sato 4 | tomura@hyuki.com = Tomura 5 | mamoru@hyuki.com = Mamoru Takahashi -------------------------------------------------------------------------------- /Facade/pagemaker/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Facade/pagemaker/__init__.py -------------------------------------------------------------------------------- /Facade/pagemaker/database.py: -------------------------------------------------------------------------------- 1 | from configparser import ConfigParser 2 | 3 | 4 | class Database(object): 5 | @classmethod 6 | def getProperties(cls, dbname): 7 | filename = dbname + ".ini" 8 | conf = ConfigParser() 9 | try: 10 | conf.read(filename) 11 | return conf["MailAddress"] 12 | except Exception: 13 | print("Warning: [{0}] is not found.".format(filename)) 14 | -------------------------------------------------------------------------------- /Facade/pagemaker/html_writer.py: -------------------------------------------------------------------------------- 1 | class HtmlWriter(object): 2 | def __init__(self, writer): 3 | self.writer = writer 4 | 5 | def title(self, title): 6 | self.writer.write("\n") 7 | self.writer.write("") 8 | self.writer.write("{0}".format(title)) 9 | self.writer.write("\n") 10 | self.writer.write("\n") 11 | self.writer.write("

    {0}

    \n".format(title)) 12 | 13 | def paragraph(self, msg): 14 | self.writer.write("

    {0}

    \n".format(msg)) 15 | 16 | def link(self, href, caption): 17 | self.writer.write("{1}".format(href, caption)) 18 | 19 | def mailto(self, mailaddr, username): 20 | self.link("mailto:{0}".format(mailaddr), username) 21 | 22 | def close(self): 23 | self.writer.write("\n") 24 | self.writer.write("\n") 25 | self.writer.close() 26 | -------------------------------------------------------------------------------- /Facade/pagemaker/page_maker.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import json 3 | from pagemaker.database import Database 4 | from pagemaker.html_writer import HtmlWriter 5 | 6 | 7 | class PageMaker(object): 8 | @classmethod 9 | def makeWelcomePage(cls, mailaddr, filename): 10 | try: 11 | prop = Database.getProperties('maildata') 12 | username =prop[mailaddr] 13 | writer = HtmlWriter(open(filename, 'w')) 14 | writer.title('Welcom to {}s page!'.format(username)) 15 | writer.paragraph("We'll wait for your sending") 16 | writer.mailto(mailaddr, username) 17 | writer.close() 18 | print('{} is created for {} ({})'.format(filename, mailaddr, username)) 19 | except Exception: 20 | print("# Failure occurred") 21 | -------------------------------------------------------------------------------- /Facade/welcome1.html: -------------------------------------------------------------------------------- 1 | 2 | Welcom to Hiroshi Yukis page! 3 | 4 |

    Welcom to Hiroshi Yukis page!

    5 |

    We'll wait for your sending

    6 | Hiroshi Yuki 7 | 8 | -------------------------------------------------------------------------------- /Facade/welcome2.html: -------------------------------------------------------------------------------- 1 | 2 | Welcom to Mamoru Takahashis page! 3 | 4 |

    Welcom to Mamoru Takahashis page!

    5 |

    We'll wait for your sending

    6 | Mamoru Takahashi 7 | 8 | -------------------------------------------------------------------------------- /FactoryMethod/Main.py: -------------------------------------------------------------------------------- 1 | from framework.idcardfactory.id_card_factory import IDCardFactory 2 | 3 | 4 | def startMain(factoryObject): 5 | card1 = factoryObject.create("Hiroshi Yuki") 6 | card2 = factoryObject.create("Tomura") 7 | card3 = factoryObject.create("Hanako Sato") 8 | card1.use() 9 | card2.use() 10 | card3.use() 11 | 12 | if __name__ == "__main__": 13 | startMain(IDCardFactory()) -------------------------------------------------------------------------------- /FactoryMethod/framework/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/FactoryMethod/framework/__init__.py -------------------------------------------------------------------------------- /FactoryMethod/framework/factory.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Factory(metaclass=ABCMeta): 5 | def create(self, owner): 6 | p = self.createProduct(owner) 7 | self.registerProduct(p) 8 | return p 9 | 10 | @abstractmethod 11 | def createProduct(self, owner): 12 | pass 13 | 14 | @abstractmethod 15 | def registerProduct(self, product): 16 | pass 17 | 18 | 19 | class Product(metaclass=ABCMeta): 20 | @abstractmethod 21 | def use(self): 22 | pass 23 | -------------------------------------------------------------------------------- /FactoryMethod/framework/idcardfactory/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/FactoryMethod/framework/idcardfactory/__init__.py -------------------------------------------------------------------------------- /FactoryMethod/framework/idcardfactory/id_card_factory.py: -------------------------------------------------------------------------------- 1 | from framework.factory import Factory, Product 2 | 3 | 4 | class IDCardFactory(Factory): 5 | def __init__(self): 6 | self.owners = [] 7 | 8 | def createProduct(self, owner): 9 | return IDCardProduct(owner) 10 | 11 | def registerProduct(self, product): 12 | self.owners.append(product.owner) 13 | 14 | 15 | class IDCardProduct(Product): 16 | def __init__(self, owner): 17 | self.owner = owner 18 | print("I'll create {0}'s card".format(self.owner)) 19 | 20 | def use(self): 21 | print("I'll use {0}'s card".format(self.owner)) 22 | -------------------------------------------------------------------------------- /Flyweight/Main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from flyweight.big_char_factory import BigCharFactory, BigString 3 | 4 | def startMain(string): 5 | bs = BigString(string) 6 | bs.print() 7 | 8 | 9 | if __name__ == '__main__': 10 | startMain(sys.argv[1]) -------------------------------------------------------------------------------- /Flyweight/big0.txt: -------------------------------------------------------------------------------- 1 | ....######...... 2 | ..##......##.... 3 | ..##......##.... 4 | ..##......##.... 5 | ..##......##.... 6 | ..##......##.... 7 | ....######...... 8 | ................ -------------------------------------------------------------------------------- /Flyweight/big1.txt: -------------------------------------------------------------------------------- 1 | ......##........ 2 | ..######........ 3 | ......##........ 4 | ......##........ 5 | ......##........ 6 | ......##........ 7 | ..##########.... 8 | ................ -------------------------------------------------------------------------------- /Flyweight/big2.txt: -------------------------------------------------------------------------------- 1 | ....######...... 2 | ..##......##.... 3 | ..........##.... 4 | ......####...... 5 | ....##.......... 6 | ..##............ 7 | ..##########.... 8 | ................ -------------------------------------------------------------------------------- /Flyweight/big3.txt: -------------------------------------------------------------------------------- 1 | ....######...... 2 | ..##......##.... 3 | ..........##.... 4 | ......####...... 5 | ..........##.... 6 | ..##......##.... 7 | ....######...... 8 | ................ -------------------------------------------------------------------------------- /Flyweight/big4.txt: -------------------------------------------------------------------------------- 1 | ........##...... 2 | ......####...... 3 | ....##..##...... 4 | ..##....##...... 5 | ..##########.... 6 | ........##...... 7 | ......######.... 8 | ................ -------------------------------------------------------------------------------- /Flyweight/big5.txt: -------------------------------------------------------------------------------- 1 | ..##########.... 2 | ..##............ 3 | ..##............ 4 | ..########...... 5 | ..........##.... 6 | ..##......##.... 7 | ....######...... 8 | ................ -------------------------------------------------------------------------------- /Flyweight/big6.txt: -------------------------------------------------------------------------------- 1 | ....######...... 2 | ..##......##.... 3 | ..##............ 4 | ..########...... 5 | ..##......##.... 6 | ..##......##.... 7 | ....######...... 8 | ................ -------------------------------------------------------------------------------- /Flyweight/big7.txt: -------------------------------------------------------------------------------- 1 | ..##########.... 2 | ..##......##.... 3 | ..........##.... 4 | ........##...... 5 | ......##........ 6 | ......##........ 7 | ......##........ 8 | ................ -------------------------------------------------------------------------------- /Flyweight/big8.txt: -------------------------------------------------------------------------------- 1 | ....######...... 2 | ..##......##.... 3 | ..##......##.... 4 | ....######...... 5 | ..##......##.... 6 | ..##......##.... 7 | ....######...... 8 | ................ -------------------------------------------------------------------------------- /Flyweight/big9.txt: -------------------------------------------------------------------------------- 1 | ....######...... 2 | ..##......##.... 3 | ..##......##.... 4 | ....########.... 5 | ..........##.... 6 | ..##......##.... 7 | ....######...... 8 | ................ -------------------------------------------------------------------------------- /Flyweight/flyweight/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Flyweight/flyweight/__init__.py -------------------------------------------------------------------------------- /Flyweight/flyweight/big_char_factory.py: -------------------------------------------------------------------------------- 1 | class BigCharFactory(object): 2 | def __init__(self): 3 | self.__pool = {} 4 | 5 | @classmethod 6 | def getInstance(cls): 7 | if not hasattr(cls, "_instance"): 8 | cls._instance = cls() 9 | return cls._instance 10 | 11 | def getBigChar(self, charname): 12 | bc = self.__pool.get(charname) 13 | if bc is None: 14 | bc = BigChar(charname) 15 | self.__pool[charname] = bc 16 | return bc 17 | 18 | 19 | class BigString(object): 20 | def __init__(self, string): 21 | self.bigchars = [] 22 | self.factory = BigCharFactory.getInstance() 23 | for s in string: 24 | self.bigchars.append(self.factory.getBigChar(s)) 25 | 26 | def print(self): 27 | for bc in self.bigchars: 28 | print(bc) 29 | 30 | 31 | class BigChar(object): 32 | def __init__(self, charname): 33 | try: 34 | with open("big{0}.txt".format(charname), 'r') as txtfile: 35 | data = txtfile.read() 36 | self.__fontdata = data 37 | except IOError: 38 | self.__fontdata = charname + '?' 39 | 40 | def __str__(self): 41 | return self.__fontdata 42 | -------------------------------------------------------------------------------- /Iterator/step1/Main.py: -------------------------------------------------------------------------------- 1 | from iterator.book import Book, BookShelf 2 | 3 | 4 | def startMain(): 5 | bookShelf = BookShelf(4) 6 | bookShelf.append(Book(name="Aroun d the World in 80 days")) 7 | bookShelf.append(Book(name="Bible")) 8 | bookShelf.append(Book(name="Cinderella")) 9 | bookShelf.append(Book(name="Daddy-Long-Legs")) 10 | it = bookShelf.iterator() 11 | while it.hasNext(): 12 | book = it.next() 13 | print(book.getName()) 14 | 15 | 16 | if __name__ == '__main__': 17 | startMain() 18 | -------------------------------------------------------------------------------- /Iterator/step1/iterator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Iterator/step1/iterator/__init__.py -------------------------------------------------------------------------------- /Iterator/step1/iterator/aggregate.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Aggregate(metaclass=ABCMeta): 5 | @abstractmethod 6 | def iterator(self): 7 | pass 8 | -------------------------------------------------------------------------------- /Iterator/step1/iterator/book.py: -------------------------------------------------------------------------------- 1 | from iterator.iterator import Iterator 2 | from iterator.aggregate import Aggregate 3 | 4 | 5 | class Book(object): 6 | def __init__(self, name): 7 | self.__name = name 8 | 9 | def getName(self): 10 | return self.__name 11 | 12 | 13 | class BookShelfIterator(Iterator): 14 | def __init__(self, bookShelf): 15 | self.__bookShelf = bookShelf 16 | self.__index = 0 17 | 18 | def hasNext(self): 19 | return True if self.__index < self.__bookShelf.getLength() else False 20 | 21 | def next(self): 22 | book = self.__bookShelf.getBookAt(self.__index) 23 | self.__index += 1 24 | return book 25 | 26 | 27 | class BookShelf(Aggregate): 28 | def __init__(self, maxSize): 29 | self.__last = 0 30 | self.__books = [None] * maxSize 31 | 32 | def getBookAt(self, index): 33 | return self.__books[index] 34 | 35 | def append(self, book): 36 | self.__books[self.__last] = book 37 | self.__last += 1 38 | 39 | def getLength(self): 40 | return self.__last 41 | 42 | def iterator(self): 43 | return BookShelfIterator(self) 44 | -------------------------------------------------------------------------------- /Iterator/step1/iterator/iterator.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Iterator(metaclass=ABCMeta): 5 | @abstractmethod 6 | def hasNext(self): 7 | pass 8 | 9 | @abstractmethod 10 | def next(self): 11 | pass 12 | -------------------------------------------------------------------------------- /Iterator/step2/Main.py: -------------------------------------------------------------------------------- 1 | from iterator.book import Book, BookShelf 2 | 3 | 4 | def startMain(): 5 | bookShelf = BookShelf() 6 | bookShelf.append(Book(name="Aroun d the World in 80 days")) 7 | bookShelf.append(Book(name="Bible")) 8 | bookShelf.append(Book(name="Cinderella")) 9 | bookShelf.append(Book(name="Daddy-Long-Legs")) 10 | for book in bookShelf: 11 | print(book.getName()) 12 | 13 | 14 | if __name__ == '__main__': 15 | startMain() 16 | -------------------------------------------------------------------------------- /Iterator/step2/iterator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Iterator/step2/iterator/__init__.py -------------------------------------------------------------------------------- /Iterator/step2/iterator/book.py: -------------------------------------------------------------------------------- 1 | class Book(object): 2 | def __init__(self, name): 3 | self.__name = name 4 | 5 | def getName(self): 6 | return self.__name 7 | 8 | 9 | class BookShelf(object): 10 | def __init__(self): 11 | self.__books = [] 12 | 13 | def append(self, book): 14 | self.__books.append(book) 15 | 16 | def __iter__(self): 17 | self.__index = 0 18 | return self 19 | 20 | def __next__(self): 21 | if self.__index >= len(self.__books): 22 | raise StopIteration() 23 | book = self.__books[self.__index] 24 | self.__index += 1 25 | return book 26 | -------------------------------------------------------------------------------- /Mediator/Main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from mediator.mediator import ConcreteMediator 3 | from mediator.colleague import ConcreteColleagueTextArea, ConcreteColleagueButton 4 | 5 | 6 | def startMain(userid, password): 7 | m = ConcreteMediator() 8 | inputIdObj = ConcreteColleagueTextArea(m, "ID") 9 | inputPwObj = ConcreteColleagueTextArea(m, "PW") 10 | pushButtonObj = ConcreteColleagueButton(m, "Login") 11 | m.setColleagues(inputIdObj, inputPwObj, pushButtonObj) 12 | 13 | inputIdObj.inputText(userid) 14 | inputPwObj.inputText(password) 15 | if pushButtonObj.clickButton(): 16 | print("Login Succeed!!") 17 | else: 18 | print("Login Failed!!") 19 | 20 | 21 | def check_input_data(params): 22 | if len(params)==3: 23 | userid = params[1] 24 | password = params[2] 25 | elif len(params)==2: 26 | userid = params[1] 27 | password = None 28 | elif len(params)==1: 29 | userid = None 30 | password = None 31 | return userid, password 32 | 33 | 34 | if __name__ == "__main__": 35 | userid, password = check_input_data(sys.argv) 36 | startMain(userid, password) 37 | -------------------------------------------------------------------------------- /Mediator/mediator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Mediator/mediator/__init__.py -------------------------------------------------------------------------------- /Mediator/mediator/colleague.py: -------------------------------------------------------------------------------- 1 | from mediator.mediator import Mediator 2 | 3 | 4 | class Colleague(Mediator): 5 | def __init__(self, mediatorObj, name): 6 | self.mediator = mediatorObj 7 | self.name = name 8 | 9 | def on_change(self): 10 | if self.mediator is not None: 11 | self.mediator.on_change(self) 12 | 13 | 14 | class ConcreteColleagueButton(Colleague): 15 | def __init__(self, mediatorObj, name=None): 16 | super(ConcreteColleagueButton, self).__init__(mediatorObj, name) 17 | self.active = False 18 | 19 | def clickButton(self): 20 | if self.active: 21 | self.on_change() 22 | return self.mediator.authentication 23 | 24 | def checkButtonStatus(self): 25 | return self.active 26 | 27 | 28 | class ConcreteColleagueTextArea(Colleague): 29 | def __init__(self, mediatorObj, name=None): 30 | super(ConcreteColleagueTextArea, self).__init__(mediatorObj, name) 31 | self.text = None 32 | 33 | def inputText(self, text): 34 | self.text = text 35 | self.on_change() -------------------------------------------------------------------------------- /Mediator/mediator/mediator.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Mediator(metaclass=ABCMeta): 5 | @abstractmethod 6 | def on_change(self, component): 7 | pass 8 | 9 | 10 | class ConcreteMediator(Mediator): 11 | def __init__(self): 12 | self.authentication = False 13 | 14 | def setColleagues(self, inputIdObj, inputPwObj, buttonObj): 15 | self.inputIdObj = inputIdObj 16 | self.inputPwObj = inputPwObj 17 | self.buttonObj = buttonObj 18 | 19 | def on_change(self, component): 20 | if component.name == "ID" or component.name == "PW": 21 | self.__refreshButton() 22 | elif component.name == "Login": 23 | self.__authentication() 24 | 25 | def __refreshButton(self): 26 | if self.inputIdObj.text is not None and self.inputPwObj.text is not None: 27 | print("(Active login button)") 28 | self.buttonObj.active = True 29 | 30 | def __authentication(self): 31 | if self.inputIdObj.text == "hoge" and self.inputPwObj.text == "fuga": 32 | print("(ID/PW is confirmed)") 33 | self.authentication = True 34 | else: 35 | print("(ID/PW is incorrect)") 36 | -------------------------------------------------------------------------------- /Memento/Main.py: -------------------------------------------------------------------------------- 1 | import time 2 | from memento.gamer import Gamer 3 | 4 | 5 | def startMain(): 6 | gamer = Gamer(100) 7 | memento = gamer.createMemento() 8 | 9 | for i in range(100): 10 | print("==== {0}".format(i)) 11 | print("現状:{0}".format(gamer)) 12 | gamer.bet() 13 | print("所持金は{0}円になりました".format(gamer.getMoney())) 14 | 15 | if gamer.getMoney() > memento.getMoney(): 16 | print(" (だいぶ増えたので、現在の状態を保存しておこう)") 17 | memento = gamer.createMemento() 18 | elif gamer.getMoney() < memento.getMoney() / 2: 19 | print(" (だいぶ減ったので、以前の状態に復帰しよう)") 20 | gamer.restoreMemento(memento) 21 | 22 | time.sleep(1) 23 | print("") 24 | 25 | 26 | if __name__ == '__main__': 27 | startMain() 28 | -------------------------------------------------------------------------------- /Memento/memento/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Memento/memento/__init__.py -------------------------------------------------------------------------------- /Memento/memento/gamer.py: -------------------------------------------------------------------------------- 1 | import random 2 | from memento.memento import Memento 3 | 4 | 5 | class Gamer(object): 6 | def __init__(self, money): 7 | self.__fruitname = ["リンゴ", "ぶどう", "バナナ", "みかん"] 8 | self.__money = money 9 | self.__fruits = [] 10 | 11 | def getMoney(self): 12 | return self.__money 13 | 14 | def bet(self): 15 | dice = random.randint(1, 6) 16 | if dice == 1: 17 | self.__money += 100 18 | print("所持金が増えました") 19 | elif dice == 2: 20 | self.__money //= 2 21 | print("所持金が半分になりました") 22 | elif dice == 6: 23 | f = self.__getFruit() 24 | print("フルーツ({0})をもらいました".format(f)) 25 | self.__fruits.append(f) 26 | else: 27 | print("何も起こりませんでした") 28 | 29 | def createMemento(self): 30 | m = Memento(self.__money) 31 | for f in self.__fruits: 32 | if f.startswith("おいしい"): 33 | m.addFruit(f) 34 | return m 35 | 36 | def restoreMemento(self, memento): 37 | self.__money = memento.money 38 | self.__fruits = memento.getFruits() 39 | 40 | def __str__(self): 41 | return "[money = {0}, fruits = {1}]".format(self.__money, self.__fruits) 42 | 43 | def __getFruit(self): 44 | prefix = '' 45 | if bool(random.getrandbits(1)): 46 | prefix = "おいしい" 47 | return prefix + random.choice(self.__fruitname) 48 | -------------------------------------------------------------------------------- /Memento/memento/memento.py: -------------------------------------------------------------------------------- 1 | class Memento(object): 2 | def __init__(self, money): 3 | self.money = money 4 | self.fruits = [] 5 | 6 | def getMoney(self): 7 | return self.money 8 | 9 | def addFruit(self, fruit): 10 | self.fruits.append(fruit) 11 | 12 | def getFruits(self): 13 | return self.fruits 14 | -------------------------------------------------------------------------------- /Observer/Main.py: -------------------------------------------------------------------------------- 1 | from observer.observer import DigitObserver, GraphObserver 2 | from observer.generator import RandomNumberGenerator 3 | 4 | 5 | def startMain(): 6 | generator = RandomNumberGenerator() 7 | observer1 = DigitObserver() 8 | observer2 = GraphObserver() 9 | generator.addObserver(observer1) 10 | generator.addObserver(observer2) 11 | generator.execute() 12 | 13 | 14 | if __name__ == '__main__': 15 | startMain() -------------------------------------------------------------------------------- /Observer/observer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Observer/observer/__init__.py -------------------------------------------------------------------------------- /Observer/observer/generator.py: -------------------------------------------------------------------------------- 1 | import random 2 | from abc import ABCMeta, abstractmethod 3 | 4 | 5 | class NumberGenerator(metaclass=ABCMeta): 6 | def __init__(self): 7 | self.__observers = [] 8 | 9 | def addObserver(self, observer): 10 | self.__observers.append(observer) 11 | 12 | def deleteObserver(self, observer): 13 | self.__observers.remove(observer) 14 | 15 | def notifyObserver(self): 16 | for o in self.__observers: 17 | o.update(self) 18 | 19 | @abstractmethod 20 | def getNumber(self): 21 | pass 22 | 23 | @abstractmethod 24 | def execute(self): 25 | pass 26 | 27 | 28 | class RandomNumberGenerator(NumberGenerator): 29 | def __init__(self): 30 | self.__number = 0 31 | super(RandomNumberGenerator, self).__init__() 32 | 33 | def getNumber(self): 34 | return self.__number 35 | 36 | def execute(self): 37 | for _ in range(20): 38 | self.__number = random.randint(0, 49) 39 | self.notifyObserver() 40 | -------------------------------------------------------------------------------- /Observer/observer/observer.py: -------------------------------------------------------------------------------- 1 | import time 2 | from abc import ABCMeta, abstractmethod 3 | 4 | 5 | class Observer(metaclass=ABCMeta): 6 | @abstractmethod 7 | def update(self, ganerator): 8 | pass 9 | 10 | 11 | class DigitObserver(Observer): 12 | def update(self, generator): 13 | print("DigitObservser: {0}".format(generator.getNumber())) 14 | time.sleep(0.1) 15 | 16 | 17 | class GraphObserver(Observer): 18 | def update(self, generator): 19 | print("GraphicObserver:", end='') 20 | count = generator.getNumber() 21 | for _ in range(count): 22 | print('*', end='') 23 | print("") 24 | time.sleep(0.1) 25 | -------------------------------------------------------------------------------- /Prototype/Main.py: -------------------------------------------------------------------------------- 1 | from framework.manager import Manager 2 | from framework.decoprototype.underline_pen_prototype import UnderlinePen 3 | from framework.decoprototype.message_box_prototype import MessageBox 4 | 5 | 6 | def startMain(managerObject): 7 | upen = UnderlinePen("-") 8 | mbox = MessageBox("*") 9 | sbox = MessageBox("/") 10 | managerObject.register("strong message", upen) 11 | managerObject.register("warning box", mbox) 12 | managerObject.register("slash box", sbox) 13 | 14 | p1 = managerObject.create("strong message") 15 | p2 = managerObject.create("warning box") 16 | p3 = managerObject.create("slash box") 17 | p1.use("Hello World") 18 | p2.use("Hello World") 19 | p3.use("Hello World") 20 | 21 | 22 | if __name__ == "__main__": 23 | startMain(Manager()) 24 | -------------------------------------------------------------------------------- /Prototype/framework/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Prototype/framework/__init__.py -------------------------------------------------------------------------------- /Prototype/framework/decoprototype/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Prototype/framework/decoprototype/__init__.py -------------------------------------------------------------------------------- /Prototype/framework/decoprototype/message_box_prototype.py: -------------------------------------------------------------------------------- 1 | import copy 2 | from framework.prototype import Prototype 3 | 4 | 5 | class MessageBox(Prototype): 6 | def __init__(self, decochar): 7 | self.__decochar = decochar 8 | 9 | def use(self, s): 10 | length = len(s) 11 | line = self.__decochar * (length + 4) 12 | 13 | print("{0}".format(line)) 14 | print("{0} {1} {2}".format(self.__decochar, s, self.__decochar)) 15 | print("{0}\n".format(line)) 16 | 17 | def createClone(self): 18 | clone = copy.deepcopy(self) 19 | return clone 20 | -------------------------------------------------------------------------------- /Prototype/framework/decoprototype/underline_pen_prototype.py: -------------------------------------------------------------------------------- 1 | import copy 2 | from framework.prototype import Prototype 3 | 4 | 5 | class UnderlinePen(Prototype): 6 | def __init__(self, ulchar): 7 | self.__ulchar = ulchar 8 | 9 | def use(self, s): 10 | length = len(s) 11 | line = self.__ulchar * (length + 2) 12 | 13 | print("\"{0}\"".format(s)) 14 | print("{0}\n".format(line)) 15 | 16 | def createClone(self): 17 | clone = copy.deepcopy(self) 18 | return clone 19 | -------------------------------------------------------------------------------- /Prototype/framework/manager.py: -------------------------------------------------------------------------------- 1 | class Manager(object): 2 | def __init__(self): 3 | self.__showcase = {} 4 | 5 | def register(self, name, proto): 6 | self.__showcase[name] = proto 7 | 8 | def create(self, protoname): 9 | p = self.__showcase[protoname] 10 | return p.createClone() 11 | -------------------------------------------------------------------------------- /Prototype/framework/prototype.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Prototype(metaclass=ABCMeta): 5 | @abstractmethod 6 | def use(self, s): 7 | pass 8 | 9 | @abstractmethod 10 | def createClone(self): 11 | pass 12 | -------------------------------------------------------------------------------- /Proxy/Main.py: -------------------------------------------------------------------------------- 1 | from proxy.printer_proxy import PrinterProxy 2 | 3 | def startMain(): 4 | p = PrinterProxy("Alice") 5 | print("Printer代理人の名前は現在({})です".format(p.getPrinterName())) 6 | p.myPrint("Nice to meet you") 7 | p.setPrinterName("Bob") 8 | print("Printer代理人の名前は現在({})です".format(p.getPrinterName())) 9 | p.myPrint("Hello, World") 10 | 11 | 12 | if __name__ == '__main__': 13 | startMain() 14 | -------------------------------------------------------------------------------- /Proxy/proxy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Proxy/proxy/__init__.py -------------------------------------------------------------------------------- /Proxy/proxy/printer_proxy.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from abc import ABCMeta, abstractmethod 4 | 5 | 6 | class Printable(metaclass=ABCMeta): 7 | @abstractmethod 8 | def setPrinterName(self, name): 9 | pass 10 | 11 | @abstractmethod 12 | def getPrinterName(self): 13 | pass 14 | 15 | @abstractmethod 16 | def myPrint(self, string): 17 | pass 18 | 19 | 20 | class Printer(Printable): 21 | @classmethod 22 | def getPrinter(cls, name): 23 | if not hasattr(cls, "_instance"): 24 | cls._instance = cls(name) 25 | else: 26 | cls._instance.__name = name 27 | return cls._instance 28 | 29 | def __init__(self, name): 30 | self.__name = name 31 | self.__heavyJob('Printerのインスタンス({})を作成中'.format(self.__name)) 32 | 33 | def setPrinterName(self, name): 34 | self.__name = name 35 | 36 | def getPrinterName(self): 37 | return self.__name 38 | 39 | def myPrint(self, string): 40 | print('=== Printer使用者({}) ==='.format(self.__name)) 41 | print(string) 42 | print("") 43 | 44 | def __heavyJob(self, msg): 45 | print(msg, end='') 46 | for _ in range(10): 47 | time.sleep(1) 48 | print('.', end='') 49 | print('完了') 50 | 51 | 52 | class PrinterProxy(Printable): 53 | def __init__(self, name): 54 | self.__name = name 55 | self.__real = None 56 | 57 | def setPrinterName(self, name): 58 | self.__name = name 59 | 60 | def getPrinterName(self): 61 | return self.__name 62 | 63 | def myPrint(self, string): 64 | self.__real = Printer.getPrinter(self.__name) 65 | self.__real.myPrint(string) 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # study_of_design_pattern 2 | 3 | デザインパターンとは、 4 | デザインパターンとは、ソフトウェア開発におけるデザインパターン(型紙(かたがみ)または設計パターン、英: design pattern)とは、過去のソフトウェア設計者が発見し編み出した設計ノウハウを蓄積し、名前をつけ、再利用しやすいように特定の規約に従ってカタログ化したものである。 5 | 6 | コンピュータのプログラミングで、素人と達人の間では驚くほどの生産性の差があり、その差はかなりの部分が経験の違いからきている。達人は、さまざまな難局を、何度も何度も耐え忍んで乗り切ってきている。そのような達人たちが同じ問題に取り組んだ場合、典型的にはみな同じパターンの解決策に辿り着く。これがデザインパターンである (GoF)。 7 | それぞれのパターンは、プログラマの間で何度も繰り返し考え出されてきた。したがって、それは最善の解決策ではないかもしれないが、その種の問題に対するトレードオフを考慮した、典型的な解決策ではある。さらに、コストがかかるかもしれない問題解決を実際に行う前の先行調査として、大変役に立つ。パターンに名前が付いていることが重要である。なぜなら、名前が付いていることで問題や解決策を記述したり、会話の中で取り上げたりすることができるようになるからである。 8 | [(以上、ウィキペディア(Wikipedia)より引用)](https://ja.wikipedia.org/wiki/デザインパターン_(ソフトウェア)) 9 | 10 | ## オブジェクトの生成に関するデザインパターンの一覧 11 | 12 | |パターン名 | 概要 | 13 | |----------------|----------------------------------------------------------------| 14 | |[Abstract Factory](https://qiita.com/ttsubo/items/30c86a265430a9e5050a)|関連する一連のインスタンスを状況に応じて、適切に生成する方法を提供する。 | 15 | |[Builder](https://qiita.com/ttsubo/items/0860e31c392aa3b91ed5) |複合化されたインスタンスの生成過程を隠蔽する。 | 16 | |[Factory Method](https://qiita.com/ttsubo/items/623f32f9e96cb16d04a4) |実際に生成されるインスタンスに依存しない、インスタンスの生成方法を提供する。| 17 | |[Prototype](https://qiita.com/ttsubo/items/07b91a14fcf4c26d7515) |同様のインスタンスを生成するために、原型のインスタンスを複製する。 | 18 | |[Singleton](https://qiita.com/ttsubo/items/c4af71ceba15b5b213f8) |あるクラスについて、インスタンスが単一であることを保証する。 | 19 | 20 | ## 構造に関するパターンの一覧 21 | 22 | |パターン名 | 概要 | 23 | |----------------|----------------------------------------------------------------| 24 | |[Adapter](https://qiita.com/ttsubo/items/d999f8dc2446c2aa30fb) |元々関連性のない2つのクラスを接続するクラスを作る。| 25 | |[Bridge](https://qiita.com/ttsubo/items/690d6d75ed6f5ff4b958) |クラスなどの実装と、呼出し側の間の橋渡しをするクラスを用意し、実装を隠蔽する。| 26 | |[Composite](https://qiita.com/ttsubo/items/bbae96baa0dec7f4e7a5) |再帰的な構造を表現する。| 27 | |[Decorator](https://qiita.com/ttsubo/items/6f1569425644054dd079) |あるインスタンスに対し、動的に付加機能を追加する。Filterとも呼ばれる。| 28 | |[Facade](https://qiita.com/ttsubo/items/f0d0b63ef20aeca7f11a) |複数のサブシステムの窓口となる共通のインタフェースを提供する。| 29 | |[Flyweight](https://qiita.com/ttsubo/items/2fecba5f66c7271128ab) |多数のインスタンスを共有し、インスタンスの構築のための負荷を減らす。| 30 | |[Proxy](https://qiita.com/ttsubo/items/3933c059ab405d262514) |共通のインタフェースを持つインスタンスを内包し、利用者からのアクセスを代理する。Wrapperとも呼ばれる。| 31 | 32 | ## 振る舞いに関するパターン 33 | 34 | |パターン名 | 概要 | 35 | |-----------------------|----------------------------------------------------------------| 36 | |[Chain of Responsibility](https://qiita.com/ttsubo/items/80fcaa529ce9f37e2543)|イベントの送受信を行う複数のオブジェクトを鎖状につなぎ、それらの間をイベントが渡されてゆくようにする。| 37 | |[Command](https://qiita.com/ttsubo/items/428a6241bd6b2562826a) |複数の異なる操作について、それぞれに対応するオブジェクトを用意し、オブジェクトを切り替えることで、操作の切替えを実現する。| 38 | |Interpreter |構文解析のために、文法規則を反映するクラス構造を作る。| 39 | |[Iterator](https://qiita.com/ttsubo/items/97d7dd23e8f939c81d78) |複数の要素を内包するオブジェクトのすべての要素に対して、順番にアクセスする方法を提供する。反復子。| 40 | |[Mediator](https://qiita.com/ttsubo/items/6b48497f5e1854017cc5) |オブジェクト間の相互作用を仲介するオブジェクトを定義し、オブジェクト間の結合度を低くする。| 41 | |[Memento](https://qiita.com/ttsubo/items/35f07879deb951d15953) |データ構造に対する一連の操作のそれぞれを記録しておき、以前の状態の復帰または操作の再現が行えるようにする。| 42 | |[Observer](https://qiita.com/ttsubo/items/34690c8e9351f5b2e989) |インスタンスの変化を他のインスタンスから監視できるようにする。Listenerとも呼ばれる。| 43 | |[State](https://qiita.com/ttsubo/items/cb3219a520451840f23f) |オブジェクトの状態を変化させることで、処理内容を変えられるようにする。| 44 | |[Strategy](https://qiita.com/ttsubo/items/b65dab0d494bebada223) |データ構造に対して適用する一連のアルゴリズムをカプセル化し、アルゴリズムの切替えを容易にする。| 45 | |[Template Method](https://qiita.com/ttsubo/items/475ac4810ae44c0ea1bd) |あるアルゴリズムの途中経過で必要な処理を抽象メソッドに委ね、その実装を変えることで処理が変えられるようにする。| 46 | |[Visitor](https://qiita.com/ttsubo/items/5fea7c0a1f9fc868dc1f) |データ構造を保持するクラスと、それに対して処理を行うクラスを分離する。| 47 | -------------------------------------------------------------------------------- /Singleton/step1/Main.py: -------------------------------------------------------------------------------- 1 | class Singleton(object): 2 | def __new__(cls, *args, **kargs): 3 | if not hasattr(cls, "_instance"): 4 | cls._instance = super(Singleton, cls).__new__(cls) 5 | return cls._instance 6 | 7 | class Myclass(Singleton): 8 | def __init__(self, input): 9 | self.input = input 10 | 11 | 12 | if __name__ == '__main__': 13 | one = Myclass(1) 14 | print("one.input={0}".format(one.input)) 15 | two = Myclass(2) 16 | print("one.input={0}, two.input={1}".format(one.input, two.input)) 17 | one.input = 0 18 | print("one.input={0}, two.input={1}".format(one.input, two.input)) 19 | -------------------------------------------------------------------------------- /Singleton/step2/Main.py: -------------------------------------------------------------------------------- 1 | class Singleton(object): 2 | @classmethod 3 | def get_instance(cls, input): 4 | if not hasattr(cls, "_instance"): 5 | cls._instance = cls(input) 6 | else: 7 | cls._instance.input = input 8 | return cls._instance 9 | 10 | class Myclass(Singleton): 11 | def __init__(self, input): 12 | self.input = input 13 | 14 | if __name__ == '__main__': 15 | one = Myclass.get_instance(1) 16 | print("one.input={0}".format(one.input)) 17 | two = Myclass.get_instance(2) 18 | print("one.input={0}, two.input={1}".format(one.input, two.input)) 19 | one.input = 0 20 | print("one.input={0}, two.input={1}".format(one.input, two.input)) 21 | -------------------------------------------------------------------------------- /State/Main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from state.context import Context 4 | from state.state import ConcreteStateBooting, ConcreteStateRun, ConcreteStateShutDown, ConcreteStateRestart 5 | 6 | 7 | def setConcreteState(operation): 8 | if operation == "start": 9 | return ConcreteStateBooting("booting") 10 | elif operation == "stop": 11 | return ConcreteStateShutDown("shutdown") 12 | elif operation == "restart": 13 | return ConcreteStateRestart("restart") 14 | 15 | def startMain(initial_operation, change_operation): 16 | obj = Context(setConcreteState(initial_operation)) 17 | print("### パソコンを、[{0}]します".format(initial_operation)) 18 | obj.handle() 19 | print("### パソコンは、[{0}]の動作状態になりました".format(obj.getState())) 20 | print("") 21 | 22 | print("... sleep 5 second") 23 | print("") 24 | time.sleep(5) 25 | 26 | obj.setState(setConcreteState(change_operation)) 27 | print("### パソコンを、[{0}]します".format(change_operation)) 28 | obj.handle() 29 | print("### パソコンの動作状態は、[{0}]になりました".format(obj.getState())) 30 | 31 | 32 | if __name__ == "__main__": 33 | startMain(sys.argv[1], sys.argv[2]) 34 | -------------------------------------------------------------------------------- /State/state/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/State/state/__init__.py -------------------------------------------------------------------------------- /State/state/context.py: -------------------------------------------------------------------------------- 1 | class Context(object): 2 | def __init__(self, stateObj): 3 | self.state = stateObj 4 | 5 | def setState(self, obj): 6 | self.state = obj 7 | 8 | def handle(self): 9 | self.state.handle(self) 10 | 11 | def getState(self): 12 | return self.state.getConcreateState() -------------------------------------------------------------------------------- /State/state/state.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class State(metaclass=ABCMeta): 5 | @abstractmethod 6 | def handle(self): 7 | pass 8 | 9 | class ConcreteState(State): 10 | def __init__(self, state): 11 | self.state = state 12 | 13 | def getConcreateState(self): 14 | return self.state 15 | 16 | 17 | class ConcreteStateBooting(ConcreteState): 18 | def __init__(self, state): 19 | super(ConcreteStateBooting, self).__init__(state) 20 | 21 | def handle(self, context): 22 | print("*** パソコンは、起動中です") 23 | context.setState(ConcreteStateRun("running")) 24 | 25 | 26 | class ConcreteStateRun(ConcreteState): 27 | def __init__(self, state): 28 | super(ConcreteStateRun, self).__init__(state) 29 | 30 | def handle(self, context): 31 | print("*** パソコンは、動作中です") 32 | 33 | 34 | class ConcreteStateShutDown(ConcreteState): 35 | def __init__(self, state): 36 | super(ConcreteStateShutDown, self).__init__(state) 37 | 38 | def handle(self, context): 39 | print("*** パソコンは、停止しています") 40 | 41 | 42 | class ConcreteStateRestart(ConcreteState): 43 | def __init__(self, state): 44 | super(ConcreteStateRestart, self).__init__(state) 45 | 46 | def handle(self, context): 47 | print("*** パソコンは、再起動をはじめます") 48 | context.setState(ConcreteStateBooting("booting")) 49 | context.handle() 50 | -------------------------------------------------------------------------------- /Strategy/Main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import strategy.strategy 3 | from strategy.strategy import WinningStrategy, CircularStrategy 4 | from strategy.player import Player 5 | 6 | 7 | def startMain(): 8 | player1 = Player("Taro", WinningStrategy()) 9 | player2 = Player("Hana", CircularStrategy()) 10 | 11 | for _ in range(10000): 12 | nextHand1 = player1.nextHand() 13 | nextHand2 = player2.nextHand() 14 | if nextHand1.isStrongerThan(nextHand2): 15 | print("Winner:{0}".format(player1)) 16 | player1.win() 17 | player2.lose() 18 | elif nextHand2.isStrongerThan(nextHand1): 19 | print("Winner:{0}".format(player2)) 20 | player1.lose() 21 | player2.win() 22 | else: 23 | print("Even...") 24 | player1.even() 25 | player2.even() 26 | 27 | print("Total Result:") 28 | print(player1) 29 | print(player2) 30 | 31 | 32 | if __name__ == '__main__': 33 | startMain() 34 | -------------------------------------------------------------------------------- /Strategy/strategy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Strategy/strategy/__init__.py -------------------------------------------------------------------------------- /Strategy/strategy/hand.py: -------------------------------------------------------------------------------- 1 | class Hand(object): 2 | HANDVALUE_GUU = 0 3 | HANDVALUE_CHO = 1 4 | HANDVALUE_PAA = 2 5 | name = ["グー", "チョキ", "パー"] 6 | hands = [] 7 | 8 | def __init__(self, handvalue): 9 | self.__handvalue = handvalue 10 | 11 | @classmethod 12 | def getHand(cls, handvalue): 13 | return cls.hands[handvalue] 14 | 15 | def isStrongerThan(self, hand): 16 | return self.fight(hand) == 1 17 | 18 | def isWeakerThan(self, hand): 19 | return self.fight(hand) == -1 20 | 21 | def fight(self, hand): 22 | if self == hand: 23 | return 0 24 | elif (self.__handvalue + 1) % 3 == hand.__handvalue: 25 | return 1 26 | else: 27 | return -1 28 | 29 | # def toString(self): 30 | # return self.name[self.__handvalue] 31 | 32 | 33 | Hand.hands.append(Hand(Hand.HANDVALUE_GUU)) 34 | Hand.hands.append(Hand(Hand.HANDVALUE_CHO)) 35 | Hand.hands.append(Hand(Hand.HANDVALUE_PAA)) -------------------------------------------------------------------------------- /Strategy/strategy/player.py: -------------------------------------------------------------------------------- 1 | class Player(object): 2 | def __init__(self, name, strategy): 3 | self.__name = name 4 | self.__strategy = strategy 5 | self.__wincount = 0 6 | self.__losecount = 0 7 | self.__gamecount = 0 8 | 9 | def nextHand(self): 10 | return self.__strategy.nextHand() 11 | 12 | def win(self): 13 | self.__strategy.study(True) 14 | self.__wincount += 1 15 | self.__gamecount += 1 16 | 17 | def lose(self): 18 | self.__strategy.study(False) 19 | self.__losecount += 1 20 | self.__gamecount += 1 21 | 22 | def even(self): 23 | self.__gamecount += 1 24 | 25 | def __str__(self): 26 | return "[{0}: {1}games, {2}win, {3}lose]".format(self.__name, 27 | self.__gamecount, 28 | self.__wincount, 29 | self.__losecount) 30 | -------------------------------------------------------------------------------- /Strategy/strategy/strategy.py: -------------------------------------------------------------------------------- 1 | import random 2 | from abc import ABCMeta, abstractmethod 3 | from strategy.hand import Hand 4 | 5 | 6 | class Strategy(metaclass=ABCMeta): 7 | @abstractmethod 8 | def nextHand(self): 9 | pass 10 | 11 | @abstractmethod 12 | def study(self, win): 13 | pass 14 | 15 | 16 | class WinningStrategy(Strategy): 17 | def __init__(self): 18 | self.__won = False 19 | self.__prevHand = None 20 | 21 | def nextHand(self): 22 | if not self.__won: 23 | self.__prevHand = Hand.getHand(random.randint(0, 2)) 24 | return self.__prevHand 25 | 26 | def study(self, win): 27 | self.__won = win 28 | 29 | 30 | class CircularStrategy(Strategy): 31 | def __init__(self): 32 | self.__Hand = 0 33 | 34 | def nextHand(self): 35 | return Hand.getHand(self.__Hand) 36 | 37 | def study(self, win): 38 | self.__Hand = (self.__Hand + 1) % 3 39 | -------------------------------------------------------------------------------- /TemplateMethod/Main.py: -------------------------------------------------------------------------------- 1 | from templatemethod.display import CharDisplay, StringDisplay 2 | 3 | 4 | def startMain(): 5 | d1 = CharDisplay('H') 6 | d2 = StringDisplay("Hello, World!") 7 | d1.display() 8 | print("") 9 | d2.display() 10 | 11 | 12 | if __name__ == '__main__': 13 | startMain() -------------------------------------------------------------------------------- /TemplateMethod/templatemethod/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/TemplateMethod/templatemethod/__init__.py -------------------------------------------------------------------------------- /TemplateMethod/templatemethod/display.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class AbstractDisplay(metaclass=ABCMeta): 5 | @abstractmethod 6 | def print(self): 7 | pass 8 | 9 | @abstractmethod 10 | def open(self): 11 | pass 12 | 13 | @abstractmethod 14 | def close(self): 15 | pass 16 | 17 | def display(self): 18 | self.open() 19 | for _ in range(5): 20 | self.print() 21 | self.close() 22 | 23 | 24 | class CharDisplay(AbstractDisplay): 25 | def __init__(self, ch): 26 | self.__ch = ch 27 | 28 | def open(self): 29 | print('<<', end='') 30 | 31 | def print(self): 32 | print(self.__ch, end='') 33 | 34 | def close(self): 35 | print('>>') 36 | 37 | 38 | class StringDisplay(AbstractDisplay): 39 | def __init__(self, string): 40 | self.__string = string 41 | self.__width = len(string) 42 | 43 | def open(self): 44 | self.__printLine() 45 | 46 | def print(self): 47 | print("|{0}|".format(self.__string)) 48 | 49 | def close(self): 50 | self.__printLine() 51 | 52 | def __printLine(self): 53 | print('+', end='') 54 | for _ in range(self.__width): 55 | print('-', end='') 56 | print('+') 57 | -------------------------------------------------------------------------------- /Visitor/Main.py: -------------------------------------------------------------------------------- 1 | from visitor.visitor import ListVistor 2 | from visitor.element import File, Directory, FileTreatmentException 3 | 4 | 5 | def startMain(): 6 | try: 7 | print("Making root entries") 8 | rootdir = Directory("root") 9 | bindir = Directory("bin") 10 | tmpdir = Directory("tmp") 11 | usrdir = Directory("usr") 12 | 13 | rootdir.add(bindir) 14 | rootdir.add(tmpdir) 15 | rootdir.add(usrdir) 16 | 17 | bindir.add(File("vi", 10000)) 18 | bindir.add(File("latex", 20000)) 19 | rootdir.accept(ListVistor()) 20 | 21 | print("") 22 | 23 | print("Making user entries...") 24 | yuki = Directory("yuki") 25 | hanako = Directory("hanako") 26 | tomura = Directory("tomura") 27 | 28 | usrdir.add(yuki) 29 | usrdir.add(hanako) 30 | usrdir.add(tomura) 31 | 32 | yuki.add(File("diary.html", 100)) 33 | yuki.add(File("composite.py", 200)) 34 | hanako.add(File("memo.tex", 300)) 35 | tomura.add(File("game.doc", 400)) 36 | tomura.add(File("junk.mail", 500)) 37 | rootdir.accept(ListVistor()) 38 | 39 | print("") 40 | print("Occurring Exception...") 41 | tmpfile = File("tmp.txt", 100) 42 | bindir = Directory("bin") 43 | tmpfile.add(bindir) 44 | except FileTreatmentException as ex: 45 | print(ex.message) 46 | 47 | 48 | if __name__ == '__main__': 49 | startMain() -------------------------------------------------------------------------------- /Visitor/visitor/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ttsubo/study_of_design_pattern/e11dde0c03aa49b22b024adbcc393f7d35898479/Visitor/visitor/__init__.py -------------------------------------------------------------------------------- /Visitor/visitor/element.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class Element(metaclass=ABCMeta): 5 | @abstractmethod 6 | def accept(self, v): 7 | pass 8 | 9 | 10 | class Entry(Element): 11 | @abstractmethod 12 | def getName(self): 13 | pass 14 | 15 | @abstractmethod 16 | def getSize(self): 17 | pass 18 | 19 | def add(self, entry): 20 | raise FileTreatmentException 21 | 22 | def __str__(self): 23 | return "{0} ({1})".format(self.getName(), self.getSize()) 24 | 25 | 26 | class File(Entry): 27 | def __init__(self, name, size): 28 | self.__name = name 29 | self.__size = size 30 | 31 | def getName(self): 32 | return self.__name 33 | 34 | def getSize(self): 35 | return self.__size 36 | 37 | def accept(self, v): 38 | v.visit(self) 39 | 40 | 41 | class Directory(Entry): 42 | def __init__(self, name): 43 | self.__name = name 44 | self.__dir = [] 45 | 46 | def getName(self): 47 | return self.__name 48 | 49 | def getSize(self): 50 | size = 0 51 | for f in self.__dir: 52 | size += f.getSize() 53 | return size 54 | 55 | def add(self, entry): 56 | self.__dir.append(entry) 57 | return self 58 | 59 | def __iter__(self): 60 | self.__index = 0 61 | return self 62 | 63 | def __next__(self): 64 | if self.__index >= len(self.__dir): 65 | raise StopIteration() 66 | dir = self.__dir[self.__index] 67 | self.__index += 1 68 | return dir 69 | 70 | def accept(self, v): 71 | v.visit(self) 72 | 73 | 74 | class FileTreatmentException(Exception): 75 | def __init__(self,*args,**kwargs): 76 | self.message = "FileTreatmentException" 77 | -------------------------------------------------------------------------------- /Visitor/visitor/visitor.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | from visitor.element import Directory 3 | 4 | 5 | class Vistor(metaclass=ABCMeta): 6 | @abstractmethod 7 | def visit(self, directory): 8 | pass 9 | 10 | 11 | class ListVistor(Vistor): 12 | def __init__(self): 13 | self.__currentdir = '' 14 | 15 | def visit(self, directory): 16 | print("{0}/{1}".format(self.__currentdir, directory)) 17 | if isinstance(directory, Directory): 18 | savedir = self.__currentdir 19 | self.__currentdir = self.__currentdir + '/' + directory.getName() 20 | for f in directory: 21 | f.accept(self) 22 | self.__currentdir = savedir 23 | --------------------------------------------------------------------------------