设计模式---简单工厂

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

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

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

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

}
### Java 工厂设计模式原理与实现 #### 定义与分类 工厂模式属于创建型设计模式,在Java编程中用于封装对象的创建逻辑。这种模式提供了接口以创建对象,而无需指定确切的类名[^1]。 存在三种主要类型的工厂模式- **简单工厂模式**:不作为标准的设计模式被提及,但常用来简化对象实例化的过程。 - **工厂方法模式**:定义了一个创建对象的接口,让子类决定实例化哪一个类。 - **抽象工厂模式**:提供了一组相关或相互依赖的对象的创建方式,通常返回一族类[^3]。 #### 实现机制 在工厂模式下,客户端不再直接使用`new`关键字来创建对象,而是调用特定的方法获取所需对象。这使得程序可以在不影响现有代码的基础上引入新的产品类型[^2]。 对于每一种工厂模式而言,其实现的核心在于如何解耦合对象使用者具体的产品类之间的关系,从而提高系统的灵活性可维护性[^4]。 #### 示例代码 以下是基于上述提到的不同种类工厂模式的一个简单例子说明: ##### 简单工厂模式 ```java // 定义操作基类 abstract class Operation { protected double numberA; protected double numberB; abstract double getResult(); } class Add extends Operation { @Override double getResult() { return this.numberA + this.numberB; } } // 创建一个静态工厂类来进行运算符的选择 public class OperationFactory { public static Operation createOperation(String operate){ Operation oper = null; switch(operate){ case "+": oper = new Add(); // 可能还有其他的操作如减乘除等... break; default: throw new IllegalArgumentException("Unsupported operation"); } return oper; } } ``` ##### 使用示例 ```java double numA = 10.0d, numB = 5.0d; String op = "+"; Operation oper = OperationFactory.createOperation(op); oper.setNumberA(numA); oper.setNumberB(numB); System.out.println("Result:" + oper.getResult()); ``` 此段代码展示了通过传入不同的字符串参数(这里是加号),可以动态地获得相应类型的`Operation`对象并执行计算功能,而不必关心内部的具体实现细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值