设计模式---简单工厂

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jdhellfire/article/details/78380672

工厂模式:给所有产品抽象出一个公共的接口,工厂类根据需要实例化不同的产品。

《大话设计模式》这本书中给出实现计算器运算例子:
这里写图片描述

一.简单工厂的好处分析如下:

1.将所有算法抽象出一个公共基类“运算类”,提供GetResult公共接口。工厂类根据需要实例化不同的“产品”即具体的算法。而客户端只需要调用公共的GetRestult算法完成计算即可。运算类的扩展不会影响到客户端计算的逻辑。

2.抽象出简单工厂类后,算法对象的创建被集中化,使得算法对象的创建和使用解耦

二.简单工厂的缺点:
工厂类中存在Switch或if ….else的结构,使得功能的演进偶可能对原有代码产生波及,违背了“开放封闭原则”。

三.示例:
下面分别用Python和ITcl语言演示简单工厂,为了代码不依赖具体项目上下文环境,便于理解,例子很简单。这里要实现一个关于“打球”的文本打印,球的种类可能有多种,根据不同类型打印不同的字样。

Python实现示例子

from abc import ABCMeta, abstractmethod


class Ball:
    @abstractmethod
    def play(self): pass


class Football(Ball):
    def play(self):
        print('play Football')


class VollyBall(Ball):
    def play(self):
        print('play Volleyball')


class Basketball(Ball):
    def play(self):
        print('play Basketball')


class BallSelecter:
    def __init__(self, type):
        self.__type = type

    def get_ball(self):
        if self.__type == 'Football':
            return Football()
        elif self.__type == 'Volleyball':
            return VollyBall()
        elif self.__type == 'Basketball':
            return Basketball()
        else:
            return None


myball = BallSelecter('Basketball').get_ball()
myball.play()

ITcl实现示例子

itcl::class Ball {
         #打球的公共接口
         public method Play {} {}
}

itcl::class FootBall {
         public method Play {} {puts "play FootBall"}
         destructor {
                   puts "FootBall destroy"
         }
}

itcl::class VollyBall {
         public method Play {} {puts "play VollyBall"}
                   destructor {
                   puts "VollyBall destroy"
         }
}
itcl::class Factory {
         constructor {} {
                  # 确保抽象类不能被初始化
                   if {[namespace tail [info class]] == "Factory"} {
                            error "Error: can't create Factory objects - abstract class."
                   }

         }

         #强调内容*#强调内容*#在Incr Tcl里,工厂方法实现了在父类的名词空间里创建对象的方式。
         #在下面这个工的例子里,尽管你想要在方法被调用的名词空间
         #里创建新的对象,
         #尽管通常情况下是在全局名词空间内,但也有可能是其它任何地方,所
         #以我们使用uplevel命令确保
         #在方法被调用的名词空间内创建对象。并且使用namespace which获得
         #该对象可以传递到其它任何名词空间的对象名字。

         public proc CreatOperate { XinBie } {
                   #itcl::local Ball b
                   #Ball b
                   switch $XinBie {
                            "Nan" {

                                     return [uplevel {namespace which [FootBall #auto]}]
                                     #return [FootBall #auto]
                            }
                            "Niu" {
                                     #::test::vollyBall0
                                     return [uplevel {namespace which [VollyBall #auto]}]
                                     #return [VollyBall #auto]
                            }

                   }
                   return $b
         }

}
set Select  "Niu"

namespace eval test  {
         #Ball b
         set b [Factory::CreatOperate $Select]
         #::test::vollyBall0
         puts $b
         $b Play

}

猜你喜欢

转载自blog.csdn.net/jdhellfire/article/details/78380672