工厂模式:工厂负责实例化大量具有相同接口的类,事先不需要知道是属于哪一个类,具有自己判断的能力;
工厂模式分为:简单工厂,工厂和抽象工厂。
先来看下简单工厂
package com.yanglf;
public class SimpleFactory {
public Fruit getFruit(String className){
if("apple".equals(className)){
return new Apple();
}
if("banana".equals(className)){
return new Banana();
}
if("orange".equals(className)){
return new Orange();
}
return null;
}
}
//建立水果接口
interface Fruit{
//所有的水果都可以吃
public void eat();
}
//苹果属于水果
class Apple implements Fruit {
public void eat() {
System.out.println("吃苹果");
}
}
//香蕉也属于水果
class Banana implements Fruit{
public void eat() {
System.out.println("吃香蕉");
}
}
//后来加入的橘子
class Orange implements Fruit{
@Override
public void eat() {
System.out.println("吃橘子");
}
}
//有一个人想吃水果
class Person{
public static void main(String[] args) throws Exception {
SimpleFactory factory = new SimpleFactory();
Fruit f = factory.getFruit("apple");//想吃的水果种类在这选择,工厂负责实例化水果
f.eat();
}
}
这种简单工厂模式有一个很大的缺点,就是添加水果的时候同样也要修改工厂中的代码,这不符合java开闭原则:即对扩展打开,对修改关闭;
利用工厂模式对上面代码进行优化
package com.yanglf;
public class SimpleFactory {
public Fruit getFruit(String className){
Fruit f = null;
try {
//利用反射找到类
f = (Fruit) Class.forName(className).newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
return f;
}
}
//建立水果接口
interface Fruit{
//所有的水果都可以吃
public void eat();
}
//苹果属于水果
class Apple implements Fruit {
public void eat() {
System.out.println("吃苹果");
}
}
//香蕉也属于水果
class Banana implements Fruit{
public void eat() {
System.out.println("吃香蕉");
}
}
//后来加入的橘子
class Orange implements Fruit{
@Override
public void eat() {
System.out.println("吃橘子");
}
}
//有一个人想吃水果
class Person{
public static void main(String[] args) throws Exception {
SimpleFactory factory = new SimpleFactory();
Fruit f = factory.getFruit("com.yanglf.Apple");//想吃的水果种类在这选择,工厂负责实例化水果
f.eat();
}
}
在工厂模式中,如果添加水果就不需要再修改代码了,前提是需要继承水果类。
如果这样写,那我们通过这个工厂就只能吃水果了,如果我们想吃蔬菜怎么办呢,这就需要抽象工厂了,我们对工厂模式进一步抽象,建立一个抽象的工厂类,
package com.yanglf;
public class TestFactory {
}
//建立水果接口
interface Fruit{
//所有的水果都可以吃
public void eat();
}
//苹果属于水果
class Apple implements Fruit {
public void eat() {
System.out.println("吃苹果");
}
}
//香蕉也属于水果
class Banana implements Fruit{
public void eat() {
System.out.println("吃香蕉");
}
}
//
class Orange implements Fruit{
@Override
public void eat() {
System.out.println("吃橘子");
}
}
interface Vegetable{
public abstract void cook();
}
class Tomato implements Vegetable{
public void cook() {
System.out.println("西红柿可以炒鸡蛋");
}
}
class Potato implements Vegetable{
@Override
public void cook() {
System.out.println("土豆可以炸薯条");
}
}
abstract class Fac {
public abstract Fruit getFruit(String className);
public abstract Vegetable getVegetable(String className);
}
class Factory extends Fac{
public Fruit getFruit(String className){
Fruit f = null;
try {
f = (Fruit) Class.forName(className).newInstance();
} catch (InstantiationException | IllegalAccessException
| ClassNotFoundException e) {
e.printStackTrace();
}
return f;
}
public Vegetable getVegetable(String className) {
Vegetable veg = null;
try {
veg = (Vegetable) Class.forName(className).newInstance();
} catch (InstantiationException | IllegalAccessException
| ClassNotFoundException e) {
e.printStackTrace();
}
return veg;
}
}
class Person{
public static void main(String[] args) throws Exception {
Factory factory = new Factory();
Fruit f = factory.getFruit("com.yanglf.Banana");
f.eat();
//或者我们可以选择蔬菜
Vegetable veg = factory.getVegetable("com.yanglf.Tomato");
veg.cook();
}
}