首先介绍下Java中简单工厂模式的实现:
首先加入接口
package com.animal;
public interface Animal {
void eat();
void sayHello();
}
然后是各个Animal的实现类
package com.animal;
public class Cat implements Animal {
@Override
public void eat() {
System.out.println("cat is eating");
}
@Override
public void sayHello() {
System.out.println("cat is saying hello");
}
}
package com.animal;
public class Dog implements Animal {
@Override
public void eat() {
System.out.println("dog is eating");
}
@Override
public void sayHello() {
System.out.println("dog is saying hello");
}
}
package com.animal;
public class Duck implements Animal {
@Override
public void eat() {
System.out.println("duck is eating");
}
@Override
public void sayHello() {
System.out.println("duck is saying hello");
}
}
设置Mapping用的Enum
package com.animal;
public enum AnimalType {
CAT("com.animal.Cat"),
DOG("com.animal.Dog"),
DUCK("com.animal.Duck");
private String value;
private AnimalType(String value) {
this.value = value;
}
public String toString() {
return this.value;
}
}
最后是工厂类
package com.animal;
public class AnimalFactory {
public static Animal getAnimal(AnimalType type) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
String clsName = type.toString();
Class clsInstance = null;
try {
clsInstance = Thread.currentThread().getContextClassLoader().loadClass(clsName);
} catch (Exception e) {
try {
clsInstance = Class.forName(clsName);
} catch (ClassNotFoundException e1) {
throw e1;
}
}
return Animal.class.cast(clsInstance.newInstance());
}
public static void main(String args[]) throws Exception {
Animal cat = AnimalFactory.getAnimal(AnimalType.CAT);
cat.eat();
Animal dog = AnimalFactory.getAnimal(AnimalType.DOG);
dog.eat();
Animal duck = AnimalFactory.getAnimal(AnimalType.DUCK);
duck.sayHello();
}
}
执行结果:
cat is eating
dog is eating
duck is saying hello
用java实现简单工厂的时候,可以用Enum来Mapping和类之间的关系,并且用Enum类型限制了工厂方法的参数。
接下来介绍一种用NodeJS实现相同模式的方法
大家在使用require函数的时候,一般参数都会指定一个js文件路径,用来标识模块位置。但是,如果参数是一个directory,结果会怎么样?
首先,文件夹结构改成下面这样
projectFolder
|_animals
|_index.js
|_cat.js
|_dog.js
|_duck.js
|_test.js
|_animal.js(Interface or Parent Class)
首先给出animal.js的参考实现
function Animal() {};
Animal.prototype = {
sayHello: function() {
console.log("animal is saying hello");
},
eat: function() {
console.log("animal is eating");
}
};
exports = module.exports = Animal;
然后是各大实现类
cat.js
var utils = require("util");
var Animal = require("../animal");
function Cat() {}
utils.inherits(Cat, Animal);
Cat.prototype.eat = function() {
console.log("cat is eating");
};
Cat.prototype.sayHello = function() {
console.log("cat is saying hello");
};
exports = module.exports = Cat;
dog.js
var utils = require("util");
var Animal = require("../animal");
function Dog() {}
utils.inherits(Dog, Animal);
Dog.prototype.eat = function() {
console.log("dog is eating");
};
exports = module.exports = Dog;
duck.js
var utils = require("util");
var Animal = require("../animal");
function Duck() {}
utils.inherits(Duck, Animal);
Duck.prototype.eat = function() {
console.log("duck is eating");
};
exports = module.exports = Duck;
看懂了Java实现中的Enum,那么下面的index.js也不难理解
module.exports = {
cat: require("./cat"),
dog: require("./dog"),
duck: require("./duck")
};
最后是测试类中的工厂方法调用
var animals = require("./animals");
var cat = new animals["cat"]();
cat.eat();
cat.sayHello();
var dog = new animals["dog"]();
dog.eat();
dog.sayHello();
var duck = new animals["duck"]();
duck.eat();
duck.sayHello();
最后结果:
cat is eating
cat is saying hello
dog is eating
animal is saying hello
duck is eating
animal is saying hello
当我在Socket.io的源码中看到这种用法的时候,不禁感到,NodeJS实在是太有前途了。利用NodeJS原生的module标准,即可轻松实现工厂方法。
浙公网安备 33010602011771号