设计模式———工厂模式

目录

一、简单工厂模式

二、工厂方法模式(多态工厂模式)

三、抽象工厂模式


工厂模式是程序中常用的设计模式,今天从下面几个点记录一下学习所得

一、简单工厂模式

这里用个例子来简单说明一下。首先,我创建如下几个类

  • Test.java:程序的主入口
  • Animal.java:动物父类
  • Chicken.java:鸡肉类,继承于Animal
  • Pig.java:猪肉类,继承于Animal
  • AnimalFactory:工厂类,用于创建相应的Animal子类

Animal.java

public abstract class Animal {
	public float price = 0;//价格
	public int total = 0;//数量
	
	public abstract void getDetail();
}

Chicken.java

public class Chicken extends Animal {
	//初始化价格及数量
	public Chicken() {
		price = 10;
		total = 100;
	}
	@Override
	public void getDetail() {
		System.out.println("鸡肉价格:"+price+"  数量:"+total);
	}
	
}

Pig.java

public class Pig extends Animal {
	public Pig() {
		price = 15;
		total = 20;
	}
	@Override
	public void getDetail() {
		System.out.println("猪肉价格:"+price+"  数量:"+total);
	}
	
}

AnimalFactory.java

public class AnimalFactory {
	//创建相应的Animal子类
	public static Animal getAnimal(String cls) {
		if(cls.equals(Chicken.class.getSimpleName())) {
			return new Chicken();
		}else if(cls.equals(Pig.class.getSimpleName())){
			return new Pig();
		}else {
			System.out.println("无此类");
			return null;
		}
	}
}

Test.java,在主入口类中进行Chicken及Pig类,并获取相应的信息

public class Test {
	public static void main(String[] args) {
		Animal chicken = AnimalFactory.getAnimal(Pig.class.getSimpleName());
		Animal pig = AnimalFactory.getAnimal(Chicken.class.getSimpleName());
		
		chicken.getDetail();
		pig.getDetail();
	}
}

输出结果

猪肉价格:15.0  数量:20
鸡肉价格:10.0  数量:100

以上代码就是简单工厂模式,这种工厂模式的缺点很明显,AnimalFactory的拓展性不是很好,举一个例子,如果现在我要添加一个Fish.java,我需要修改AnimalFactory.java中的代码才行。

所以对AnimalFactory.java代码做如下的修改:

public class AnimalFactory {
	//创建相应的Animal子类
	public static Animal getAnimal(String cls) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		Class clazz = Class.forName(cls);
		return (Animal)clazz.newInstance();
	}
}

修改后的代码看似拓展性比较好,如果再次添加一个新类,并不会修改代码,但是却有一个新问题。AnimalFactory类似与一个中转站,这里面包含了对各种Animal的操作方法,比如Chicken销往北京的价格与数量和上海是不同的,所以在Chicken属性的赋值上我们要做区分,虽然我们能在Chicken.java中设置不同地区的不同属性值,但是Chicken只是bean,并不适合做这些工作;而在AnimalFactory中操作的话,会因为Aniaml种类的增多显得非常的冗余,所以使用下面介绍的一种工厂模式比较合适

二、工厂方法模式(多态工厂模式)

包括如下几个类

  • Chicken,Pig,Animal
  • AnimalFactory.java:抽象类
  • ChickenFactory.java:Chicken的工厂类,实现AnimalFactory接口
  • PigFactory.java:Pig的工厂类,实现AnimalFactory接口

我们对Chiken及Pig类的构造器进行简单的修改:

public class Chicken extends Animal {

	//初始化价格及数量
	public Chicken(float p,int t) {
		price = p;
		total = t;
	}
	
	@Override
	public void getDetail() {
		System.out.println("鸡肉价格:"+price+"  数量:"+total);
	}
	
}
public class Pig extends Animal {

	public Pig(float p,int t) {
		price = p;
		total = t;
	}
	
	@Override
	public void getDetail() {
		System.out.println("猪肉价格:"+price+"  数量:"+total);
	}
}

AnimalFactory.java

public interface AnimalFactory  {
	public Animal getAnimal();
}

ChickenFactory.java

public class ChickenFactory implements AnimalFactory {
	@Override
	public Animal getAnimal() {
		return new Chicken(10,100);
	}
}

PigFactory.java

public class PigFactory implements AnimalFactory{
	@Override
	public Animal getAnimal() {
		// TODO Auto-generated method stub
		return new Pig(15,150);
	}
}

在主程序Test中进行测试

public class Test {

	public static void main(String[] args){
		AnimalFactory chickenFactory = new ChickenFactory();
		Animal chicken = chickenFactory.getAnimal();
		chicken.getDetail();
		
		AnimalFactory pigFactory = new PigFactory();
		Animal pig = pigFactory.getAnimal();
		pig.getDetail();
	}
}

