java工厂设计模式浅析

interface Fruit{
	public void eat();
}
class Apple implements Fruit{
	public void eat(){
		System.out.println("*** eat apple");
	}
}
class Banana implements Fruit{
	public void eat(){
		System.out.println("*** eat banana");
	}
} 
public class TestDemo{
	public static void main(String[] args)/*模拟客户端运行*/
	{
		Friut f = new Apple();
		f.eat();
		/*以下是新增加客户需求Banana的增加的代码*/
		Friut g = new Banana();
		g.eat();
		/*由于一个接口可能有多个子类,即客户端的需求可能有多种,但是以上的设计模式,如果客户端发出了吃香蕉的请求,则
		需要在客户端中修改(或增加代码),但是如果客户端的需求有上千成万种,此时修改代码就很不方便了。
		在整个代码过程中,对客户端的最终工作是调用接口的虚函数,即获得一个接口Fruit对象f而后进行函数调用;
		至于是被谁实例化的,客户端并不需要知道。而以上代码中最大的问题在于关键字new,使得程序的耦合度太高。
		直接导致了客户端需求一大,代码就会不方便维护*/
	}
}

我们知道,确认一个代码是否真的好的标准是:

1.客户端调用简单,不需要关注具体的细节;2.客户端之外的代码修改,不会影响用户的使用。

那么,可不可以让客户端只是输入一段字符串就好呢?

    上面说到,接口对象是被谁实例化的客户端并不需要关心。所以我们增加一个过渡类Factory来实例化,使用(Fruit)作为函数声明的返回值,使用(new 接口Fruit的子类名)作为函数体内部的返回值;

    然后,我们在客户端中修改客户端的调用方式,然客户输入的字符串作为实参传入过渡类的函数形参,由于函数由static修饰,所以应该使用过渡类名来调用。然后用Fruit接口对象来接收返回值。

    由函数可知,该返回值就直接决定了new哪个接口的子类的对象了。所以使用接口对象f来调用eat()就可以。

    如果客户输入了不同的字符串,就可以直接新增类。并在过渡类中进行条件的增加即可,main函数完全不用修改代码。

    这样,代码维护起来就更加方便了。

下面给出修改后的代码:

interface Fruit{
	public void eat();
}
class Apple implements Fruit{
	public void eat(){
		System.out.println("*** eat apple");
	}
}
class Banana implements Fruit{
	public void eat(){
		System.out.println("*** eat banana");
	}
} 
class Factory{
	public static Fruit getInstance(String className)/*声明为static表明这个类中不打算使用属性,参数className是客户输入的*/
	{
		if("apple".equals(className))
			return new Apple();
		else if("orange".equals(className))
			return new Orange();
		else return null;
	}
}
public class TestDemo{
	public static void main(String[] args)/*模拟客户端运行*/
	{
		Fruit f = Factory.getInstance("apple");
		f.eat();
	}
}

猜你喜欢

转载自blog.csdn.net/dyd850804/article/details/81008658