1.总结下工厂方法模式的特点:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到子类。也就是具体的new对象都是具体工厂去做。而抽象工厂只是提供接口。工厂方法模式解析:工厂方法模式。简单点说就是工厂方法模式只是定义了创建对象的接口(给起个叫抽象工厂的名),实际让子类决定实现哪个接口来实例化对象(这个子类起名叫具体工厂。。。)
工厂方法模式的缺点:就是实例化对象依赖工厂类(具体工厂),如果想要扩展下功能,就必然得修改那个工厂类(具体工厂)。
2.抽象工厂模式:
就是提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
还是举之前造斧头的例子。
--2.1提供版本Axe1和版本Axe2的斧头:
public interface Axe1{
//制造Axe1版
public void make();
}
//实现Axe2版制造斧头的接口
public interface Axe2{
//Axe2版制造
public void make();
}
虽然都调用制造的方法,但是两个类(接口或者叫抽象产品)的make方法一个是造Axe1版,一个是造Axe2版的。以上也就体现了抽象工厂方法提供多个接口(抽象产品)。然而工厂方法模式只会提供一个接口(抽象产品)。
--2.2实现Axe1版的钢斧和石斧,实现Axe2版的钢斧和石斧:
public class SteelAxe1 implements Axe1{
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("制造出来了Axe1版钢斧!");
}
}
public class SteelAxe2 implements Axe2{
public void make() {
// TODO Auto-generated method stub
System.out.println("制造出来了Axe2版钢斧!");
}
}
public class StoneAxe1 implements Axe1{
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("制造出来了Axe1版石斧!");
}
}
public class StoneAxe2 implements Axe2{
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("制造出来了Axe2版石斧!");
}
}
Axe1版的抽象产品产生了Axe1版的石斧(具体产品)和Axe1版的钢斧(具体产品)。Axe2版的抽象产品产生了Axe2版的石斧(具体产品)和Axe2版的钢斧(具体产品)。所以其中一个抽象产品产生了多个具体产品。
--2.3.Axe1版本产品和Axe2版本产品的提供者(抽象工厂):
public interface Provider {
public Axe1 provideAxe1();
public Axe2 provideAxe2();
}
以上这个接口提供了两种版本的产品提供给用户。实现了这个接口的钢厂和石厂,就可以提供两个版本的钢斧和石斧。而这个接口叫做抽象工厂。
--2.4.钢斧厂和石斧厂:
public class SteelFactory implements Provider{
@Override
public Axe1 provideAxe1() {
// TODO Auto-generated method stub
return new SteelAxe1();
}
@Override
public Axe2 provideAxe2() {
// TODO Auto-generated method stub
return new SteelAxe2();
}
}
public class StoneFactory implements Provider{
@Override
public Axe1 provideAxe1() {
// TODO Auto-generated method stub
return new StoneAxe1();
}
@Override
public Axe2 provideAxe2() {
// TODO Auto-generated method stub
return new StoneAxe2();
}
}
如果是工厂方法模式那么只能提供钢斧和石斧两类斧头,只能从材料上区分,单调了。而抽象工厂模式可以提供Axe1版的石斧、Axe1版的钢斧、Axe2版的石斧、Axe2版的钢斧四类斧头。
工厂方法模式中石斧厂只能造石斧,钢斧厂只能造钢斧。不能造出多个版本斧头。也就是每个具体工厂类只能实例化一个具体产品。抽象工厂模式中石斧厂可以造版本1石斧和版本2的石斧。钢斧厂可以造版本1钢斧和版本2的钢斧。也就是每个具体工厂可以实例化多个具体产品。
--2.5.测试下各个类型的斧头:
public static void main(String[] args) {
Provider steelProvide=new SteelFactory();
steelProvide.provideAxe1().make();
steelProvide.provideAxe2().make();
Provider stoneProvide=new StoneFactory();
stoneProvide.provideAxe1().make();
stoneProvide.provideAxe2().make();
}
运行结果:
制造出来了Axe1版钢斧!
制造出来了Axe2版钢斧!
制造出来了Axe1版石斧!
制造出来了Axe2版石斧!
--------------------------------------------------------------------------------------------------------------------------------------
总结:
工厂方法模式:一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
--------------------------------------------------
通俗理解:
情况一:如果用户要工厂里生产的石斧,那么直接搞个简单工厂模式就可以了。
情况二:如果用户要工厂里生产的石斧,但是工厂里面有钢斧,石斧和木斧啥的,把斧头的功能抽象出来成抽象产品,然后再把工厂分为几个小厂子,分别标注为钢斧厂,石斧厂和木斧厂,每个小厂子造标注类型的斧头,用户只要去石斧小厂子取石斧(实现了抽象产品的具体产品)就可以了。这个就是工厂方法模式。
情况三:如果用户想要工厂里生产一把联想牌的钢斧,但是钢斧厂里有联想牌的钢斧和苹果牌的钢斧,就把两种牌子的斧头抽线出来成两个抽象产品,厂子里有石斧,钢斧和木斧,每种都对应两个牌子。工厂抽象出了两种牌子(抽象工厂)。。实际就是给厂子划分成石斧厂,木斧厂,钢斧厂,然后每个厂子生产两种牌子的斧头(就是实现了抽象工厂的具体工厂)。