简单工厂模式
java
abstract class Product{
}
public class ProductA extends Product{
}
public class ProductB extends Product{
}
public class Factory {
public static Product produce(int type){
if(type == 1){
return new ProductA();
}else if(type == 2){
return new ProductB();
}
return null;
}
}
这种设计模式有什么优点?
它将调用produce()方法的调用方与生产Product的具体细节分离开了。
比如小王想生产产品A,他直接调用produce()方法,传入type,就可以拿到ProductA,不需要关心ProductA是如何生产出来的,也不需要关心ProductA里面的具体细节。
这种设计模式又有什么缺点呢?
如果你想添加另外一种产品ProductC,就不得不修改produce()方法,这样就违背了开闭原则
。
什么是开闭原则?
开闭原则简单来说就是:对修改关闭,对拓展开放。即当我们想要拓展功能的时候最好不要修改已有的代码,以免产生Bug,应该提前做好类的抽象,在抽象的基础上进行拓展。
工厂方法模式
使用工厂方法模式就可以解决上面这个问题,我们来看代码:
scala
public abstract class AbsFactory {
abstract Product produce();
}
public class FactoryA extends AbsFactory{
@Override
Product produce() {
return new ProductA();
}
}
public class FactoryB extends AbsFactory {
@Override
Product produce() {
return new ProductB();
}
}
调用方直接调用对应工厂类的produce()方法即可:
typescript
public class Test {
public static void main(String[] args) {
AbsFactory factoryA = new FactoryA();
factoryA.produce();
}
}
如果后续你想添加产品ProductC,直接添加ProductC及FactoryC即可,不需要对已有的代码进行修改,符合开闭原则;同时符合单一职责原则,每个具体工厂类只负责创建对应的产品,不需要像简单工厂那样存在复杂的if逻辑判断。
Android 中RecyclerView.Adapter
就运用了工厂方法模式:
java
public abstract static class Adapter<VH extends ViewHolder> {
//延迟实现构建细节到子类中
public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);
}
抽象工厂模式
如果产品A包含2个零件:PartOne和PartTwo,就可以使用抽象工厂模式来实现:
csharp
//零件1
public class PartOne {
}
//零件2
public class PartTwo {
}
public interface Factory {
PartOne produceOne();
PartTwo produceTwo();
}
public class FactoryA implements Factory{
@Override
public PartOne produceOne() {
return new PartOne();
}
@Override
public PartTwo produceTwo() {
return new PartTwo();
}
}
//产品A
public class ProductA {
private PartOne partOne;
private PartTwo partTwo;
private Factory factory;
public ProductA(Factory factory){
this.factory = factory;
}
public void prepare(){
partOne = factory.produceOne();
partTwo = factory.produceTwo();
}
}
使用方法如下:
java
public class Test {
public static void main(String[] args) {
Factory factory = new FactoryA();
ProductA productA = new ProductA(factory);
productA.prepare();
}
}
抽象工厂模式与工厂方法模式的区别在于抽象工厂模式适用于构建一组关联对象的场景,例如上例中ProductA中包含的两个对象:PartOne和PartTwo。