工厂模式和依赖
Factory Pattern and dependencies
工厂方法是为了避免违反开闭原则。
而不是通过继承创建对象:
Product myProd = new ConcreteProduct1; // concreteProduct extends abstract product
myProd.doSomething();
我们使用工厂 "interface" 和亲戚具体工厂(class 实现工厂并覆盖其方法的实体):
Factory myFact = new ConcreteFact1; // (2)
Product myProd = myFact.createProd(); // (1)
myProd.doSomething(); // (1)
我读了很多关于工厂方法的文章;我了解到,使用工厂方法可以排除开闭原则的错误。但是我还是不明白:
- 使用这种设计模式,我们仍然依赖于 class Product (myProd) (1)
- 此外..我们与具体工厂有依赖关系(客户需要实例化一个特定的想要的具体工厂,客户必须知道一个)(2)
谢谢你的任何澄清。
我们确实对Product
有依赖,但重点是消除对ConcreteProduct
的依赖。
不,我们不依赖于 ConcreteFactory
,因为我们作为参数传递给工厂。
class MassProduction {
ProductFactory factory;
public MyClass(ProductFactory fact) {
factory = fac;
}
public List<Product> produce(int amount) {
ArrayList<Product> result = new ArrayList<>(amount);
for (int i = 0; i < amount; i++) {
result.add(factory.createProduct());
}
return result;
}
}
我们在任何时候都不会依赖于 ConcreteProduct
或 ConcreteFactory
。
您可能并不完全需要使用整个概念。
这是一个用例:
// define the interfaces
public interface Product {}
public interface ProductFactory {
public Product createProduct();
}
// create some implementors
public class Sweatshirt implements Product {
static final ProductFactory FACTORY = new ProductFactory() {
public Product createProduct() {
return new Sweatshirt();
}
}
}
public class Pants implements Product {
static final ProductFactory FACTORY = new ProductFactory() {
public Product createProduct() {
return new Pants();
}
}
}
public class Hat implements Product {
static final ProductFactory FACTORY = new ProductFactory() {
public Product createProduct() {
return new Hat();
}
}
}
// create a client class
class Stock {
private List<? extends Product> stock = new ArrayList<>();
public void add(int amount, ProductFactory fac) {
for (int i = 0; i < amount; i++) {
stock.add(fac.createProduct());
}
}
public void printAll() {
stock.forEach(p -> System.out.println(p.getClass()));
}
}
// driver class that allows the user to enter amounts and product type
// and adds them to the stock until any entry is invalid
class InventoryManagement {
public static void main(String[] args) {
Stock stock = new Stock();
try (Scanner sc = new Scanner(System.in)) {
while (true) {
// read amount from console input
int amount = sc.nextInt();
// read type from console input
String value = sc.next();
ProductFactory factory = null;
switch(value) {
case "s":
factory = Sweatshirt.FACTORY;
break;
case "p":
factory = Pants.FACTORY;
break;
case "h":
factory = Hat.FACTORY;
break;
}
if (factory != null) {
stock.add(amount, factory);
} else {
break;
}
}
} catch (Exception e) {}
stock.printAll();
}
}
如您所见,客户端 class (Stock
) 没有任何对任何具体 Product
或 Factory
的引用,但它使用给定的Factory
秒创建 Product
秒。连接两者(客户端classStock
和具体产品)的驱动程序class。
工厂方法是为了避免违反开闭原则。 而不是通过继承创建对象:
Product myProd = new ConcreteProduct1; // concreteProduct extends abstract product
myProd.doSomething();
我们使用工厂 "interface" 和亲戚具体工厂(class 实现工厂并覆盖其方法的实体):
Factory myFact = new ConcreteFact1; // (2)
Product myProd = myFact.createProd(); // (1)
myProd.doSomething(); // (1)
我读了很多关于工厂方法的文章;我了解到,使用工厂方法可以排除开闭原则的错误。但是我还是不明白:
- 使用这种设计模式,我们仍然依赖于 class Product (myProd) (1)
- 此外..我们与具体工厂有依赖关系(客户需要实例化一个特定的想要的具体工厂,客户必须知道一个)(2)
谢谢你的任何澄清。
我们确实对
Product
有依赖,但重点是消除对ConcreteProduct
的依赖。不,我们不依赖于
ConcreteFactory
,因为我们作为参数传递给工厂。class MassProduction { ProductFactory factory; public MyClass(ProductFactory fact) { factory = fac; } public List<Product> produce(int amount) { ArrayList<Product> result = new ArrayList<>(amount); for (int i = 0; i < amount; i++) { result.add(factory.createProduct()); } return result; } }
我们在任何时候都不会依赖于 ConcreteProduct
或 ConcreteFactory
。
您可能并不完全需要使用整个概念。
这是一个用例:
// define the interfaces
public interface Product {}
public interface ProductFactory {
public Product createProduct();
}
// create some implementors
public class Sweatshirt implements Product {
static final ProductFactory FACTORY = new ProductFactory() {
public Product createProduct() {
return new Sweatshirt();
}
}
}
public class Pants implements Product {
static final ProductFactory FACTORY = new ProductFactory() {
public Product createProduct() {
return new Pants();
}
}
}
public class Hat implements Product {
static final ProductFactory FACTORY = new ProductFactory() {
public Product createProduct() {
return new Hat();
}
}
}
// create a client class
class Stock {
private List<? extends Product> stock = new ArrayList<>();
public void add(int amount, ProductFactory fac) {
for (int i = 0; i < amount; i++) {
stock.add(fac.createProduct());
}
}
public void printAll() {
stock.forEach(p -> System.out.println(p.getClass()));
}
}
// driver class that allows the user to enter amounts and product type
// and adds them to the stock until any entry is invalid
class InventoryManagement {
public static void main(String[] args) {
Stock stock = new Stock();
try (Scanner sc = new Scanner(System.in)) {
while (true) {
// read amount from console input
int amount = sc.nextInt();
// read type from console input
String value = sc.next();
ProductFactory factory = null;
switch(value) {
case "s":
factory = Sweatshirt.FACTORY;
break;
case "p":
factory = Pants.FACTORY;
break;
case "h":
factory = Hat.FACTORY;
break;
}
if (factory != null) {
stock.add(amount, factory);
} else {
break;
}
}
} catch (Exception e) {}
stock.printAll();
}
}
如您所见,客户端 class (Stock
) 没有任何对任何具体 Product
或 Factory
的引用,但它使用给定的Factory
秒创建 Product
秒。连接两者(客户端classStock
和具体产品)的驱动程序class。