工厂方法模式跟抽象工厂模式有什么区别
1.这个我的理解是概念问题,就是思想的界限,可以理解成组织不同的表现,虽然都是工厂模式,表现不一样。实在理解不了,可以把一个工厂只有一个方法就是工厂方法模式,抽象工厂是可以多个方法。就按上一篇的代码工厂去理解。我看了网上的说法:
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
看到这个说法,我是一头雾水进来,有一头雾水出去。这分明是一个概念问题,概念理解往往都很微妙,总有一种只可意会不可言传的那种神奇事情。
我回头看看之前那两个工厂模式,发现工厂方法模式有一个地方容易出错。就是调用包装和苹果的时候
User 调用
public static void main(String[] args) {
// eatConconut(); //想吃椰子的时候
// eatPineapple(); //想吃菠萝的时候
fruitFactory = new AppleFactory();
bagFactory = new AppleBagFactory();
packApple();
eatApple(); //想吃苹果的时候
}
上面代码我如果改成 fruitFactory = new CoconutFactory();调用eatConconut();和packApple();程序也没有问题,但是现实中我买了苹果结果给我用菠萝的包装去打包,如果我把这个当做礼品送人,人家满心欢喜的收到菠萝,结果却是苹果,他会不会继续埋汰我。因此我理解工厂方法就单一产品,而且容易让后来者搞混,这对于设计模式本着让代码质量变高团队合作更有效的本质搞成了破坏代码质量破坏团队建设,既然工厂方法模式有局限性,就再开创另一个概念,抽象工厂模式。
代码
//抽象工厂
public abstract class AbstractFactory {
public abstract Fruit getFruit();
public abstract Bag getBag();
}
//具体业务的工厂
public class AppleFactory extends AbstractFactory {
public Fruit getFruit(){
return new Apple();
}
@Override
public Bag getBag() {
return new AppleBag();
}
}
//具体业务的工厂
public class PineappleFactory extends AbstractFactory {
public Fruit getFruit(){
return new Pineapple();
}
@Override
public Bag getBag() {
return new PineAppleBag();
}
}
//具体业务的工厂
public class CoconutFactory extends AbstractFactory {
public Fruit getFruit(){
return new Coconut();
}
@Override
public Bag getBag() {
return new CoconutBag();
}
}
public class User {
// static FruitFactory fruitFactory;
// static BagFactory bagFactory;
public static void main(String[] args) {
// eatConconut(); //想吃椰子的时候
// eatPineapple(); //想吃菠萝的时候
// fruitFactory = new AppleFactory();
// bagFactory = new AppleBagFactory();
// eatApple(); //想吃苹果的时候
// packApple();
}
public static void sendApple(){
AbstractFactory factory = new AppleFactory();
Fruit fruit = factory.getFruit();
Bag bag = factory.getBag();
fruit.eat();
bag.pack();
}
// public static void eatConconut(){//吃椰子
// // Coconut co = new Coconut();
// // co.eat();
// // Fruit fruit = SimpleFactory.getFruit(SimpleFactory.TYPE_COCONUT);
// Fruit fruit = fruitFactory.getFruit();
// fruit.eat();
// }
// public static void packCoconut(){
// Bag bag = bagFactory.getBag();
// bag.pack();
// }
// public static void eatPineapple(){//吃菠萝
// // Pineapple pineapple = new Pineapple();
// // pineapple.eat();
// // Fruit fruit = SimpleFactory.getFruit(SimpleFactory.TYPE_PIANEAPPLE);
// Fruit fruit = fruitFactory.getFruit();
// fruit.eat();
// }
// public static void packPineapple(){
// Bag bag = bagFactory.getBag();
// bag.pack();
// }
//
// public static void eatApple(){//吃苹果
// // Apple apple = new Apple();
// // apple.eat();
// // Fruit fruit = SimpleFactory.getFruit(SimpleFactory.TYPE_APPLE);
// Fruit fruit = fruitFactory.getFruit();
// fruit.eat();
// }
//
// public static void packApple(){
// Bag bag = bagFactory.getBag();
// bag.pack();
// }
}
具体水果类和包装类不变,跟上一篇文章一模一样。
遵循的原则和违反的原则
相比工厂方法模式,抽象工厂模式违反了哪些原则,一半违反了面向接口编程原则,单一职责原则,
1.遵循开闭原则
在这里我看到了设计模式就像一本兵书一样,如果死死按它执行行不通,容易形成纸上谈兵的现象,灵活运用,抽象工厂模式是打破工厂方法模式的局限,工厂方法模式只能运用到业务小的开发中,就是团队很确定,这次开发完了就不在写了,可以用工厂方法增加代码阅读性,如果业务不单一,多样的,运用工厂方法模式,新来员工会调错,然后时不时来问这段代码是干嘛的哪个方法是干嘛的,就用抽象方法,把打包方法和吃的方法写到一起,他理解一个具体业务其他的具体业务也就理解了,我也就轻松了不用再带着他阅读所有业务代码。
总结
1.学到这个模式,我感觉是设计模式是代码开发的一本开发指导兵书,可以了解它的思想,但是不能死死运用,灵活运用。
2.设计模式又是我们日常开发的一种概念普及,如果大家都学过设计模式,交流起来就方便,直接说我这里用工厂方法模式,我那业务用抽象工厂模式,这块代码用静态工厂模式
3.学习思想即可,具体还要看业务而定,不要学习赵括纸上谈兵。