- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
抽象工厂模式和工厂方法模式都是创建型设计模式,它们解决了不同场景下的对象创建问题。
根据 GOF 工厂方法 图案
Define an interface for creating an object, but let the subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclass.
package com.companyx;
public interface IProduct {
public void serve();
}
package com.companyx;
public abstract class Factory {
public abstract IProduct createProduct();
private void performCriticalJob(){
IProduct product = createProduct();
product.serve();
}
public void executeJob(){
//some code
performCriticalJob();
//some more code
}
}
package com.companyx;
class AppAProductFeatureX implements IProduct{
@Override
public void serve() {
//some code
}
}
package com.companyx;
public class AppAFeatureXProductFactory extends Factory{
@Override
public IProduct createProduct() {
return new AppAProductFeatureX();
}
}
package com.clientcompany;
import com.companyx.AppAFeatureXProductFactory;
import com.companyx.Factory;
public class Client {
public static void main(String[] args) {
Factory fact = new AppAFeatureXProductFactory();
fact.executeJob();
}
}
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
package com.companyb;
public interface IProductA {
public void performAJob();
}
package com.companyb;
//can be named better, but lets go with this name for this time
public class ProductAVersion1 implements IProductA{
@Override
public void performAJob() {
// some code
}
}
package com.companyb;
public interface IFactory {
public IProductA createProduct();
}
public class FactoryA implements IFactory{
@Override
public IProductA createProduct() {
return new ProductAVersion1(); // concrete class of product is hidden
}
}
package com.clientcompany.productprovider;
import com.companyb.IFactory;
import com.companyb.IProductA;
public class SomeClientClass {
private IFactory factory;
private IProductA product;
public void doSomeJobWithProductA() {
// some code
product.performAJob();
//someCode();
}
public void setFactory(IFactory factory) {
this.factory = factory;
this.product = factory.createProduct();
}
}
package com.clientcompany.productprovider;
import com.companyb.FactoryA;
public class SomeOtherClientCode {
public static void main(String[] args) {
SomeClientClass someClientClass = new SomeClientClass();
someClientClass.setFactory(new FactoryA());
someClientClass.doSomeJobWithProductA();
}
}
createProduct()
用户提供的具体实现形式具体工厂实现?
最佳答案
我很难穿上你的鞋子。但是我对这个主题很感兴趣,所以我会尝试一下。这里涉及的概念如 library
, framework
, factory method
, abstract factory
和 product family
等等。
一、library vs framework
实际上与工厂、抽象工厂或任何模式无关。库与框架的辩论不是从模式发挥作用的实现角度来看的。例如,JUnit 是一个带有丰富断言库的框架。那么,junit 是否应该更喜欢一种模式而不是其他模式来实现其内部实现? Java 本身是一个带有 JCL 库的框架。类似于java的Dot Net甚至称自己为框架,并包含BCL库。因此,在实现上下文中不再有框架与库的争论。
所以问题归结为您应该使用哪种模式?这不是关于区别,这很清楚,而是关于在哪种情况下使用哪个。在这种情况下,Client Code
是所有可能 call
的代码您现在正在输入的那个。某些代码是由您还是其他人编写的,在相同或不同的 jar 中,来自相同或不同的组织,都没有关系。从一个代码片段的角度来看,任意 其他代码(即使在同一类的不同方法中)是客户端代码,如果该代码有可能 call
您现在正在输入的代码。
在键入任何代码时(无论框架或库状态如何),有时我们需要获取某个对象的实例。可能我们需要一个 BufferedReader
.如果在编译时我们绝对确定对象的具体类,KISS
随它去new
ing。
我们可能不知道实例的具体类。现在问题是客户端代码是否有这些信息?如果客户端代码知道实际的具体类,但我不知道,那么我们使用 FactoryMethod
图案。我输入的代码将在(比如说)它的参数列表中请求一个工厂对象的实例。知道实际具体类的客户端代码将提供一个工厂对象来进行创建。这种情况的例子见 JDBC
就像我们要处理一条 sql 语句一样。在编译时我们不知道是否应该实例化 mysql.JDBC4PreparedStatement
或 microsoft.SQLServerStatement
.它取决于连接字符串,这取决于最终用户。所以我们得到一个Connection
实例并将其发送至 createStatement()
.看,我们正在委派一个类型为 sql.Statement
的对象的构造。到 sql.Connection
的子类.这里 conn
实例是工厂对象。我们如何获得工厂并不重要,只是我们从客户端代码中获得了它。
如果我们需要 Process
的实例对象,在编译时我们不知道它是否会是 Win32Process
或 UnixProcess
,我们将创建它的责任委托(delegate)给 ProcessBuilder
这是builder pattern
与工厂模式有关。 jdbc ConnectionManager
也是如此.
如果有许多不同的类不是通过继承而是通过家庭我们可以使用 AbstractFactory
.比如jdbc的点网对应DbProviderFactory
.我的代码需要 Connection
的实例, Command
, DataReader
等等,它们不是通过继承而是由 MySql 或 SqlServer 的家族相关的。所以我们得到了 DbProviderFactory
的子类的一个实例。 .可能是 MySqlProviderFactory
或 SqlProviderFactory
这取决于运行时和客户端代码。一旦我们有了那个工厂,我们就可以做 CreateCommand()
, CreateConnection()
等等。
希望这可以帮助您在工厂模式和抽象工厂模式之间进行选择。
关于java - 工厂方法更适合框架和库的抽象工厂吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42516772/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!