面向对象的设计要遵循几项基本原则:
OCP(open-closed principle ):开闭原则,一个类的实体应该对扩展开放,对修改关闭。
DIP(dependence invers princip):依赖倒转原则,要针对接口编程,而不是针对实现编程。
LOD(low of demeter):迪米特法则:只与你直接的朋友通讯,而不与陌生人通讯。 工厂模式主要分三种,简单工厂模式,工厂方法模式和抽象工厂模式。
工厂模式也是设计模式中最常用的模式之一,工厂模式的主要目的是要使调用者和构建者分离,具体优点有:
可以使代码结构清晰,有效的封装变化。在编程中,产品类的实例化有事是复杂多变的。通过把实例化过程封装,是的调用者根本无需关心产品的实例化过程,只需要通过方法调用到需要的类。
对调用者屏蔽具体的产品类,使用工厂类,调用者只要关心调用的接口,即使具体的实现过程发生变化,对调用者也没有影响。
降低耦合度。
简单工厂模式
在一般的情况下,我们在一个类中调用另一个类时需要通过实例化需要的类来调用,这时候调用者参与了实体类实例化的构造,增加了耦合 度,工厂模式就是要把这种实例化类的过程重新包装起来,调用者只需调用工厂的某个方法边能获取类的实例化对象。
我们有一个汽车接口
package com.panda.com.simpleFactory;
public interface Car {
void run();
}
分别有两个汽车来实现
package com.panda.com.simpleFactory;
public class Byd implements Car {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("比亚迪车");
}
}
package com.panda.com.simpleFactory;
public class Bmw implements Car {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("宝马车");
}
}
和一个工厂类package com.panda.com.simpleFactory;
public class Factory {
public static Car getcar(String car){
if("宝马".equals(car)){
return new Bmw();
}else if("比亚迪".equals(car)){
return new Byd();
}else{
return null;
}
}
}
然后可以通过这个工厂类来调用静态方法得到实例化的对象
package com.panda.com.simpleFactory;
/**
* 简单工厂模式
* @author Administrator
*
*/
public class UseCar {
public static void main(String[] args) {
Car car1 = Factory.getcar("宝马");
Car car2 = Factory.getcar("比亚迪");
car1.run();
car2.run();
}
}
如果增加新的实体类的汽车,只需要在工厂类中添加合适的条件和返回值,而调用者的方法不会改变。
当然,如果仔细观察我们就会发现这个违反了OCP原则,因为涉及到修改工厂类的代码,违反了只能扩展,不能修改的原则。
工厂方法模式
所谓工厂方法就是为每一个实体类写一个对应工厂类,当调用者调用时就可以直接按照各自的工厂方法进行调用。如例
写一个工厂接口
package com.panda.com.factoryMethod;
public interface Factory {
Car getCar();
}
然后为每个实体类写一个实现工厂接口的对应的工厂类
package com.panda.com.factoryMethod;
public class BmwFactory implements Factory {
@Override
public Car getCar() {
return new Bmw();
}
}
package com.panda.com.factoryMethod;
public class BydFactory implements Factory {
@Override
public Car getCar() {
return new Byd();
}
}
这样在调用时这些使用工厂类的对象来调用方法就可以
package com.panda.com.factoryMethod;
/**
* 工厂方法模式
* @author Administrator
*/
public class UseCar {
public static void main(String[] args) {
Car car1 = new BmwFactory().getCar();
Car car2 = new BydFactory().getCar();
car1.run();
car2.run();
}
}
对比简单工厂模式,工厂方法完美的避免了修改原有代码这一准则,但是同时,当我们新建实体类时却要写一个相对应的工厂类,实体类多起来后,类的数量会比较臃肿,所以两相对比,虽然简单工厂模式稍微违反了OCP准则,但在实际开发中,简单工厂模式更加常用。
抽象工厂模式
抽象工厂模式完全有别于前两种工厂模式,因为抽象工厂是对于一个产品族而言的,所谓产品族,就是组成一个完整产品的各部件。例如一个汽车是有发动机,车体,轮胎,座椅,内饰等等组成,这些组件就是一个产品族。
我们现就以一个发动机,座椅,轮胎为一个产品族用代码实现抽线工厂模型
package com.panda.com.abstractFactory;
public interface Engin {
void run();
}
class goodEngin implements Engin{
@Override
public void run() {
System.out.println("跑得快");
}
}
class badEngin implements Engin{
@Override
public void run() {
System.out.println("跑得慢");
}
}
package com.panda.com.abstractFactory;
public interface Seat {
void massage();
}
class goodSeat implements Seat{
@Override
public void massage() {
System.out.println("有按摩功能");
}
}
class badSeat implements Seat{
@Override
public void massage() {
System.out.println("没有按摩功能");
}
}
package com.panda.com.abstractFactory;
public interface Tyre {
void revoles();
}
class goodTyre implements Tyre{
@Override
public void revoles() {
// TODO Auto-generated method stub
System.out.println("质量好");
}
}
class badTyre implements Tyre{
@Override
public void revoles() {
// TODO Auto-generated method stub
System.out.println("质量差");
}
}
然后是一个抽象工厂接口和一个工厂实现类package com.panda.com.abstractFactory;
public interface Factory {
Engin getEngin();
Seat getSeat();
Tyre getTyre();
}
package com.panda.com.abstractFactory;
public class GoodCarFactory implements Factory{
@Override
public Engin getEngin() {
// TODO Auto-generated method stub
return new goodEngin();
}
@Override
public Seat getSeat() {
// TODO Auto-generated method stub
return new goodSeat();
}
@Override
public Tyre getTyre() {
// TODO Auto-generated method stub
return new goodTyre();
}
}
最后调用者用工厂调用package com.panda.com.abstractFactory;
public class Client {
/**
* 抽象工厂模式
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Factory factory = new GoodCarFactory();
Engin en = factory.getEngin();
en.run();
}
}
这种模式有个前提,那就是不能增加某个产品,而只能增加一个产品族。