距离上次写设计模式的博客已经很久,翻看一下,是【java设计模式之责任链----Filter (2015-06-15 22:59)】时间好长了啊。
按理说,应该两天一片的速度,哎,都是我太懒了,眼高手低的,而且还有点。。。所以应该要想我的座右铭一样【专心致志做好一件事】,好好做事,认真做人。
不闲扯了,现在开始正题:
同样,这一片的工厂系列的设计模式依旧是学习了马老师的设计模式总结来写的。听马老师的课感觉倍舒服,无拘无束,虽然还是会过后就忘了,嘻嘻^^!
由于马老师的课程安排深浅得很合理,我就不自己瞎吵吵了,按照课程的安排来。
step1 -- 围绕交通工具展开课程,如图
step2 -- 【静态工厂模式】如何控制司机只开一辆车而且车的产生不是司机来控制的?
静态工厂模式:
public class Car { private static Car car = new Car(); // private static List<Car> cars = new ArrayList<Car>(); private Car(){ } public static Car getInstance(){ return car; } public void run(){ System.out.println("我开车了。。。"); } }
将构造方法私有化,在类的外部就不能通过直接new来获取对象了。如果不将getInstance声明为static,那么久不能在外部直接调用该方法。如果在该方法中直接返回【new Car()】,那么我开的车就不是一个车了,每次调用这个方法获得的都是新Car。加上【private static Car car = new Car();】就将Car的对象进行固定了,这样就只能开一辆,别人获得的也是同一辆车,意思就是在整个环境中就只有这么一个Car,这就是单例模式。
step3 -- 【简单工厂模式】如何任意定制交通工具的类型和生产过程
为了实现可以对交通工具的任意定制,此时面向对象的java的优势就出来了,她的封装、继承和多态的特点就show了。具体怎么实现呢?
既然都是交通工具,都会移动,那么我以定义一个接口【Moveable】,
public interface Moveable { void run(); }
在调用具体的交通工具时就是面向接口编程,但前提是这些交通工具都要实现这个接口。如下代码:
public class Test { public static void main(String[] args) { Moveable m = new Car(); m.run(); } }
其中的Car实现了那个Moveable接口。
那么怎么控制这些个交通工具的生产过程呢?比如,如何控制是否有足够权限来生产这类交通工具。
这肯定就要用工厂了啊,工厂就是生产产品,生产交通工具的啊,权限就像是你给工厂下的订单,工厂不能相信你,工厂也不敢给你做。
那么具体实现是什么呢?
给每一个实现了【Moveable】接口的类,都专门“建立”一个工厂,专门来生产对应得产品。
为了,使这些工厂能有同统一的方法来产生对象,也就是为了以后的扩展性更好,需求发生改变时修改的地方最少,那么就给这些工厂升华出一个父类或者是接口都OK!这里就来个抽象类【VehicleFactory】
看代码:
public abstract class VehicleFactory { abstract Moveable create(); } --------------------------- public class CarFactory extends VehicleFactory{ public Moveable create() { return new Car(); } } --------------------------- public class Test { public static void main(String[] args) { VehicleFactory factory = new BroomFactory(); Moveable m = factory.create(); m.run(); } }
step4 -- 【抽象工厂模式】系列产品的生产,如果还是用简单工厂模式的话,那么要改的话必然会早成很多地方要改,而且扩展也不方便,因为这一系列的产品工厂都得重“建立”,那么怎样才能省,才能方便呢?
思路就是,有一个工厂可以生产一系列的产品,而不是只生产一类产品。好了,思路出来了代码上:
public abstract class AbstractFactory { public abstract Vehicle createVehicle(); public abstract Weapon createWeapon(); public abstract Food createFood(); } ------------------------ public abstract class Vehicle { public abstract void run(); } ----------------------- public abstract class Weapon { public abstract void shoot(); } ------------------------- public abstract class Food { public abstract void printName(); } ------------------------- public class AK47 extends Weapon{ public void shoot() { System.out.println("哒哒哒..."); } } ------------------------- public class Apple extends Food { public void printName() { System.out.println("apple"); } } ----------------------- public class Car extends Vehicle { public void run() { System.out.println("冒着烟奔跑中car......."); } } ----------------------- public class DefaultFactory extends AbstractFactory{ @Override public Food createFood() { return new Apple(); } @Override public Vehicle createVehicle() { return new Car(); } @Override public Weapon createWeapon() { return new AK47(); } } ------------------------------ public class MagicFactory extends AbstractFactory { @Override public Food createFood() { return new MushRoom(); } @Override public Vehicle createVehicle() { return new Broom(); } @Override public Weapon createWeapon() { return new MagicStick(); } }
这样当要替换这一系列的产品的时候,只需要更换具体的工厂就OK了。如下代码:
public class Test { public static void main(String[] args) { AbstractFactory f = new DefaultFactory(); Vehicle v = f.createVehicle(); v.run(); Weapon w = f.createWeapon(); w.shoot(); Food a = f.createFood(); a.printName(); } }
step6 -- Spring的IoC和AOP
Spring的IoC就是很专业的面向接口的编程。在她的配置文件里声明了接口的具体实现类。在这里就不细说她的工作原理了。
finally -- 最后就说一下,简单工厂和抽象工厂的区别,其实就是灵活度和方便度的不同,简单的灵活,但是抽象的方便。
马老师说的很经典:【现在学模式,使为了用,当遇到问题,怎么合理怎么来,管他什么模式。要练就的就是“先是看山是山,到看山不是山,再到看山又是山”,学模式一样,多动手敲代码比什么都强!!!】
与看到此文的你,共勉!!!