美文网首页
Python要点解析

Python要点解析

作者: plutoese | 来源:发表于2016-07-16 13:47 被阅读71次

    Design Pattern

    Singleton Design Pattern

    Singleton provides you with a mechanism to have one, and only one, object of a given type and provides a global point of access.

    这个模式的要点在于只创建一个实例,并为此提供全局接口。

    Hence, Singletons are typically used in cases such as logging or database operations, printer spoolers, and many others, where there is a need to have only one instance that is available across the application to avoid conflicting requests on the same resource. For example, we may want to use one database object to perform operations on the DB to maintain data consistency or one object of the logging class across multiple services to dump log messages in a particular log file sequentially.

    最容易想到的用途应该是数据库登录。

    In brief, the intentions of the Singleton design pattern are as follows:

    • Ensuring that one and only one object of the class gets created
    • Providing an access point for an object that is global to the program
    • Controlling concurrent access to resources that are shared

    简单来说,这种模式的特点在于这几个方面:(1)保证只有一个实例被创建;(2)提供全局接口;(3)控制对资源的多线程访问

    A simple way of implementing Singleton is by making the constructor private and creating a static method that does the object initialization. This way, one object gets created on the first call and the class returns the same object thereafter.

    class Singleton(object):
    
        def __new__(cls):
           if not hasattr(cls, 'instance'):
             cls.instance = super(Singleton, cls).__new__(cls)
           return cls.instance
    
    s = Singleton()
    print("Object created", s)
    
    s1 = Singleton()
    print("Object created", s1)
    

    Lazy instantiation in the Singleton pattern

    Lazy instantiation makes sure that the object gets created when it’s actually needed. Consider lazy instantiation as the way to work with reduced resources and create them only when needed.

    class Singleton:
    
        __instance = None
    
        def __init__(self):
            if not Singleton.__instance:
                print(" __init__ method called..")
            else:
                print("Instance already created:", self.getInstance())
    
        @classmethod
        def getInstance(cls):
            if not cls.__instance:
                cls.__instance = Singleton()
            return cls.__instance
    
    s = Singleton() ## class initialized, but object not created
    print("Object created", Singleton.getInstance()) ## Gets created here
    s1 = Singleton() ## instance already created
    

    The Monostate Singleton pattern

    As the concept is based on all objects sharing the same state, it is also known as the Monostate pattern.

    class Borg:
        __shared_state = {"1":"2"}
        def __init__(self):
            self.x = 1
            self.__dict__ = self.__shared_state
            pass
    
    b = Borg()
    b1 = Borg()
    b.x = 4
    
    print("Borg Object 'b': ", b)  ## b and b1 are distinct objects
    print("Borg Object 'b1': ", b1)
    print("Object State 'b':", b.__dict__) ## b and b1 share same state
    print("Object State 'b1':", b1.__dict__)
    

    The Factory Pattern – Building Factories to Create Objects

    In object-oriented programming, the term factory means a class that is responsible for creating objects of other types. Typically, the class that acts as a factory has an object and methods associated with it. The client calls this method with certain parameters; objects of desired types are created in turn and returned to the client by the factory.

    from abc import ABCMeta, abstractmethod
    
    class Animal(metaclass = ABCMeta):
    
        @abstractmethod
        def do_say(self):
            pass
    
    class Dog(Animal):
    
        def do_say(self):
            print("Bhow Bhow!!")
    
    class Cat(Animal):
    
        def do_say(self):
            print("Meow Meow!!")
    
    
    ## forest factory defined
    class ForestFactory(object):
        def make_sound(self, object_type):
            return eval(object_type)().do_say()
    
    ## client code
    if __name__ == '__main__':
        ff = ForestFactory()
        animal = input("Which animal should make_sound Dog or Cat?")
        ff.make_sound(animal)
    

    The Façade Pattern – Being Adaptive with Façade

    Understanding Structural design patterns

    The following points will help us understand more about Structural patterns:

    • Structural patterns describe how objects and classes can be combined to form larger structures.
    • Structural patterns can be thought of as design patterns that ease the design by identifying simpler ways to realize or demonstrate relationships between entities. Entities mean objects or classes in the object-oriented world.
    • While the Class patterns describe abstraction with the help of inheritance and provide a more useful program interface, Object patterns describe how objects can be associated and composed to form larger objects. Structural patterns are a combination of Class and Object patterns.

    Understanding the Façade design pattern

    Façade hides the complexities of the internal system and provides an interface to the client that can access the system in a very simplified way.

    Consider the example of a storekeeper. Now, when you, as a customer, visit a store to buy certain items, you’re not aware of the layout of the store. You typically approach the storekeeper, who is well aware of the store system. Based on your requirements, the storekeeper picks up items and hands them over to you. Isn’t this easy? The customer need not know how the store looks and s/he gets the stuff done through a simple interface, the storekeeper.

    An example

    As discussed earlier, the Façade class simplifies the interface for the client. In this case, EventManager acts as a façade and simplifies the work for You. Façade talks to the subsystems and does all the booking and preparations for the marriage on your behalf.

    class Hotelier(object):
    
        def __init__(self):
            print("Arranging the Hotel for Marriage? --")
    
        def __isAvailable(self):
            print("Is the Hotel free for the event on given day?")
            return True
    
        def bookHotel(self):
            if self.__isAvailable():
                print("Registered the Booking\n\n")
    
    
    class Florist(object):
    
        def __init__(self):
            print("Flower Decorations for the Event? --")
    
        def setFlowerRequirements(self):
            print("Carnations, Roses and Lilies would be used for Decorations\n\n")
    
    
    class Caterer(object):
    
        def __init__(self):
            print("Food Arrangements for the Event --")
    
        def setCuisine(self):
            print("Chinese & Continental Cuisine to be served\n\n")
    
    class Musician(object):
    
        def __init__(self):
            print("Musical Arrangements for the Marriage --")
    
        def setMusicType(self):
            print("Jazz and Classical will be played\n\n")
    
    
    class EventManager(object):
    
        def __init__(self):
            print("Event Manager:: Let me talk to the folks\n")
    
        def arrange(self):
            self.hotelier = Hotelier()
            self.hotelier.bookHotel()
    
            self.florist = Florist()
            self.florist.setFlowerRequirements()
    
            self.caterer = Caterer()
            self.caterer.setCuisine()
    
            self.musician = Musician()
            self.musician.setMusicType()
    
    
    class You(object):
    
        def __init__(self):
            print("You:: Whoa! Marriage Arrangements??!!!")
    
        def askEventManager(self):
            print("You:: Let's Contact the Event Manager\n\n")
            em = EventManager()
            em.arrange()
    
        def __del__(self):
            print("You:: Thanks to Event Manager, all preparations done! Phew!")
    
    you = You()
    you.askEventManager()
    

    The Proxy Pattern – Controlling Object Access

    Proxy, in general terms, is a system that intermediates between the seeker and provider. Seeker is the one that makes the request, and provider delivers the resources in response to the request. In the web world, we can relate this to a proxy server. The clients (users in the World Wide Web), when they make a request to the website, first connect to a proxy server asking for resources such as a web page. The proxy server internally evaluates this request, sends it to an appropriate server, and gets back the response, which is then delivered to the client. Thus, a proxy server encapsulates requests, enables privacy, and works well in distributed architectures.

    ** An example**

    Consider the example of an Actor and his Agent. When production houses want to approach an Actor for a movie, typically, they talk to the Agent and not to the Actor directly. Based on the schedule of the Actor and other engagements, the Agent gets back to the production house on the availability and interest in working in the movie. The Agent acts as a Proxy that handles all the scheduling & payments for the Actor.

    class Actor(object):
    
        def __init__(self):
            self.isBusy = False
    
        def occupied(self):
            self.isBusy = True
            print(type(self).__name__ , "is occupied with current movie")
    
        def available(self):
            self.isBusy = False
            print(type(self).__name__ , "is free for the movie")
    
        def getStatus(self):
            return self.isBusy
    
    class Agent(object):
    
        def __init__(self):
            self.principal = None
    
        def work(self):
            self.actor = Actor()
            if self.actor.getStatus():
                self.actor.occupied()
            else:
                self.actor.available()
    
    
    if __name__ == '__main__':
        r = Agent()
        r.work()
    

    The Observer Pattern – Keeping Objects in the Know

    In the Observer design pattern, an object (Subject) maintains a list of dependents (Observers) so that the Subject can notify all the Observers about the changes that it undergoes using any of the methods defined by the Observer.

    class Subject:
        
        def __init__(self):
            self.__observers = []
        
        def register(self, observer):
            self.__observers.append(observer)
        
        def notifyAll(self, *args, **kwargs):
            for observer in self.__observers:
                observer.notify(self, *args, **kwargs)
    
    
    class Observer1:
        
        def __init__(self, subject):
            subject.register(self)
        
        def notify(self, subject, *args):
            print(type(self).__name__,':: Got', args, 'From', subject)
    
    class Observer2:
        
        def __init__(self, subject):
            subject.register(self)
        
        def notify(self, subject, *args):
            print(type(self).__name__, ':: Got', args, 'From', subject)
    
    
    subject = Subject()
    observer1 = Observer1(subject)
    observer2 = Observer2(subject)
    subject.notifyAll('notification')
    
    # coding = UTF-8
    
    class NewsPublisher:
    
        def __init__(self):
            self.__subscribers = []
            self.__latestNews = None
    
        def attach(self, subscriber):
            self.__subscribers.append(subscriber)
    
        def detach(self):
            return self.__subscribers.pop()
    
        def subscribers(self):
            return [type(x).__name__ for x in self.__subscribers]
    
        def notifySubscribers(self):
            for sub in self.__subscribers:
                sub.update()
    
        def addNews(self, news):
            self.__latestNews = news
    
        def getNews(self):
            return "Got News:", self.__latestNews
    
    
    from abc import ABCMeta, abstractmethod
    
    class Subscriber(metaclass=ABCMeta):
    
        @abstractmethod
        def update(self):
            pass
    
    
    class SMSSubscriber:
    
        def __init__(self, publisher):
            self.publisher = publisher
            self.publisher.attach(self)
    
        def update(self):
            print(type(self).__name__, self.publisher.getNews())
    
    class EmailSubscriber:
    
        def __init__(self, publisher):
            self.publisher = publisher
            self.publisher.attach(self)
    
        def update(self):
            print(type(self).__name__, self.publisher.getNews())
    
    class AnyOtherSubscriber:
    
        def __init__(self, publisher):
            self.publisher = publisher
            self.publisher.attach(self)
    
        def update(self):
            print(type(self).__name__, self.publisher.getNews())
    
    
    if __name__ == '__main__':
        news_publisher = NewsPublisher()
    
        for Subscribers in [SMSSubscriber, EmailSubscriber, AnyOtherSubscriber]:
            Subscribers(news_publisher)
            print("\nSubscribers:", news_publisher.subscribers())
    
            news_publisher.addNews('Hello World!')
            news_publisher.notifySubscribers()
    
            print("\nDetached:", type(news_publisher.detach()).__name__)
            print("\nSubscribers:", news_publisher.subscribers())
    
            news_publisher.addNews('My second news!')
            news_publisher.notifySubscribers()
    

    The Command Pattern – Encapsulating Invocation

    The Command pattern is a behavioral design pattern in which an object is used to encapsulate all the information needed to perform an action or trigger an event at a later time.

    class Wizard():
    
        def __init__(self, src, rootdir):
            self.choices = []
            self.rootdir = rootdir
            self.src = src
    
        def preferences(self, command):
            self.choices.append(command)
    
        def execute(self):
            for choice in self.choices:
                if list(choice.values())[0]:
                    print("Copying binaries --", self.src, " to ", self.rootdir)
                else:
                    print("No Operation")
    
        def rollback(self):
            print("Deleting the unwanted..", self.rootdir)
    
    
    if __name__ == '__main__':
        ## Client code
        wizard = Wizard('python3.5.gzip', '/usr/bin/')
        ## Steps for installation. ## Users chooses to install Python only
        wizard.preferences({'python':True})
        wizard.preferences({'java':False})
        wizard.execute()
    
    from abc import ABCMeta, abstractmethod
    
    class Command(metaclass=ABCMeta):
        def __init__(self, recv):
            self.recv = recv
    
        def execute(self):
            pass
    
    class ConcreteCommand(Command):
    
        def __init__(self, recv):
            self.recv = recv
    
        def execute(self):
            self.recv.action()
    
    class Receiver:
    
        def action(self):
            print("Receiver Action")
    
    class Invoker:
    
        def command(self, cmd):
            self.cmd = cmd
    
        def execute(self):
            self.cmd.execute()
    
    if __name__ == '__main__':
        recv = Receiver()
        cmd = ConcreteCommand(recv)
        invoker = Invoker()
        invoker.command(cmd)
        invoker.execute()
    
    from abc import ABCMeta, abstractmethod
    
    class Order(metaclass=ABCMeta):
    
        @abstractmethod
        def execute(self):
            pass
    
    class StockTrade:
    
        def buy(self):
            print("You will buy stocks")
    
        def sell(self):
            print("You will sell stocks")
    
    class Agent:
    
        def __init__(self):
            self.__orderQueue = []
    
        def placeOrder(self, order):
            self.__orderQueue.append(order)
            order.execute()
    
    class BuyStockOrder(Order):
    
        def __init__(self, stock):
            self.stock = stock
    
        def execute(self):
            self.stock.buy()
    
    class SellStockOrder(Order):
    
        def __init__(self, stock):
            self.stock = stock
    
        def execute(self):
            self.stock.sell()
    
    
    if __name__ == '__main__':
        #Client
        stock = StockTrade()
        buyStock = BuyStockOrder(stock)
        sellStock = SellStockOrder(stock)
    
        #Invoker
        agent = Agent()
        agent.placeOrder(buyStock)
        agent.placeOrder(sellStock)
    

    The Template Method Pattern – Encapsulating Algorithm

    The Template Method pattern is a behavioral design pattern that defines the program skeleton or an algorithm in a method called the Template Method. It is important to note that the change in the steps (as done by the subclasses) don’t impact the original algorithm’s structure. Thus, the facility of overriding by subclasses in the Template Method pattern allows the creation of different behaviors or algorithms.

    from abc import ABCMeta, abstractmethod
    
    class AbstractClass(metaclass=ABCMeta):
        def __init__(self):
            pass
    
        @abstractmethod
        def operation1(self):
            pass
    
        @abstractmethod
        def operation2(self):
            pass
    
        def template_method(self):
            print("Defining the Algorithm. Operation1 follows Operation2")
            self.operation2()
            self.operation1()
    
    
    class ConcreteClass(AbstractClass):
    
        def operation1(self):
            print("My Concrete Operation1")
    
        def operation2(self):
            print("Operation 2 remains same")
    
    
    class Client:
        def main(self):
            self.concreate = ConcreteClass()
            self.concreate.template_method()
    
    client = Client()
    client.main()
    
    from abc import  ABCMeta, abstractmethod
    
    class Compiler(metaclass=ABCMeta):
        @abstractmethod
        def collectSource(self):
            pass
    
        @abstractmethod
        def compileToObject(self):
            pass
    
        @abstractmethod
        def run(self):
            pass
    
        def compileAndRun(self):
            self.collectSource()
            self.compileToObject()
            self.run()
    
    class iOSCompiler(Compiler):
        def collectSource(self):
            print("Collecting Swift Source Code")
    
        def compileToObject(self):
            print("Compiling Swift code to LLVM bitcode")
    
        def run(self):
            print("Program runing on runtime environment")
    
    
    iOS = iOSCompiler()
    iOS.compileAndRun()
    
    from abc import abstractmethod, ABCMeta
    
    class Trip(metaclass=ABCMeta):
        
        @abstractmethod
        def setTransport(self):
            pass
        
        @abstractmethod
        def day1(self):
            pass
        
        @abstractmethod
        def day2(self):
            pass
        
        @abstractmethod
        def day3(self):
            pass
        
        @abstractmethod
        def returnHome(self):
            pass
        
        def itinerary(self):
            self.setTransport()
            self.day1()
            self.day2()
            self.day3()
            self.returnHome()
    
    class VeniceTrip(Trip):
        
        def setTransport(self):
            print("Take a boat and find your way in the Grand Canal")
        
        def day1(self):
            print("Visit St Mark's Basilica in St Mark's Square")
        
        def day2(self):
            print("Appreciate Doge's Palace")
        
        def day3(self):
            print("Enjoy the food near the Rialto Bridge")
        
        def returnHome(self):
            print("Get souvenirs for friends and get back")
    
    
    class MaldivesTrip(Trip):
        
        def setTransport(self):
            print("On foot, on any island, Wow!")
        
        def day1(self):
            print("Enjoy the marine life of Banana Reef")
        
        def day2(self):
            print("Go for the water sports and snorkelling")
        
        def day3(self):
            print("Relax on the beach and enjoy the sun")
        
        def returnHome(self):
            print("Dont feel like leaving the beach..")
    
    
    class TravelAgency:
        
        def arrange_trip(self):
            choice = input("What kind of place you'd like to go historical or to a beach?")
            if choice == 'historical':
                self.venice = VeniceTrip()
                self.venice.itinerary()
            if choice == 'beach':
                self.maldives = MaldivesTrip()
                self.maldives.itinerary()
    
    
    TravelAgency().arrange_trip()
    

    Model-View-Controller – Compound Patterns

    This is how the MVC pattern works: the model represents the data and business logic (how information is stored and queried), view is nothing but the representation (how it is presented) of the data, and controller is the glue between the two, the one that directs the model and view to behave in a certain way based on what a user needs. Interestingly, the view and controller are dependent on the model but not the other way round. This is primarily because a user is concerned about the data. Models can be worked with independently and this is the key aspect of the MVC pattern.

    The MVC design pattern works with the following terms—Model, View, Controller and the Client:

    • Model: This declares a class to store and manipulate data
    • View: This declares a class to build user interfaces and data displays
    • Controller: This declares a class that connects the model and view
    • User: This declares a class that requests for certain results based on certain actions
    class Model(object):
        def logic(self):
            data = 'Got it!'
            print("Model: Crunching data as per business logic")
            return data
    
    class View(object):
        def update(self, data):
            print("View: Updating the view with results: ", data)
    
    
    class Controller(object):
        def __init__(self):
            self.model = Model()
            self.view = View()
    
        def interface(self):
            print("Controller: Relayed the Cient asks")
            data = self.model.logic()
            self.view.update(data)
    
    class Client(object):
        print("Client: asks for certain information")
        controller = Controller()
        controller.interface()
    

    The State Design Pattern

    The State design pattern is a Behavioral design pattern, which is also sometimes referred to as an objects for states pattern. In this pattern, an object can encapsulate multiple behaviors based on its internal state.

    from abc import abstractmethod, ABCMeta
    
    class State(metaclass=ABCMeta):
    
        @abstractmethod
        def Handle(self):
            pass
    
    class ConcreteStateB(State):
        def Handle(self):
            print("ConcreteStateB")
    
    class ConcreteStateA(State):
        def Handle(self):
            print("ConcreteStateA")
    
    class Context(State):
    
        def __init__(self):
            self.state = None
    
        def getState(self):
            return self.state
    
        def setState(self, state):
            self.state = state
    
        def Handle(self):
            self.state.Handle()
    
    
    context = Context()
    stateA = ConcreteStateA()
    stateB = ConcreteStateB()
    
    context.setState(stateA)
    context.Handle()
    
    from abc import abstractmethod, ABCMeta
    
    class State(metaclass=ABCMeta):
    
        @abstractmethod
        def doThis(self):
            pass
    
    class StartState (State):
        def doThis(self):
            print("TV Switching ON..")
    
    class StopState (State):
        def doThis(self):
            print("TV Switching OFF..")
    
    class TVContext(State):
    
        def __init__(self):
            self.state = None
    
        def getState(self):
            return self.state
    
        def setState(self, state):
            self.state = state
    
        def doThis(self):
            self.state.doThis()
    
    
    context = TVContext()
    context.getState()
    start = StartState()
    stop = StopState()
    
    context.setState(stop)
    context.doThis()
    
    class ComputerState(object):
        name = "state"
        allowed = []
        
        def switch(self, state):
            if state.name in self.allowed:
                print('Current:',self,' => switched to new state',state.name)
                self.__class__ = state
            else:
                print('Current:',self,' => switching to',state.name,'not possible.')
        
        def __str__(self):
            return self.name
    
    
    class Off(ComputerState):
        name = "off"
        allowed = ['on']
    
    class On(ComputerState):
        name = "on"
        allowed = ['off','suspend','hibernate']
    
    class Suspend(ComputerState):
        name = "suspend"
        allowed = ['on']
    
    class Hibernate(ComputerState):
        name = "hibernate"
        allowed = ['on']
    
    
    class Computer(object):
        def __init__(self, model='HP'):
            self.model = model
            self.state = Off()
        
        def change(self, state):
            self.state.switch(state)
    
    
    if __name__ == "__main__":
        comp = Computer()
        # Switch on
        comp.change(On)
        # Switch off
        comp.change(Off)
        
        # Switch on again
        comp.change(On)
        # Suspend
        comp.change(Suspend)
        # Try to hibernate - cannot!
        comp.change(Hibernate)
        # switch on back
        comp.change(On)
        # Finally off
        comp.change(Off)
    

    相关文章

      网友评论

          本文标题:Python要点解析

          本文链接:https://www.haomeiwen.com/subject/cgyyjttx.html