JAVA设计模式之工厂模式

来源:互联网 发布:windows vista特效 编辑:程序博客网 时间:2024/06/09 17:59

工厂模式

1. 什么是工厂模式?

Java使用关键字new创建一个新的对象,在一些复杂的业务中,一个对象的创建往往伴随着其他操作的进行,比如数据的初始化,关联对象的实例化。因此在这样的系统中创建一个对象往往是一个繁复的工作。

如何轻松方便的构造实例对象,而不用关心构造对象实例的复杂过程和细节,这就是工厂模式存在的原因。建立一个“工厂”专门创建对象实例。

工厂模式包含(按照抽象程度弱强排列):简单工厂模式、工厂方法模式、抽象工厂模式

2. 简单工厂模式

2.1 什么是简单工厂模式?

简单工厂模式:简单工厂模式又叫静态工厂方法模式,专门定义一个工厂对象来负责创建其他类的实例对象,被创建的实例对象通常都有共同的父类。在简单工厂模式中,可以根据变量的不同返回不同的实例对象。

2.2 角色

工厂方法类:此类是简单工厂模式的核心部分,具有复杂的业务逻辑,负责根据不同情况返回不同的产品实例对象。

抽象产品类:所有产品类的公共父接口,定义了产品类的基本行为。

具体产品类:具有共同的父类,拥有各自的属性。

2.3 优点

1)工厂方法类中拥有所有的业务逻辑代码,客户端不需要知道创建产品实例对象的具体操作,只需要传入对应的参数就能返回相应的实例对象。

2)工厂方法类涵盖了所有的业务逻辑,代码逻辑简单,可读性强,由于工厂方法只有一个,因此类文件的数量不会很庞大。

2.4 缺点

1)由于工厂方法中涵盖了所有的业务逻辑,属于是硬编码,当产品类发生变化(新增或者减少)时,必须要去修改工厂方法类,改动比较大。

2)当业务变得复杂,产品类变得庞大的时候,工厂类方法中的代码会很庞大且复杂,不利于维护。

2.5 使用场景

1)工厂方法创建的产品对象较少的情况。这种情况下,工厂方法维护的产品对象较少,不会造成工厂类中业务逻辑复杂。

2)对于客户端不知道具体的产品对象创建细节,只需要知道传入工厂类的参数。

2.6 示例代码

1)产品公共接口

/**

 * 公共产品接口

 */

public interface Product {

/*产品描述*/

public void introduce();

}

 

2Phone产品类

/**

 * Phone产品类

 */

public class Phoneimplements Product{

@Override

public void introduce() {

System.out.println("This is a Phone!");

}

}

 

3Car产品类

/**

 * Car产品类

 */

public class Carimplements Product {

@Override

public void introduce() {

System.out.println("This is a Car!");

}

}

 

4)核心工厂方法

/**

 * 产品创建工厂

 */

public class ProductFactory {

/**

 * 根据类名创建产品对象,传入参数可以是其他类型

 */

public static Product makeProduct(Class<?>productClass){

Product product=null;

if(Phone.class.equals(productClass))

product= new Phone();

if(Car.class.equals(productClass))

product=new Car();

return product;

}

}

 

(5)测试代码

    public static void main(String[]args) {

Product car=ProductFactory.makeProduct(Car.class);

Product phone=ProductFactory.makeProduct(Phone.class);

car.introduce();

phone.introduce();

}

(6)运行结果

This is a Car!

This is a Phone!


3. 工厂方法模式

 

3.1 什么是工厂方法模式?

工厂方法模式:《Head First设计模式》书中指出,定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。个人理解,工厂方法模式相对于简单工厂模式只不过是把工厂方法抽象成了一个抽象工厂接口,派生出多个具体工厂方法类,每个具体工厂只能够创建一种产品实例对象。

3.2 角色

1抽象产品类:同简单工厂模式。

2具体产品类:同简单工厂模式。

3抽象工厂类:工厂类的抽象方法,所有工厂类的父接口。

4具体工厂类:实现了抽象工厂类,每个具体工厂类只能创建一种产品对象。

3.3 优点

1)将不同产品之间的创建逻辑分开,有利于产品创建逻辑的维护。

2)因为各种产品创建之间没有耦合,所以对于产品新增、删除比较好扩展,不用修改原有代码。

3)客户端不用理解产品对象创建的细节,只需要知道产品对应的工厂方法即可。

3.4 缺点

1)工厂方法业务逻辑分开过后,会造成类文件庞大,增加了系统的复杂度和运行开销。

2)由于产品继承于同一个父类或实现同一个接口,是一个类型(家族)的产品对象,因此工厂方法模式中不会出现不同类型(家族)的产品对象。

