简单工厂模式
简单工厂模式是一种创建型模式,它不属于23种设计模式。简单工厂模式是通过一个类(工厂类)来创建其他类的实例,其他类都有一个共同的父类。实例的创建是通过向工厂类传入不同的参数来创建不同的对象。
简单工厂模式需要的角色。
具体工厂就是那个创建类的类,抽象产品就是公共的父类,创建的实例就是具体工厂的实例。
- 一个抽象产品接口
- 多个具体产品类
- 一个具体工厂类
具体实例:
水果类接口
package simpleFactory;
public interface Fruit {
//采摘方法
public void get();
}
实现水果接口
苹果类
package simpleFactory;
public class Apple implements Fruit {
//采摘苹果
public void get() {
System.out.println("采摘苹果");
}
}
香蕉类
package simpleFactory;
public class Banana implements Fruit {
//采摘香蕉
public void get() {
System.out.println("采摘香蕉");
}
}
工厂类
package simpleFactory;
public class FruitFactory {
//采集水果
public static Fruit getFruit(String type) {
if(type.equals("apple")) {
return new Apple();
}else if(type.equals("banana")){
return new Banana();
}else {
System.out.println("输入有误");
return null;
}
}
}
client
package simpleFactory;
public class Client {
public static void main(String[] args) {
Fruit apple = FruitFactory.getFruit("apple");
Fruit banana = FruitFactory.getFruit("banana");
// Fruit other = FruitFactory.getFruit("pear");
apple.get();
banana.get();
// other.get();
}
}
运行结果
采摘苹果
采摘香蕉
简单工厂模式存在的弊端:
- 不同类的实例对象的新建逻辑都在一个类中,不能体现类的“高内聚”。
- 当有新的产品需要生产时,需要改动工厂类的代码,不符合“开放-封闭 ”原则。
简单工程就可以理解为:一个工厂,不同的产品,同一个工厂可以根据参数生产不同的产品。一句话:按需生产。需就是参数。
工厂方法模式
工厂方法模式是一种创建型模式,也叫多态工厂模式(运行时工厂呈现出一种多态),是设计模式中的一种,工厂方法模式的工厂类不再是一个具体的类,而是一个工厂接口,每个产品的生产交给实现它的具体的子类来完成,它只提供了生产产品的规范,具体的怎么生产由子类决定,在要扩展新的产品时,就实现一个新的产品工厂,扩展性较好。
工厂方法模式需要的角色
- 一个抽象产品接口
- 多个具体产品类
- 一个抽象工厂接口(对实现同一个抽象接口的类生产)
- 多个具体工厂类
模型图
实例
抽象工厂
package factoryMethod;
public interface FruitFactory {
public Fruit getFruit();
}
抽象工厂实现类
package factoryMethod;
public class AppleFactory implements FruitFactory {
@Override
public Fruit getFruit() {
return new Apple();
}
}
package factoryMethod;
public class BananaFactory implements FruitFactory {
@Override
public Fruit getFruit() {
return new Banana();
}
}
client
package factoryMethod;
public class Client {
public static void main(String[] args) {
FruitFactory factory = null;
Fruit fruit = null;
//苹果工厂生产苹果
factory = new AppleFactory();
fruit = factory.getFruit();
fruit.get();
//香蕉工厂生产香蕉
factory = new BananaFactory();
fruit =factory.getFruit();
fruit.get();
}
}
结果
采摘苹果
采摘香蕉
1,高内聚,每个工厂只有一种对象的实例化逻辑,代码清晰。
2,扩展性好,生产一种新的产品时不需要修改原来的工厂,只需新建一个生产该产品的工厂类即可,符合“开放-封闭”原则。
简单理解:多个工厂,多个产品类,不同的工厂可以生产不同的产品(例如:手机工厂生产手机,mp3工厂生产mp3)
抽象工厂模式
抽象工厂模式与工厂方法模式有相似之处,都是通过不同的工厂生产不同的产品,担关注点又有所不同。工厂方法模式关注生产不同族的商品(例如:苹果和香蕉,汽车与火车)抽象工厂的关注点在于不同的工厂可以生产同一个产品族的不同产品(例如苹果的大和小,不同品牌的笔记本)这里引用https://www.cnblogs.com/geek6/p/3951677.html关于抽象工厂模式的阐释。
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例,也就是创建的是一个产品线下的多个产品。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
工厂方法创建 "一种" 产品,他的着重点在于"怎么创建",也就是说如果你开发,你的大量代码很可能围绕着这种产品的构造,初始化这些细节上面。也因为如此,类似的产品之间有很多可以复用的特征,所以会和模版方法相随。
抽象工厂需要创建一些列产品,着重点在于"创建哪些"产品上,也就是说,如果你开发,你的主要任务是划分不同差异的产品线,并且尽量保持每条产品线接口一致,从而可以从同一个抽象工厂继承。
需要的角色
- 多个抽象产品类
- 一个抽象工厂接口(对实现不同抽象产品接口的类生产)
- 多个具体工厂类
产品图
这里的ProductA的子类1和子类2是属于同一产品族的,ProductB的子类1和子类2也是同一产品族(就如同联想笔记本和hp笔记本,还有大众帕萨特的高配车型和低配车型,铅笔的粗铅笔和细铅笔)
工厂图
Factory关注的不再是怎么生产产品,而是生产什么,在工厂方法模式中factory的不同子类生产的只是一种产品,而在抽象工厂模式中不同的子类生产不同的产品,就像下图Factory1可以生产产品A也可以生产产品B,但不同的Factory生产的同一类产品是不同的,就是说Facory1和Factory2生产的ProductA属于不同类的产品,就像(工厂1和工厂2都是生产笔记本电脑的厂商,虽然笔记本电脑都属于笔记本电脑类,但是他们生产不同品牌的电脑,工厂1生产联想,工厂2生产hp)
这里实例说明一下
抽象产品接口
package stractFactory;
public interface Fruit {
//采摘方法
public void get();
}
实现产品接口的抽象类
package stractFactory;
public abstract class Apple implements Fruit {
//采摘苹果
public abstract void get();
}
package stractFactory;
public abstract class Banana implements Fruit {
//采摘香蕉
public abstract void get();
}
实现抽象类的具体类
package stractFactory;
public class BigApple extends Apple {
@Override
public void get() {
System.out.println("大苹果");
}
}
package stractFactory;
public class SmallApple extends Apple {
@Override
public void get() {
System.out.println("小苹果");
}
}
package stractFactory;
public class BigBanana extends Banana {
@Override
public void get() {
System.out.println("大香蕉");
}
}
package stractFactory;
public class SmallBanana extends Banana {
@Override
public void get() {
System.out.println("小香蕉");
}
}
抽象工厂接口
package stractFactory;
public interface FruitFactory {
public Fruit getBanana();
public Fruit getApple();
}
具体实现类
package stractFactory;
public class SmallFactory implements FruitFactory {
@Override
public Fruit getBanana() {
return new SmallBanana();
}
@Override
public Fruit getApple() {
return new SmallApple();
}
}
package stractFactory;
public class BigFactory implements FruitFactory {
@Override
public Fruit getBanana() {
return new BigBanana();
}
@Override
public Fruit getApple() {
return new BigApple();
}
}
client
package stractFactory;
public class MainClazz {
public static void main(String[] args) {
FruitFactory factory = null;
factory = new BigFactory();
factory.getApple().get();
factory.getBanana().get();
factory = new SmallFactory();
factory.getApple().get();
factory.getBanana().get();
}
}
结果
大苹果
大香蕉
小苹果
小香蕉
从抽象工厂接口也可以看出,抽象工厂模式关注的是生产哪些产品而不是怎么生产,这里有点难理解,小编也要好好揣摩一下。