简单工厂
简单工厂是真的简单,如果我们有N个类需要被工厂管理,那我们给N个类分配一个唯一标识,调用工厂方法需要传递标识,工厂根据传入的标识创建对象。这种做法的缺点很明显,扩展性太差!严重违反开闭原则。如果要是又新增M个类需要被工厂管理,那么还要去改工厂类代码。
package simplefactory_k;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-01-15 10:45
* @notify
* @version 1.0
*/
public class Airplane {
}
View Code
package simplefactory_k;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-01-15 10:46
* @notify
* @version 1.0
*/
public class Rocket {
}
View Code
package simplefactory_k;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-01-15 10:46
* @notify
* @version 1.0
*/
public class Screw {
}
View Code
package simplefactory_k;
/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-01-15 10:46
* @notify
* @version 1.0
*/
public class SimpleFactoryK {
public static Object getObject(String obj) {
if (obj.equals("飞机")) {
return new Airplane();
} else if (obj.equals("火箭")) {
return new Rocket();
} else if (obj.equals("螺丝")) {
return new Screw();
} else {
return null;
}
}
}
View Code
package simplefactory_k;
/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-01-15 10:53
* @notify
* @version 1.0
*/
public class Main {
public static void main(String[] args) {
Object airplane = SimpleFactoryK.getObject("飞机");
System.out.println(airplane instanceof Airplane);
Object rocket = SimpleFactoryK.getObject("火箭");
System.out.println(rocket instanceof Rocket);
Object screw = SimpleFactoryK.getObject("螺丝");
System.out.println(screw instanceof Screw);
}
}
View Code
工厂方法
工厂方法弥补了简单工厂不易于扩展的缺点,给一个产品族定义一个接口,产品族下边定义具体的产品实现。(产品族的纵向的,接口和实现类,或者抽象类和子类)创建产品族工厂接口,不同的产品工厂创建不同的产品。苹果和香蕉都是都是水果族,苹果工厂生产苹果,香蕉工厂生产香蕉,而他们属于水果工厂。当我们需要增加另外一种水果,例如橘子,需要我们创建一个橘子类,和一个橘子类的工厂,这听起来好像又麻烦了许多。但是我们假设,创建一个类需要很多的参数,整体的创建需要写很多的代码。那创建一个工厂类是完全有必要的。
package factorymethod_k;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-01-15 14:22
* @notify
* @version 1.0
*/
public interface Fruiter {
void product();
}
View Code
package factorymethod_k;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-01-15 14:24
* @notify
* @version 1.0
*/
public class Apple implements Fruiter {
@Override
public void product() {
System.out.println("种出苹果");
}
}
View Code
package factorymethod_k;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-01-15 14:24
* @notify
* @version 1.0
*/
public class Banana implements Fruiter {
@Override
public void product() {
System.out.println("种出香蕉");
}
}
View Code
package factorymethod_k;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-01-15 14:25
* @notify
* @version 1.0
*/
public interface Farm {
Fruiter getBean();
}
View Code
package factorymethod_k;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-01-15 14:26
* @notify
* @version 1.0
*/
import factoryMethod.Fruit;
public class AppleFarm implements Farm{
@Override
public Fruiter getBean() {
return new Apple();
}
}
View Code
package factorymethod_k;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-01-15 14:26
* @notify
* @version 1.0
*/
public class BananaFarm implements Farm{
@Override
public Fruiter getBean() {
return new Banana();
}
}
View Code
package factorymethod_k;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2020-01-15 14:29
* @notify
* @version 1.0
*/
public class Client {
public static void main(String[] args) {
Farm farm = new AppleFarm();
Fruiter fruiter = farm.getBean();
Farm farm2 = new BananaFarm();
Fruiter fruiter2 = farm2.getBean();
System.out.println(fruiter instanceof Apple);
System.out.println(fruiter2 instanceof Banana);
}
}
View Code
抽象工厂
工厂方法对于单一产品族是够用了,但是如果是多产品族就不行了。思考一个场景,有一个水果族,和一个蔬菜族。水果和蔬菜都分热带种植环境,和常温种植环境。如果使用工厂方法,我们要怎么做呢?创建一个水果族接口,创建一个水果族工厂接口,创建一个蔬菜族的接口,一个蔬菜族工厂接口。但这显然是不符合实际逻辑的,热带水果和常温水果肯定不能在一个工厂被创建出来。热带蔬菜和常温蔬菜也是。于是我们需要横向抽取。热带水果,常温水果都是水果,热带蔬菜,常温蔬菜都是蔬菜。我们在园丁接口做抽取,有管理常温农作物的园丁和管理热带农作物的园丁。现在一个农场就可以创建两个族群的产品了。
package abstractFactory;
/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-07-24 10:55
* @notify 蔬菜接口
* @version 1.0
*/
public interface Veggie {
}
View Code
package abstractFactory;
/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-07-24 10:58
* @notify 热带的蔬菜
* @version 1.0
*/
import com.sun.org.apache.regexp.internal.RE;
public class TropicalVeggie implements Veggie {
private String name;
public TropicalVeggie(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
View Code
package abstractFactory;
/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-07-24 10:56
* @notify 北方的蔬菜
* @version 1.0
*/
public class NorthernVeggie implements Veggie {
private String name;
public NorthernVeggie(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
View Code
package abstractFactory;
/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-07-24 11:00
* @notify 水果接口
* @version 1.0
*/
public interface Fruit {
}
View Code
package abstractFactory;
/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-07-24 11:00
* @notify 北方的水果
* @version 1.0
*/
public class NorthernFruit implements Fruit {
private String name;
public NorthernFruit(String name) {
this.name = name;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
View Code
package abstractFactory;
/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-07-24 11:02
* @notify 热带的水果
* @version 1.0
*/
public class TropicalFruit implements Fruit {
private String name;
public TropicalFruit(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
View Code
package abstractFactory;
/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-07-24 10:50
* @notify 园丁抽象类
* @version 1.0
*/
public interface Gardener {
}
View Code
package abstractFactory;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-07-24 10:50
* @notify 管理北方农场的园丁
* @version 1.0
*/
public class NorthernGardener implements Gardener {
// 北方的水果
public Fruit createFruit(String name) {
return new NorthernFruit(name);
}
//北方的蔬菜
public Veggie createVeggie(String name) {
return new NorthernVeggie(name);
}
}
View Code
package abstractFactory;
/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-07-24 10:53
* @notify 管理热带农场的园丁
* @version 1.0
*/
public class TropicalGardener implements Gardener{
//热带水果
public Fruit createFruit(String name){
return new TropicalFruit(name);
}
//热带蔬菜
public Veggie createVeggie(String name){
return new TropicalVeggie(name);
}
}
View Code
package abstractFactory;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-07-24 12:28
* @notify
* @version 1.0
*/
import junit.framework.TestCase;
public class AbstractFactoryTest extends TestCase {
public void testCreate(){
TropicalGardener tropicalGardener = new TropicalGardener();
Fruit fruit1 = tropicalGardener.createFruit("热带水果");
Veggie veggie1 = tropicalGardener.createVeggie("热带蔬菜");
assertTrue(fruit1 instanceof TropicalFruit);
assertTrue(veggie1 instanceof TropicalVeggie);
NorthernGardener northernGardener = new NorthernGardener();
Fruit fruit2 = northernGardener.createFruit("北方水果");
Veggie veggie2 = northernGardener.createVeggie("北方蔬菜");
assertTrue(fruit2 instanceof NorthernFruit);
assertTrue(veggie2 instanceof NorthernVeggie);
}
}
View Code