面对对象设计的原则
1.OCP (开闭原则 open-close principle) 一个软件类的实体 应该对扩展开放对修改关闭
2.DIP(依赖反转原则 Dependence Inversion principle) :要针对接口编程 不要针对实现编程 通俗来讲 就是依赖于接口而不是类调用之间之间调用.
3.LoD(迪米特法则,Law of Demeter):只与你直接的朋友通信,而避免和陌生人通信. 就是这个本身这个类.尽量少于别的类有关系
工厂模式
1.实现了调用者和创建者的分离
2.它的详细分类
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
简单工厂模式
如果只是继承的话.调用者调用父类.也要调用子类
接口 /** * @Created by xiaodao */ public interface Car { void run(); } 实现类: public class Byd implements Car { @Override public void run() { System.out.println("比亚迪....."); } } 实现类: public class Audi implements Car{ @Override public void run() { System.out.println("奥迪...在跑..."); } } 调用者: /** * @Created by xiaodao * 没有工厂模式的情况下. */ public abstract class Client01 extends Audi implements Car {//调用者.. public static void main(String[] args) { Car car1 = new Audi(); Car car2 = new Byd(); car1.run(); car2.run(); } }
现在我们用单间工厂模式来实现一下..
public class CarFactory { /** * 违反开闭原则..这里也可以直接new autiCar() * @param type * @return */ public static Car createCar(String type){ if("audi".equals(type)){ return new Audi(); }else if ("byd".equals(type)){ return new Byd(); } return null; } }
关于这里的判断 我们可以在做一个枚举类.或者配置一个字典项之类的实现.
调用者
/** * @Created by xiaodao * 简单工厂模式 */ public class Client02 {//调用者.. public static void main(String[] args) { Car car1 = CarFactory.createCar("audi"); Car car2 = CarFactory.createCar("byd"); car1.run(); car2.run(); } }
这样类图虽然看起来复杂了.但是如果我们需要多加一个汽车的话.就在CarFactory里直接添加一个.就可以了.然后我们就可以调用了.哈哈,那么他是不是如名字那样一样简单
工厂方法模式
工厂方法虽然符合ocp原则,但是也有它的弊端.就是创建的工厂方法会很多,实际项目中用的看情况而定
工厂方式模式与简单工厂模式最大的不同在于 ,简单工厂模式只有一个(对于一个项目或者一个独立的模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类
具体接口: public interface Car { void run(); } 接口的实现类: public class Byd implements Car { @Override public void run() { System.out.println("比亚迪....."); } } 接口的实现类: public class Audi implements Car { @Override public void run() { System.out.println("奥迪...在跑..."); } } 工厂的接口: public interface CarFactory { Car getCar(); } 工厂接口的实现: public class AudiFactory implements CarFactory{ @Override public Car getCar() { return new Audi(); } } 工厂接口的实现类: public class BydFactory implements CarFactory { @Override public Car getCar() { return new Byd(); } } 调用者的话,只需要关心使用哪个工厂实现类,而产生的.实例就可以了. public class Client { public static void main(String[] args) { Car caraudi = new AudiFactory().getCar(); Car bydCar = new BydFactory().getCar(); caraudi.run(); bydCar.run(); } }
这个就是工厂方法模式.它和静态工厂类的区别就是他遵守了OCP原则如果我们需要增加一个实现类的话.我们只需要在创建一个carFactory的实现类以及一个实现了Car的实例就好了.这样我们调用者只需要关心.CarFactory的实现类就好了
但是这种方法如果实例多的话不好维护.
从管理角度来说.也是各有优缺点.简单工厂模式就需要维护一个类...工厂方法模式.扩展性也非常的好.
主要角色
carFactory 工厂接口
audiFactory 工厂实现来获取audi的实例
Car 接口 用来定义实例的属性
audi等 具体实例的实现
这样client 只需要用工厂实现来获取想要的实例而不需要直接和car audi等直接进行交互.具体的维护交给工厂 客户端只需要调用就可以
抽象工厂abstract factory模式
抽象工厂方法是用来生成不同产品族的全部产品(对于新增加的产品.很难) 抽象工厂方法主要是用来针对产品族 就是有很多产品,而不是一个产品,和简单工厂模式,根本上就不同,
我们来举个例子,如果是前面的简单工厂方法,是针对一个汽车工厂 他可以生产很多汽车,比较单一的实现 那么抽象工厂方法就是我可以生成不同的配件(不同的工厂) 来组合成一辆汽车 需要不同的产品最终组合一个产品族
在企业开发中一般使用的情况很少,因为这将是一个大的工程.
我们先来看下类的调用关
类的结构.我这里都写在一个包下了.不够清晰:
这里先说一下各自的角色
tyreFactory 轮胎工厂生产不同的轮胎
seatFactory 座椅工厂
engineFactory 引擎工厂
他们的子类就是不同的实例 生产出不同的产品
CarAbstractFactory 抽象工厂接口 他可以生产轮胎.座椅 引擎
luxuryFactoryImpl 奢侈汽车工厂 可以接受不同厂家的生产的配件
lowFactoryImpl 低端汽车工厂 也是接受各种厂家的配件
具体生成汽车的地方可以自由的组合 这样大家是不是有点对抽象工厂了解不少?
下面我们来上代码
/** * @Created by xiaodao * 座椅工厂 */ public interface SeatFactory { void useSeat(); } /** * @Created by xiaodao * 轮胎工厂 */ public interface TyreFactory { void useTyre(); } /** * @Created by xiaodao */ public interface EngineFactory { void useEngine(); } /** * @Created by xiaodao * 奢侈引擎 */ public class LuxuryEngineFactoryImpl implements EngineFactory { @Override public void useEngine() { System.out.println("使用的时候奢侈引擎"); } } public class LuxurySeatFactoryImpl implements SeatFactory { @Override public void useSeat() { System.out.println("使用的高级座椅"); } } public class LuxuryTyreFactoryImpl implements TyreFactory { @Override public void useTyre() { System.out.println("使用奢侈轮胎"); } } public class LowEngineFactoryImpl implements EngineFactory { @Override public void useEngine() { System.out.println("使用的是低级引擎."); } } public class LowSeatFactoryImpl implements SeatFactory { @Override public void useSeat() { System.out.println("低级座椅"); } } public class LowTyreFactoryImpl implements TyreFactory { @Override public void useTyre() { System.out.println("使用低级轮胎接口"); } } //抽象接口工厂 public interface CarAbstractFactory { /** * 座椅工厂 * @return */ public SeatFactory createSeat(); public EngineFactory createEngine(); public TyreFactory createTyre(); } public class LowCarFactory implements CarAbstractFactory { @Override public SeatFactory createSeat() { return new LowSeatFactoryImpl(); } @Override public EngineFactory createEngine() { return new LowEngineFactoryImpl(); } @Override public TyreFactory createTyre() { return new LowTyreFactoryImpl(); } } public class LuxuryCarFactory implements CarAbstractFactory{ @Override public SeatFactory createSeat() { return new LuxurySeatFactoryImpl(); } @Override public EngineFactory createEngine() { return new LuxuryEngineFactoryImpl(); } @Override public TyreFactory createTyre() { return new LuxuryTyreFactoryImpl(); } } 调用 public class Client { public static void main(String[] args) throws IllegalAccessException, InstantiationException { CarAbstractFactory luxurycar = LuxuryCarFactory.class.newInstance(); luxurycar.createEngine().useEngine(); luxurycar.createSeat().useSeat(); luxurycar.createTyre().useTyre(); CarAbstractFactory lowcar = LowCarFactory.class.newInstance(); lowcar.createEngine().useEngine(); lowcar.createSeat().useSeat(); lowcar.createTyre().useTyre(); } } 结果 使用的时候奢侈引擎 使用的高级座椅 使用奢侈轮胎 使用的是低级引擎. 低级座椅 使用低级轮胎接口
我们通过以上代码接口来扩展 对象的创建方式
1. LuxuryCarFactory.class.newInstance()
2.对象的clone()方法
市面上有很多抽象接口的实现方式.写的代码都其实思想都是大同小异,我们主要是理解它思想.
来源:https://www.cnblogs.com/bj-xiaodao/p/10821230.html