设计模式(二)----工厂模式和抽象工厂模式

工厂模式简介

工厂模式(Factory Pattern)是Java中最常用的设计模式之一。它提供了一种创建对象的最佳方式。在工厂模式中,在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
主要解决:接口选择问题。
何时使用:明确地计划不同条件下创建不同实例时。
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
关键代码:创建过程在其子类进行。
应用实例:想要一辆汽车,可直接从工厂里面提货,不用管这辆车是怎么做出来的,也不用管汽车里的具体实现。
优点:一个调用者想创建一个对象,只需知道其名称即可。扩展性高,若想增加一个产品,只需扩展一个工厂类就可以。屏蔽产品的具体实现,调用者只关心产品接口。
缺点:每次增加一个产品时,都需增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程序上增加了系统的复杂度,同时也增加了系统具体类的依赖。
使用场景:日志记录器,记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
数据库访问,当用户不知道系统最后采用哪一类数据库,以及数据库可能有变化时。
注:作为一种创建型设计模式,在任何需要生成复杂对象的地方,都可使用工厂模式。复杂对象适合使用工厂模式,而简单对象,特别是只需通过new就可完成创建的对象,无需使用工厂模式。若使用工厂模式,就需引入一个工厂类,会增加系统复杂度。

创建接口

public interface Person {
	void eat();
}

创建接口实现类
Chinese类

public class Chinese implements Person {
	public void eat() {
		System.out.println("吃水饺。。。");
	}
}

American类

public class American implements Person {
	public void eat() {
		System.out.println("Eat KFC。。。");
	}
}

British类

public class British implements Person {
	public void eat() {
		System.out.println("Eat Bread。。。");
	}
}

创建工厂,生成基于给定信息的实体类对象

public class PersonFactory {
	public Person getPerson(String person) {
		if (person == null) {
			return null;
		}
		if (person.equalsIgnoreCase("Chinese")) {
			return new Chinese();
		} else if (person.equalsIgnoreCase("American")) {
			return new American();
		} else if (person.equalsIgnoreCase("British")) {
			return new British();
		}
		return null;
	}
}

使用工厂,通过传递类型信息来获取实体类对象

public class FactoryPatternDemo {
	public static void main(String[] args) {
		//新建工厂对象
		PersonFactory pFactory = new PersonFactory();
		//通过工厂获取chinese对象
		Person chinese = pFactory.getPerson("Chinese");
		chinese.eat();
		//通过工厂获取american对象
		Person american = pFactory.getPerson("American");
		american.eat();
		//公共工厂获取british对象
		Person british = pFactory.getPerson("British");
		british.eat();
	}
}

输出结果为

吃水饺。。。
eat KFC。。。
eat Bread。。。

抽象工厂模式简介

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要解决:接口选择问题。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。
关键代码:在一个工厂里聚合多个同类产品。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的Creator里加代码,又要在具体的里面加代码。
注:产品族难扩展,产品等级易扩展。
抽象工厂说白了就是在工厂里面获取工厂。
实例场景:将一所大学比作一个超级工厂,学校里的各个系比作从超级工厂获取的子工厂,每个系下面的各个班级比作从子工厂获取的各个对象(各个子工厂中的各个对象须有共性)。

定义Information接口(学院)

public interface Information {
	void study();
}

定义Software类(专业)

public class Software implements Information {
	public void study() {
		System.out.println("Study Software。。。");
	}
}

定义Network类(专业)

public class Network implements Information {
	public void study() {
		System.out.println("Study Network。。。");
	}
}

定义Computer类(专业)

public class Computer implements Information {
	public void study() {
		System.out.println("Study Computer。。。");
	}
}

定义Physical接口(学院)

public interface Physical {
	void train();
}

定义Athletics类(专业)

public class Athletics implements Physical {
	public void train() {
		System.out.println("Train Athletics。。。");
	}
}

定义Basketball类(专业)

public class Basketball implements Physical {
	public void train() {
		System.out.println("Train Bastetball。。。");
	}
}

定义Football类(专业)

public class Football implements Physical {
	public void train() {
		System.out.println("Train Football。。。");
	}
}

为Information和Phyfical对象创建抽象类来获取工厂

public abstract class AbstractFactory {
	public abstract Information getInformation(String information);
	public abstract Physical getPhysical(String physical);
}

创建扩展了AbstractFactory的工厂类,基于给定信息生成实体类对象

public class InformationFactory extends AbstractFactory {
	public Information getInformation(String information) {
		if (information == null) {
			return null;
		}
		if (information.equalsIgnoreCase("Software")) {
			return new Software();
		} else if (information.equalsIgnoreCase("Network")) {
			return new Network();
		} else if (information.equalsIgnoreCase("Computer")) {
			return new Computer();
		}
		return null;
	}

	public Physical getPhysical(String physical) {
		return null;
	}
}
public class PhysicalFactory extends AbstractFactory {
	public Information getInformation(String information) {
		return null;
	}

	public Physical getPhysical(String physical) {
		if (physical == null) {
			return null;
		}
		if (physical.equalsIgnoreCase("Athletics")) {
			return new Athletics();
		} else if (physical.equalsIgnoreCase("Basketball")) {
			return new Basketball();
		} else if (physical.equalsIgnoreCase("Football")) {
			return new Football();
		}
		return null;
	}
}

创建一个工厂创造器/生成器类,通过传递Information或Physical信息来获取工厂

public class FactoryProducer {
	public static AbstractFactory getFactory(String factory) {
		if (factory.equalsIgnoreCase("Information")) {
			return new InformationFactory();
		} else if (factory.equalsIgnoreCase("physical")) {
			return new PhysicalFactory();
		}
		return null;
	}
}

使用FactoryProducer获取AbstractFactory,通过传递类信息来获取实体类对象

public class AbstractFactoryPatternDemo {
	public static void main(String[] args) {
		//获取信息学院(工厂)
		AbstractFactory informationFactory = FactoryProducer.getFactory("Information");
		//获取软件专业(对象)
		Information software = informationFactory.getInformation("Software");
		software.study();
		//获取网络专业(对象)
		Information network = informationFactory.getInformation("Network");
		network.study();
		//获取计算机专业(对象)
		Information computer = informationFactory.getInformation("Computer");
		computer.study();
		//获取体育学院(工厂)
		AbstractFactory physicalFactory = FactoryProducer.getFactory("Physical");
		//获取田径专业(对象)
		Physical athletics = physicalFactory.getPhysical("Athletics");
		athletics.train();
		//获取篮球专业(对象)
		Physical basketball = physicalFactory.getPhysical("Basketball");
		basketball.train();
		//获取足球专业(对象)
		Physical football = physicalFactory.getPhysical("Football");
		football.train();
	}
}

输出结果为

Study Software。。。
Study Network。。。
Study Computer。。。
Train Athletics。。。
Train Basketball。。。
Train Football。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值