3.5 使用场景

    当客户端不需要关心产品对象创建的具体过程和细节,创建对象的工厂方法又是不固定的,这个时候可以使用工厂方法模式。客户端不用知道创建对象的细节,只需要记住创建对象的具体工厂方法。

3.6 示例代码

1)产品公共接口

/**

 * 公共产品接口

 */

public interface Product {

/*产品描述*/

public void introduce();

}

 

2Phone产品类

/**

 * Phone产品类

 */

public class Phoneimplements Product{

@Override

public void introduce() {

System.out.println("This is a Phone2");

}

}

 

3Car产品类

/**

 * Car产品类

 */

public class Carimplements Product {

@Override

public void introduce() {

System.out.println("This is a Car2");

}

}

 

4)抽象工厂方法

/**

 * 抽象工厂方法

 */

public interface Factory {

/*创建产品方法*/

public Product makeProduct();

}

 

5car具体工厂方法

/**

 * car创建工厂方法

 */

public class CarFactoryimplements Factory {

@Override

public Product makeProduct() {

return new Car();

}

}

 

6Phone具体工厂方法

/**

 * Phone创建工厂方法

 */

public class PhoneFactoryimplements Factory {

@Override

public Product makeProduct() {

return new Phone();

}

}

 

7)测试代码

public static void main(String[]args) {

Factory carFactory=new CarFactory();

Car car=(Car) carFactory.makeProduct();

car.introduce();

Factory phoneFactory=new PhoneFactory();

Phone phone=(Phone) phoneFactory.makeProduct();

phone.introduce();

}

    

 

8)运行结果

 

This is a Car2!

This is a Phone2!


4. 抽象工厂模式

4.1 什么是抽象工厂模式?

抽象工厂模式:《Head First设计模式》书中指出,提供一个接口用于创建相关或依赖对象的家族家族的意思表示继承于同一个父类或实现同一个接口的一系列java),而不需要明确指定具体类。个人理解,相对于工厂方法模式,抽象工厂模式的抽象程度更高些。抽象工厂衍生出许多具体的工厂方法,每个具体工厂方法又能创建多个具体的不同类型(家族)产品实例对象。

4.2 角色

1抽象产品类:同工厂方法模式。

2具体产品类:同工厂方法模式。

3抽象工厂类:工厂类的抽象方法,所有工厂类的父接口。

4具体工厂类:实现了抽象工厂类,每个具体工厂类可以创建多种不同类型(家族)产品对象。

4.3 优点

1)具备工厂方法模式的优点

2)因为定义了产品公共接口,实现了产品族的概念,使客户端在使用产品对象的时候始终能保持在一个类型(产品族)里面。

4.4 缺点

    1)当在已知产品族的情况下如果想要新增产品族,改动将会很大。比如现在已经有汽车类、电话类,如果想要再新增一个服装类就比较麻烦了。

4.5 使用场景

1)一个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

2)同属于同一个产品族的产品是在一起使用的,这一约束必须要在系统的设计中体现出来。

3)系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。

4.6 示例代码

(1)产品族父接口

/*汽车类产品族*/

public interface Car {}

 

/*手机类产品族*/

public interface Phone {}

 

(2)汽车具体产品类

/*奔驰汽车*/

public class Benzimplements Car {

public Benz() {

System.out.println("this is a Benz!");

}

}

 

/*宝马汽车*/

public class BMWimplements Car {

public BMW() {

System.out.println("this is a BMW!");

}

}

 

(3)手机具体产品类

/*苹果手机*/

public class Iphoneimplements Phone {

public Iphone() {

System.out.println("this is a Iphone!");

}

}

 

/*华为手机*/

public class HUAWEIimplements Phone {

public HUAWEI() {

System.out.println("this is a HUAWEI!");

}

}

 

(4)抽象工厂类

public interface Factory {

/*创建汽车对象*/

public Car produceCar();

/*创建手机对象*/

public Phone producePhone();

}

 

(5)高端产品工厂类

public class ProductFactoryAimplements Factory {

@Override

public Car produceCar() {

return new Benz();

}

@Override

public Phone producePhone() {

return new Iphone();

}

}

 

(6)中端产品工厂类

public class ProductFactoryBimplements Factory {

@Override

public Car produceCar() {

return new BMW();

}

@Override

public Phone producePhone() {

return new HUAWEI();

}

}

 

(7)测试代码

public static void main(String[]args) {

Factory levelA=new ProductFactoryA();

levelA.produceCar();

levelA.producePhone();

Factory levelB=new ProductFactoryB();

levelB.produceCar();

levelB.producePhone();

}

 

(8)运行结果

this is a Benz!

this is a Iphone!

this is a BMW!

this is a HUAWEI!


【四川乐山程序员联盟,欢迎大家加群相互交流学习5 7 1 8 1 4 7 4 3】

阅读全文
0 0
原创粉丝点击