输出的结果

鸡肉价格:10.0  数量:100
猪肉价格:15.0  数量:150

如果我们需要添加一个Finish类的话,只需要创建Finish.java和FinishFactory.java即可;如果Chicken或者Pig类因为销往各地价格不同,只需要在各自的Factory中进行个性化代码添加即可,耦合性降低,代码也不会冗余

三、抽象工厂模式

我们依然以Chicken和Pig为例,Chicken,Pig可能销往北京,上海;而北京,上海既能接收Chicken,也能接收Pig。所以地点和产品更是一个产品族。我们对产品进行细化,对产品的工厂类进行细化

Animal.java:所有bean的父类

Chicken.java,Pig.java:某个产品的抽象类

BeijingChicken.java,BeijingPig.java,ShanghaiChicken.java,ShanghaiPig.java:对某个产品的具体细化

AnimalFactory:工厂类的父类

BeijingFactory.java,ShanghaiFactory.java:具体工厂类的细化

Animal.java  Chicken.java  Pig.java代码如下:

public interface Animal {
	void getDetail();
}


public abstract class Chicken implements Animal {
	public float price = 0;//价格
	public int total = 0;//数量
	public abstract void getDetail();
}


public abstract class Pig implements Animal {
	public float price = 0;//价格
	public int total = 0;//数量
	public abstract void getDetail();
}

这里我将属性提到具体的产品中,因为产品的属性不一定一样;这里Chicken Pig是抽象类,通过地点来将其细化

BeijingChicken.java  ShanghaiChicken.java代码如下

public class BeijingChicken extends Chicken {
	
	public BeijingChicken(float p,int t) {
		price = p;
		total = t;
	}
	@Override
	public void getDetail() {
		// TODO Auto-generated method stub
		System.out.println("北京鸡肉价格:"+price+"   数量:"+total);
	}
}



public class ShanghaiChicken extends Chicken {

	public ShanghaiChicken(float p,int t) {
		price = p;
		total = t;
	}
	@Override
	public void getDetail() {
		// TODO Auto-generated method stub
		System.out.println("上海鸡肉价格:"+price+"   数量:"+total);
	}
}

BeijngPig.java  ShanghaiPig.java代码如下:

public class BeijingPig extends Pig{
	public BeijingPig(float p,int t) {
		price = p;
		total = t;
	}
	@Override
	public void getDetail() {
		// TODO Auto-generated method stub
		System.out.println("北京猪肉价格:"+price+"   数量:"+total);
	}
}


public class ShanghaiPig extends Pig {
	public ShanghaiPig(float p,int t) {
		price = p;
		total = t;
	}
	@Override
	public void getDetail() {
		// TODO Auto-generated method stub
		System.out.println("上海猪肉价格:"+price+"   数量:"+total);
	}
}

以上的这四个类就是具体的产品

AnimalFactory.java  BeijingFactory.java   ShanghaiFactory.java代码如下

public interface AnimalFactory {
	public Animal getChickenDetail();
	public Animal getPigDetail();
}


public class BeijingFactory implements AnimalFactory {
	@Override
	public Animal getChickenDetail() {
		// TODO Auto-generated method stub
		return new BeijingChicken(10, 100);
	}
	@Override
	public Animal getPigDetail() {
		// TODO Auto-generated method stub
		return new BeijingPig(15, 150);
	}
}



public class ShanghaiFactory implements AnimalFactory {
	@Override
	public Animal getChickenDetail() {
		// TODO Auto-generated method stub
		return new ShanghaiChicken(20, 120);
	}

	@Override
	public Animal getPigDetail() {
		// TODO Auto-generated method stub
		return new ShanghaiPig(25, 130);
	}
}

以鸡肉为例,进行测试

public class Test {
	public static void main(String[] args) {
		AnimalFactory beijingChickenFactory = new BeijingFactory();
		BeijingChicken beijingChicken = (BeijingChicken) beijingChickenFactory.getChickenDetail();
		BeijingPig beijingPig = (BeijingPig) beijingChickenFactory.getPigDetail();
		beijingChicken.getDetail();
		beijingPig.getDetail();
	}
}

结果

北京鸡肉价格:10.0   数量:100
北京猪肉价格:15.0   数量:150

以上就是抽象工厂类的代码,这样做的好处:我如果想要添加一个深圳的地点,我只需要创建一个ShenzhenFactory.java即可,非常符合OCP原则。但是这样的模式依然有一个非常不好的缺点,就是如果我想要添加产品的话,依然需要改AnimalFactory.java中的代码

猜你喜欢

转载自blog.csdn.net/qq_32019367/article/details/85870982