Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java4th版本中思考-是否有必要创建一个工厂来将代码与实现隔离?_Java_Design Patterns - Fatal编程技术网

在Java4th版本中思考-是否有必要创建一个工厂来将代码与实现隔离?

在Java4th版本中思考-是否有必要创建一个工厂来将代码与实现隔离?,java,design-patterns,Java,Design Patterns,我目前正在阅读“Java思维第四版”。在“接口”一章和子章“接口和工厂”中,说明了以下内容 一个接口是多个实现的网关, 生成符合接口的对象的典型方法是 工厂法设计模式。而不是调用构造函数 直接调用factory对象上的创建方法 从理论上讲,通过这种方式生成接口的实现 代码与接口的实现完全隔离, 因此,可以透明地将一个实现替换为另一个实现 另一个这是一个展示工厂结构的演示 方法: (为了便于参考,在我的问题后引用了示例代码) 我的问题是,我们为什么不把“serviceConsumer”方法变成 p

我目前正在阅读“Java思维第四版”。在“接口”一章和子章“接口和工厂”中,说明了以下内容

一个接口是多个实现的网关, 生成符合接口的对象的典型方法是 工厂法设计模式。而不是调用构造函数 直接调用factory对象上的创建方法 从理论上讲,通过这种方式生成接口的实现 代码与接口的实现完全隔离, 因此,可以透明地将一个实现替换为另一个实现 另一个这是一个展示工厂结构的演示 方法:

(为了便于参考,在我的问题后引用了示例代码)

我的问题是,我们为什么不把“serviceConsumer”方法变成

public static void serviceConsumer(Service s) { 
    s.method1(); 
    s.method2(); 
} 
在这种情况下,代码取决于接口“服务”,而不是实现。(它也可以透明地“交换”,不是吗?)。所以,我并没有真正理解在这里使用“工厂”以及它在开始时的状态

-----------------------------以下引自“Java思维”------------------------------

//: interfaces/Factories.java 
import static net.mindview.util.Print.*;
interface Service {
    void method1();
    void method2();
}
interface ServiceFactory {
    Service getService();
}
class Implementation1 implements Service {
    Implementation1() {} // Package access 
    public void method1() {
        print("Implementation1 method1");
    }
    public void method2() {
        print("Implementation1 method2");
    }
}
class Implementation1Factory implements ServiceFactory {
    public Service getService() {
        return new Implementation1();
    }
}
class Implementation2 implements Service {
    Implementation2() {} // Package access 
    public void method1() {
        print("Implementation2 method1");
    }
    public void method2() {
        print("Implementation2 method2");
    }
}
class Implementation2Factory implements ServiceFactory {
    public Service getService() {
        return new Implementation2();
    }
}
public class Factories {
    public static void serviceConsumer(ServiceFactory fact) {
        Service s = fact.getService();
        s.method1();
        s.method2();
    }
    public static void main(String[] args) {
        serviceConsumer(new Implementation1Factory());
        // Implementations are completely interchangeable: 
        serviceConsumer(new Implementation2Factory());
    }
}
/* Output: 
Implementation1 method1 
Implementation1 method2 
Implementation2 method1 
Implementation2 method2 
*/ //:~

没有什么可以阻止你写这样的方法,引用的语句是关于对象本身的创建

在这种情况下,代码取决于接口“服务”,而不是实现


在这两种情况下,代码都取决于接口,区别在于,在您的实现中,
服务
是在方法
服务消费者

之外创建的。没有什么可以阻止您编写这种方法,引用的语句是关于对象本身的创建

在这种情况下,代码取决于接口“服务”,而不是实现


在这两种情况下,代码取决于接口,区别在于,在您的实现中,
服务
是在方法
服务消费者
之外创建的,如果您看到工厂方法的实际使用,可能会更清楚。TIJ示例没有任何上下文

我最喜欢的例子是
Collection.iterator()
,其中
Collection
ServiceFactory
iterator
服务。您可以在
serviceConsumer()
中看到调用,但请考虑以下几点:

Collection c = new ArrayList();  // ArrayList is a Factory for its iterator
Iterator i = c.iterator();  // getService()
if (i.hasNext()) { ...} 
如果
serviceConsumer
是一种打印集合的方法(而不是没有上下文的方法),您可以看到传递
ServiceFactory
ArrayList
)比传递
服务
迭代器
)要好得多。使用它可以进行更多的封装(服务的细节隐藏在方法中)

以下是一些UML图,有助于理解相似性:

工厂方法模式

TIJ示例

Collection.iterator()


注意:pink类实际上是实现与集合对应的迭代器接口类型的匿名类。它们通常不是客户端以任何其他方式(隐藏)实例化的类。

如果您看到工厂方法的实际使用,可能会更清楚。TIJ示例没有任何上下文

我最喜欢的例子是
Collection.iterator()
,其中
Collection
ServiceFactory
iterator
服务。您可以在
serviceConsumer()
中看到调用,但请考虑以下几点:

Collection c = new ArrayList();  // ArrayList is a Factory for its iterator
Iterator i = c.iterator();  // getService()
if (i.hasNext()) { ...} 
如果
serviceConsumer
是一种打印集合的方法(而不是没有上下文的方法),您可以看到传递
ServiceFactory
ArrayList
)比传递
服务
迭代器
)要好得多。使用它可以进行更多的封装(服务的细节隐藏在方法中)

以下是一些UML图,有助于理解相似性:

工厂方法模式

TIJ示例

Collection.iterator()


注意:pink类实际上是实现与集合对应的迭代器接口类型的匿名类。它们通常不是客户机以任何其他方式(隐藏)实例化的类。

噢,ic。然而,如果跳过“工厂”是可以的,那么为什么它会增加更多的层来使事情复杂化呢?我们需要更进一步,假设“服务”对象的创建可能非常复杂,值得一个工厂这样做吗?工厂在这里是必不可少的。问题是,您看到的是工厂的效果(它正在放弃对实现的依赖),而没有考虑工厂的存在。更广泛地看待它。如果你不是用工厂来创建服务,而是在很多地方自己创建对象(这实际上是引入了对实现的依赖),那么在服务接口的实现改变之后,你将不得不改变许多对象的创建,而不是改变工厂中的一段代码。哦,ic。然而,如果跳过“工厂”是可以的,那么为什么它会增加更多的层来使事情复杂化呢?我们需要更进一步,假设“服务”对象的创建可能非常复杂,值得一个工厂这样做吗?工厂在这里是必不可少的。问题是,您看到的是工厂的效果(它正在放弃对实现的依赖),而没有考虑工厂的存在。更广泛地看待它。如果您不是使用factory创建服务,而是在许多地方自己创建对象(这实际上引入了对实现的依赖),那么在更改服务接口的实现之后,您将不得不更改许多对象创建,而不是更改factory中的一段代码。