首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >工厂方法与工厂方法设计模式

工厂方法与工厂方法设计模式
EN

Software Engineering用户
提问于 2014-03-21 11:08:18
回答 2查看 5.5K关注 0票数 5

目前,我正在从这本书中学习设计模式(尽管我没有尝试其他任何东西,但我发现它非常优秀)。

我对两个概念感到困惑:工厂方法和工厂方法设计模式。

我试着去理解每一个都意味着什么,我得出了一些结论。我想知道我的定义是否准确。

Factory方法是一种用于做一件事的方法:创建一个特定超级类型的对象并返回它。它可以使用参数,也可以不接受参数,也可以使用if语句“决定”要创建什么样的具体对象。

例如,这是一个工厂方法:

代码语言:javascript
复制
public Hat createHat(String hatColor){

    Hat hat;

    if (hatColor.equals("red")) hat = new RedHat();
    else if (hatColor.equals("blue")) hat = new BlueHat();
    else if (hatColor.equals("green")) hat = new GreenHat();
    else hat = new DefaultHat();

    return hat;

}

工厂方法设计模式是以工厂方法命名的。

此模式提供了一种封装来自客户端的对象创建的特定方法。

它的工作方式如下:模式是由两个类组成的系统,Creator和ConcreteCreator。Creator是abstract类,ConcreteCreator是该类的子类。

ConcreteCreator的工作--创建一个对象并使用工厂方法返回它。它只需要包含这一个方法。

Creator的工作-操作和使用从它的子类ConcreteCreator收到的对象,并通常将其返回给客户端。

这样做的方式如下:

Creator包含一个abstract方法,它的签名类似于SupertypeObject createObject()。每当它需要一个SupertypeObject类型的对象时,它就调用createObject()

问题是,createObject()和我说的一样,abstract。实现此方法是ConcreteCreator的工作。

这样,createObject()的实现就会对Creator隐藏起来。它不知道它得到了什么具体的对象,但它确实知道它是SypertypeObject类型的。

这样,客户端就可以使用Creator对象创建某种超级类型的对象,但是创建的具体对象将取决于子类。因此,声明ShoeFactory factory = new CaliforniaStyleShoesFactory()将使factory生产加利福尼亚风格的鞋子,而ShoeFactory factory = new NYStyleShoesFactory()将使factory生产NY风格的鞋子。因为创建具体对象的实现依赖于ConcreteCreator。

示范守则:

代码语言:javascript
复制
Class Client(){

    public static void main(String[] args){

        ShoeFactory factory;
        Shoe shoe;

        factory = new NYStyleShoeFactory();
        shoe = factory.makeShoe();
        System.out.println(shoe.getDescription()); // "A NY style shoe".

        // ShoeFactory's makeShoe() invokes createShoe() in the subclass, receives a Shoe
        // (doesn't know the concrete type of the Shoe. Depends on the subclass) and
        // does manipulations on it.
        // Returns the Shoe to the client.

        factory = new CaliforniaStyleShoeFactory():
        shoe = factory.makeShoe();
        System.out.println(shoe.getDescription()); // "A California style shoe".

}

}

我对这两个概念的理解准确吗?谢谢

EN

回答 2

Software Engineering用户

回答已采纳

发布于 2014-03-21 16:01:21

是的,你是对的。

这种模式是这样的,因为它使用工厂方法描述了一个已知的、被广泛接受的解决方案。

该模式可能被命名为"XXXX“。这并不重要。

关于@pdr关于您所描述的真正的“抽象工厂”的评论,下面的图像说明了两者的区别,Factory方法正是您所描述的:

这些图像是从此PDF本站拍摄的。它是由一个名叫Jason McDonald的软件工程师制作的。

票数 5
EN

Software Engineering用户

发布于 2014-03-21 16:32:21

你在评论中说了一些值得强调和解释的话。

一种方法怎么可能是一种模式?

虽然大多数设计模式都是类或对象的模板,它们是如何相互关联的,但这实际上只适用于面向对象的设计模式。设计模式的主题有很大的适用性,有些设计模式,如工厂或接口,可以很好地应用于使用单个方法或功能的实现。

例如,我们可以在一个简单的函数式JavaScript程序中使用这两种方法。假设我们有如下所示,即我们公司在Intranet上使用的ActiveX对象。

代码语言:javascript
复制
var oNeat = new ActiveXObject("OurCompany.NeatThing");
oNeat.DoStuff();

看起来很简单,但我们可以将上面的两行分别用一对模式包装。

代码语言:javascript
复制
function GetNeatThing() {
  return new ActiveXObject("OurCompany.NeatThing");
}

function DoStuff(onWhat) {
  if(onWhat && onWhat.DoStuff) {
    onWhat.DoStuff();
  }
}

然后我们的呼吁变得简单起来:

代码语言:javascript
复制
var oNeat = GetNeatThing();
DoStuff(oNeat);

虽然这本身并没有给我们带来很多好处,但我们确实获得了更好的模块化。如果我们将GetNeatThingDoStuff函数移动到他们自己的js文件中,并使用它们而不是硬编码的引用,那么我们就得到了拥有一个工厂和一个接口的所有好处。

(具体来说,我们可以改变我们的progID的NeatThing,甚至把它从ActiveX移到类似web服务器的东西上。我们甚至可以改变它的工作方式,重新命名这个可怕的"DoStuff“方法,使其更具描述性,同时不破坏现有的代码。)

票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/233166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档