设计模式(一)简单工厂、工厂方法和抽象工厂
简单工厂模式
定义:
- 简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类(Factory)来负责创建其他类的实例,被创建的实例通常都具有共同的父类(接口)。
简单工厂模式中的角色和职责:
-
工厂(Creator):简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
-
抽象(Product):简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
-
具体产品(Concrete Product):简单工厂模式所创建的具体实例对象。
示例:
-
抽象:
public interface Fruit { /* 采集水果 */ public void get(); }
-
工厂:
public class FruitFactory { public static Fruit getFruit(String type) { try { if (type.equalsIgnoreCase("apple")) { return Apple.class.newInstance(); } else if (type.equalsIgnoreCase("banana")) { return Banana.class.newInstance(); } else { System.out.println("没有这个类"); return null; } } catch (Exception e) { e.printStackTrace(); } return null; } }
-
具体产品:
//实现1 public class Apple implements Fruit { public void get() { System.out.println("采集苹果"); } } //实现2 public class Banana implements Fruit{ public void get(){ System.out.println("采集香蕉"); } }
-
测试类
public class MainClass { public static void main(String[] args) { Fruit apple = FruitFactory.getFruit("Apple"); Fruit banana = FruitFactory.getFruit("banana"); apple.get(); banana.get(); } }
优缺点:
-
优点:用户在使用时可以直接根据工厂类去创建所需的实例,而无
需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。 -
缺点:
-
由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。
-
简单工厂模式适合拥有固定的实现类,当别人设计好之后,我们只需要调用就行了,但违反了开放-封闭的原则,想要增加新的实现类,就必须要修改工厂方法。
-
应用:
-
在Dao层的实现上,如在MVC框架层上定义一个接口,其中有多个实现类,我们不需要理解实现类是怎样实现的,只需要通过父类创建子类的对象即可。
-
如在连接数据库的时候,框架给我们提供了一个管理数据库连接的工厂类,在实现类中可能有多个实现类(mysql , mssql , oracle等),我们只需要通过工厂类创建出实现类的对象即可。
工厂方法模式(多态工厂模式)
定义:
- 工厂方法模式的意义是定义一个创建产品对象的工厂接口(FruitFactory接口),将实际创建工作推迟到子类当中(BananaFactory implements FruitFactory 等)。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
工厂方法模式中的角色和职责:
-
抽象工厂(Creator): 工厂方法模式的核心,任何工厂类都必须实现这个接口。
-
具体工厂( Concrete Creator): 具体工厂类是抽象工厂的一个实现,负责实例化产品对象。
-
抽象(Product): 工厂方法模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
-
具体产品(Concrete Product): 工厂方法模式所创建的具体实例对象。
示例:
-
核心工厂(抽象工厂):负责管理工厂,不负责工厂的创建
public interface FruitFactory { public Fruit getFruit(); }
-
具体工厂:负责对各个实例的初始化
public class BananaFactory implements FruitFactory { @Override public Fruit getFruit() { return new Banana(); } } public class AppleFactory implements FruitFactory { @Override public Fruit getFruit() { return new Apple(); } }
-
抽象:所有实例化对象都拥有的方法
public interface Fruit { /* 采集水果 */ public void get(); }
-
具体产品
public class Apple implements Fruit { public void get() { System.out.println("采集苹果"); } } public class Banana implements Fruit{ public void get(){ System.out.println("采集香蕉"); } }
-
测试创建类
public class MainClass { public static void main(String[] args) { FruitFactory appleFactory = new AppleFactory(); Fruit apple = appleFactory.getFruit(); apple.get(); FruitFactory bananaFactory = new BananaFactory(); Fruit banana = bananaFactory.getFruit(); banana.get(); } }
好处
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了“开放-封闭”原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。
抽象工厂模式
-
定义:抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。
-
抽象工厂中角色和职责
-
抽象工厂(Creator):抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个接口。
-
具体工厂( Concrete Creator):具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。
-
抽象(Product):抽象模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。
-
具体产品(Concrete Product):抽象模式所创建的具体实例对象。
抽象工厂中方法对应产品结构,具体工厂对应产品族。
-
产品族和产品等级结构
举例
-
抽象工厂:
public interface FruitFactory { //实例化Apple public Fruit getApple(); //实例化Banana public Fruit getBanana(); }
-
抽象:
public abstract class Banana implements Fruit{ /* * 采集 */ public abstract void get(); } public abstract class Apple implements Fruit { /* * 采集 */ public abstract void get(); }
-
具体工厂
public class NorthFruitFactory implements FruitFactory { public Fruit getApple() { return new NorthApple(); } public Fruit getBanana() { return new NorthBanana(); } } public class SouthFruitFactory implements FruitFactory { public Fruit getApple() { return new SouthApple(); } public Fruit getBanana() { return new SouthBanana(); } }
-
具体产品:
public class NorthBanana extends Banana { public void get() { System.out.println("采集北方香蕉"); } } public class NorthApple extends Apple { public void get() { System.out.println("采集北方苹果"); } } public class SouthApple extends Apple { public void get() { System.out.println("采集南方苹果"); } } public class SouthBanana extends Banana { public void get() { System.out.println("采集南方香蕉"); } }
-
测试类
public class MainClass { public static void main(String[] args) { FruitFactory ff = new NorthFruitFactory(); Fruit apple = ff.getApple(); apple.get(); Fruit banana = ff.getBanana(); banana.get(); FruitFactory ff2 = new SouthFruitFactory(); Fruit apple2 = ff2.getApple(); apple2.get(); Fruit banana2 = ff2.getBanana(); banana2.get(); } }
对工厂方法的使用举例: