diff --git a/patterns/structural/facade.py b/patterns/structural/facade.py index 7a6c57c8..5caef955 100644 --- a/patterns/structural/facade.py +++ b/patterns/structural/facade.py @@ -2,6 +2,9 @@ # -*- coding: utf-8 -*- """ +Example from https://en.wikipedia.org/wiki/Facade_pattern#Python + + *What is this pattern about? The Facade pattern is a way to provide a simpler unified interface to a more complex system. It provides an easier way to access functions @@ -13,17 +16,6 @@ serves as an unified interface to all the underlying procedures to turn on a computer. -*What does this example do? -The code defines three classes (TC1, TC2, TC3) that represent complex -parts to be tested. Instead of testing each class separately, the -TestRunner class acts as the facade to run all tests with only one -call to the method runAll. By doing that, the client part only needs -to instantiate the class TestRunner and call the runAll method. -As seen in the example, the interface provided by the Facade pattern -is independent from the underlying implementation. Since the client -just calls the runAll method, we can modify the classes TC1, TC2 or -TC3 without impact on the way the client uses the system. - *Where is the pattern used practically? This pattern can be seen in the Python standard library when we use the isdir function. Although a user simply uses this function to know @@ -40,84 +32,66 @@ """ from __future__ import print_function -import time - -SLEEP = 0.1 - - -# Complex Parts -class TC1: - def run(self): - print(u"###### In Test 1 ######") - time.sleep(SLEEP) - print(u"Setting up") - time.sleep(SLEEP) - print(u"Running test") - time.sleep(SLEEP) - print(u"Tearing down") - time.sleep(SLEEP) - print(u"Test Finished\n") - - -class TC2: - def run(self): - print(u"###### In Test 2 ######") - time.sleep(SLEEP) - print(u"Setting up") - time.sleep(SLEEP) - print(u"Running test") - time.sleep(SLEEP) - print(u"Tearing down") - time.sleep(SLEEP) - print(u"Test Finished\n") - - -class TC3: - def run(self): - print(u"###### In Test 3 ######") - time.sleep(SLEEP) - print(u"Setting up") - time.sleep(SLEEP) - print(u"Running test") - time.sleep(SLEEP) - print(u"Tearing down") - time.sleep(SLEEP) - print(u"Test Finished\n") - - -# Facade -class TestRunner: + + +# Complex computer parts +class CPU(object): + """ + Simple CPU representation. + """ + def freeze(self): + print("Freezing processor.") + + def jump(self, position): + print("Jumping to:", position) + + def execute(self): + print("Executing.") + + +class Memory(object): + """ + Simple memory representation. + """ + def load(self, position, data): + print("Loading from {0} data: '{1}'.".format(position, data)) + + +class SolidStateDrive(object): + """ + Simple solid state drive representation. + """ + def read(self, lba, size): + return "Some data from sector {0} with size {1}".format(lba, size) + + +class ComputerFacade(object): + """ + Represents a facade for various computer parts. + """ def __init__(self): - self.tc1 = TC1() - self.tc2 = TC2() - self.tc3 = TC3() - self.tests = [self.tc1, self.tc2, self.tc3] - - def runAll(self): - [i.run() for i in self.tests] - - -# Client -if __name__ == '__main__': - testrunner = TestRunner() - testrunner.runAll() - -### OUTPUT ### -# ###### In Test 1 ###### -# Setting up -# Running test -# Tearing down -# Test Finished -# -# ###### In Test 2 ###### -# Setting up -# Running test -# Tearing down -# Test Finished -# -# ###### In Test 3 ###### -# Setting up -# Running test -# Tearing down -# Test Finished -# + self.cpu = CPU() + self.memory = Memory() + self.ssd = SolidStateDrive() + + def start(self): + self.cpu.freeze() + self.memory.load("0x00", self.ssd.read("100", "1024")) + self.cpu.jump("0x00") + self.cpu.execute() + + +def main(): + """ + >>> computer_facade = ComputerFacade() + >>> computer_facade.start() + Freezing processor. + Loading from 0x00 data: 'Some data from sector 100 with size 1024'. + Jumping to: 0x00 + Executing. + """ + + +if __name__ == "__main__": + import doctest + doctest.testmod(optionflags=doctest.ELLIPSIS) diff --git a/tests/structural/test_facade.py b/tests/structural/test_facade.py deleted file mode 100644 index a3765d28..00000000 --- a/tests/structural/test_facade.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -import unittest -import sys - -try: - from io import StringIO -except ImportError: - from StringIO import StringIO -from patterns.structural.facade import TestRunner, TC1, TC2, TC3 - - -class TestRunnerFacilities(unittest.TestCase): - def setUp(self): - self.tc1 = TC1() - self.tc2 = TC2() - self.tc3 = TC3() - self.average_result_tc1 = ( - "###### In Test 1 ######\n" + "Setting up\n" + "Running test\n" + "Tearing down\n" + "Test Finished" - ) - self.average_result_tc2 = ( - "###### In Test 2 ######\n" + "Setting up\n" + "Running test\n" + "Tearing down\n" + "Test Finished" - ) - self.average_result_tc3 = ( - "###### In Test 3 ######\n" + "Setting up\n" + "Running test\n" + "Tearing down\n" + "Test Finished" - ) - self.runner = TestRunner() - self.out = StringIO() - self.saved_stdout = sys.stdout - sys.stdout = self.out - - def tearDown(self): - self.out.close() - sys.stdout = self.saved_stdout - - def test_tc1_output(self): - self.tc1.run() - output = self.out.getvalue().strip() - self.assertEqual(output, self.average_result_tc1) - - def test_tc2_output(self): - self.tc2.run() - output = self.out.getvalue().strip() - self.assertEqual(output, self.average_result_tc2) - - def test_tc3_output(self): - self.tc3.run() - output = self.out.getvalue().strip() - self.assertEqual(output, self.average_result_tc3) - - def test_bunch_launch(self): - self.runner.runAll() - output = self.out.getvalue().strip() - self.assertEqual( - output, str(self.average_result_tc1 + '\n\n' + self.average_result_tc2 + '\n\n' + self.average_result_tc3) - )