我有一个带有工厂方法Factory
的抽象类工厂getProduct()
和他的子类。
我有抽象的类产品Product
和他的子类。
类工厂创建了类 - 产品的对象。
abstract class Factory {
abstract function getProduct();
}
class FirstFactory extends Factory {
public function getProduct() {
return new FirstProduct();
}
}
abstract class Product {
};
class FirstProduct extends Product {
}
结果我可以使用这个客户端代码:
$factory = new FirstFactory();
$firstProduct = $factory->getProduct();
$factory = new SecondFactory();
$secondProduct = $factory->getProduct();
问题:这种模式需要什么?因为在客户端代码中我只能使用直接类:
$firstProduct = new FirstProduct();
$secondProduct = new SecondProduct();
答案 0 :(得分:1)
如果您在编译时知道=IFERROR(INDEX(Sheet1!C$1:C$5,SMALL(INDEX(NOT(ISBLANK(Sheet1!$C$1:$C$5))*ROW($C$1:$C$5),0),COUNTBLANK(Sheet1!$C$1:$C$5)+ROW($C1))),"")
始终为firstProduct
类型且FirstProduct
始终为secondProduct
类型,那么就不需要工厂方法。< / p>
只有在要创建可能为SecondProduct
或可能为FirstProduct
的产品时,工厂方法才有用,具体取决于工厂的运行时类型。也许,例如,工厂的类型由用户输入决定。
答案 1 :(得分:1)
重要的是要注意工厂模式并不总是最好的解决方案,对于简单的情况,使用简单的new
会更好。例如,没有Factory,你的例子可能会更好。
当您不需要处理类的确切实现但保留在“抽象层”(例如,接口和抽象类)时,工厂模式将充分发挥其功能。您可以查看“依赖性倒置原则DIP”(依赖于抽象。不依赖于具体的类)。
例如,假设您有一个使用数据库系统的软件。无论出于何种原因,您都知道使用的具体数据库(MongoDB,SQL ...)可能会在以后更改。 (或者甚至在开发过程中只需要在文件中使用虚假的硬编码数据库)。工厂模式允许您通过调用正确的工厂在一行中从一个切换到另一个,因为所有实现都依赖于抽象。 (这实际上是DAO模式,它充分利用了Factory Pattern,请参阅oracle文档以获取更多信息:https://docs.python.org/3/library/functions.html#id)
这是一个具体而简单的实施例子。
您希望实例化两个玩家,但具体的玩家类应该以更通用的方式实现,以便以后可以重复使用。这对于添加几个新阵营非常重要,你不想花时间回到你的玩家类。
要构建并运行它,请在Main.java中复制,然后复制javac Main.java
和java Main
结果应为
http://www.oracle.com/technetwork/java/dataaccessobject-138824.html
// Factories ----------------------------------------
abstract class AbsUnitFactory {
public abstract Warrior creaWarrior();
public abstract Peon creaPeon();
}
class OrcFactory extends AbsUnitFactory {
public Warrior creaWarrior() {
return new OrcWarrior();
}
public Peon creaPeon() {
return new OrcPeon();
}
}
class HumanFactory extends AbsUnitFactory {
public Warrior creaWarrior() {
return new HumanWarrior();
}
public Peon creaPeon() {
return new HumanPeon();
}
}
abstract class Unit {
public abstract String getRole();
public abstract String getFaction();
@Override
public String toString() {
String str = new String();
str += "[UNIT]\n";
str += " Role: " + this.getRole() + "\n";
str += " Faction: " + this.getFaction() + "\n";
return str;
}
}
// Warrior Units ----------------------------------------
abstract class Warrior extends Unit {
@Override
public String getRole() {
return "I'm a badass Warrior with the biggest sword!";
}
}
class OrcWarrior extends Warrior {
@Override
public String getFaction() {
return "Orc";
}
}
class HumanWarrior extends Warrior {
@Override
public String getFaction() {
return "Human";
}
}
// Peon Units ----------------------------------------
abstract class Peon extends Unit {
@Override
public String getRole() {
return "I'm a little simple peon... Ready to work.";
}
}
class HumanPeon extends Peon {
@Override
public String getFaction() {
return "Human";
}
}
class OrcPeon extends Peon {
@Override
public String getFaction() {
return "Orc";
}
}
// Main components ----------------------------------------
class Player {
private AbsUnitFactory factory;
private Peon myPeon;
private Warrior myWarrior;
public Player(AbsUnitFactory pFactory) {
this.factory = pFactory;
this.myPeon = this.factory.creaPeon();
this.myWarrior = this.factory.creaWarrior();
}
@Override
public String toString() {
return this.myPeon.toString() + this.myWarrior.toString();
}
}
class Main {
public static void main(String[] args) {
AbsUnitFactory humanFactory = new HumanFactory();
AbsUnitFactory orcFactory = new OrcFactory();
Player humanPlayer = new Player(humanFactory);
Player orcPlayer = new Player(orcFactory);
System.out.println("***** Human player *****");
System.out.println(humanPlayer.toString());
System.out.println("***** Orce player *****");
System.out.println(orcPlayer.toString());
}
}
了解如何为任何阵营重用玩家类,并且唯一定义女巫派系的行是Factory。 (你甚至可以添加一个单身人士)。
这些是我非常欣赏的书(关于设计模式)
答案 2 :(得分:0)
可以注入工厂而不是实际的工厂。假设您有一个类只能在运行时根据某些特定条件进行实例化,在这种情况下,您不能执行新的Foo(... args)。 一种选择是注入FooFactory,让它为你创建Foo实例。