工厂模式(Factory Pattern)是开发中比较常用的设计模式之一。
它属于创建型模式(单例模式就是创建型模式的一种),这种模式让我们在创建对象时不会直接暴露创建逻辑,而是通过使用一个共同的接口来完成对象的创建
。
工厂模式可以分为三种,分别是简单工厂模式、工厂方法模式以及抽象工厂模式
(后面的两种模式都是基
于第一种模式进行的),我们主要来讲解简单工厂模式。
其实工厂设计模式就是根据现实抽象过来的模式,
我们在Java中,习惯要用什么对象,就去找它的类去new,主要其实并不好
,类与类的耦合度会比较高,而且我们现实中也不会你需要买什么东西就跑去生产车间里去买吧,我们生活中更多的是一个商店或者是商场把对应的商品从生产线上购买到店里来,然后你需要什么跟老板说你要买的商品名称,老板就提供给你。
由商店来管理这些对象,我们不关心这些商品的生产细节。
➢调用者想创建一一个对象,只要知道其名称(也就是不同的标签)就可以在工厂获取具体的
对象;
➢扩展性强,如果想增加一个产品(也就是具体的对象),只要扩展工厂类就可以(也就是
增加不同的标签,增加不同标签所对应的对象) ;
➢屏蔽产品的具体实现,调用者只关心产品的接口、无需关心内部实现;
➢面向接口编程,体现了面向对象的思想;
public class FactoryDemo1 {
public static void main(String[] args) {
Fruit apple = new Apple();
Fruit banane = new Banane();
apple.eat();
banane.eat();
}
}
interface Fruit{
void eat();
}
class Apple implements Fruit{
public void eat() {
System.out.println("苹果真好吃");
}
}
class Banane implements Fruit{
public void eat() {
System.out.println("香蕉真好吃");
}
}
public class FactoryDemo2 {
public static void main(String[] args) {
FruitFatory fatory = new FruitFatory();
Fruit apple = fatory.getApple();
Fruit banane = fatory.getBanane();
apple.eat();
banane.eat();
}
}
class FruitFatory{
public Fruit getApple() {
return new Apple();
}
public Fruit getBanane() {
return new Banane();
}
}
interface Fruit{
void eat();
}
class Apple implements Fruit{
public void eat() {
System.out.println("苹果真好吃");
}
}
class Banane implements Fruit{
public void eat() {
System.out.println("香蕉真好吃");
}
}
public class FactoryDemo3 {
public static void main(String[] args) {
Fruit apple = FruitFatory.getApple();
Fruit banane = FruitFatory.getBanane();
apple.eat();
banane.eat();
}
}
class FruitFatory{
public static Fruit getApple() {
return new Apple();
}
public static Fruit getBanane() {
return new Banane();
}
}
interface Fruit{
void eat();
}
class Apple implements Fruit{
public void eat() {
System.out.println("苹果真好吃");
}
}
class Banane implements Fruit{
public void eat() {
System.out.println("香蕉真好吃");
}
}
public class FactoryDemo4 {
public static void main(String[] args) {
Fruit apple = FruitFatory.getFruit("apple");
Fruit banane = FruitFatory.getFruit("banane");
apple.eat();
banane.eat();
}
}
class FruitFatory{
public static Fruit getFruit(String fruitName) {
if("apple".equalsIgnoreCase(fruitName)) {
return new Apple();
}else if("banane".equalsIgnoreCase(fruitName)) {
return new Banane();
}else {
return null;
}
}
}
interface Fruit{
void eat();
}
class Apple implements Fruit{
public void eat() {
System.out.println("苹果真好吃");
}
}
class Banane implements Fruit{
public void eat() {
System.out.println("香蕉真好吃");
}
}
/src/lession14/entity
public interface Fruit {
void eat();
}
public class Pear implements Fruit{
@Override
public void eat() {
System.out.println(" 梨真好吃 ");
}
}
public class Banane implements Fruit{
public void eat() {
System.out.println(" 香蕉真好吃 ");
}
}
public class Apple implements Fruit{
public void eat() {
System.out.println(" 苹果真好吃 ");
}
}
/**
*
* 想让你的工厂直接不需要进行频繁的更改,它也可以顺利的生产出
* 我们想要的对象!
*
*/
public class FactoryDemo5 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Fruit apple = FruitFatory.getFruit("apple");
Fruit banane = FruitFatory.getFruit("banane");
Fruit pear = FruitFatory.getFruit("pear");
apple.eat();
banane.eat();
pear.eat();
}
}
class FruitFatory{
public static Fruit getFruit(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class<?> classObj = Class.forName("lession14.entity."+initClassName(className));
return (Fruit) classObj.newInstance();
}
public static String initClassName(String className) {
StringBuilder sb = new StringBuilder();
return sb.append((className.charAt(0)+"").toUpperCase()).append(className.substring(1).toLowerCase()).toString();
}
}
在Demo2中,我们已经可以通过-一个工厂类来构建具体的类对象了,但是还需要像调用方法一样来操作, 并且不同的对象不同的方法名,能否进一步 进行优化?
到Demo3中,我们直接使用一个统一-的方 法来获取不同的对象,在方法内部进行名字的判断就可以了,然后通过new或者是通过反射来获取到指定的对象。
在该模式中,工厂类是整个模式的关键。它包含必要的判断逻辑(比如根据外界给定的信息,决定究竟应该创建哪个具体类的对象)。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。
但是,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。并且,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。在具体调用比较麻烦。