创建型模式 |
单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式 |
结构型横式 |
适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式 |
行为型模式 |
模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式 |
我们要明确的一点,我们设计模式的基础是面向对象编程(Object Oriented Programming,OOP),只要是提及设计模式,肯定都是基于面向对象编程的,所以我们的设计模式要以面向对象的基本原则为基础!!!接下来,我给大家列出关于面向对象的六大基本原则!
总原则:OCP(开闭原则, Open-Closed Principle) |
对扩展开放,对修改关闭。设计功能模块的时候,应当使这个模块在不被修改的前提下可以被扩展(功能) |
DIP(依赖倒转原则, Dependence Inversion Principle) |
依赖抽象不依赖具体,高层模块不应该依赖底层模块,两者应该依赖抽象,抽象不应该依赖细节(具体实现),细节依赖抽象(依赖接口) 提高可维护性 |
LOD(迪米特法则, Law of demeter) |
对象之间联系越少越好,对于对象的使用,方法调用,具体内部细节知道的越少越好(高内聚,低耦合) 可维护性强。(尽量少与其他类有关系,利于解耦) |
SRP(单一职责原则,Single responsibility principle) |
一个类或模块应该只做一件事(一个类或者模块对应一个功能类),高内聚,低耦合,专注于单一功能(高内聚) |
ISP(接口隔离原则,Interface Segregation Principle) |
一个接口最好只有一个方法(功能),让实现一个接口的类重写一种方法(功能)。针对不同功能应该有不同接口,使接口的功能有选择性,不强迫必须实现不需要的功能。 |
CRP(组合/聚合原则,Composite Reuse Principle) |
尽量使用对象组合,而不是继承对象达到功能复用的目的,一个新对象A能使用已有对象B达到功能复用(B对象的功能),就不要通过继承(B)对象来达到功能复用 |
LSP(里氏替换原则,Liskov Substitution Principle) |
对于父类出现的地方,都可以用子类代替(多态,继承) |
简单工厂模式 |
用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有代码) |
工厂方法模式 |
用来生产同一等级结构中的固定产品。(支持增加任意产品) |
抽象工厂模式 |
用来生产不同产品族的全部产品。(对于增加新的产品,无能为力,支持增加产品族) |
首先我,定义了一个Instrument 接口(乐器)
package 二_工厂模式;
public interface Instrument {
void sing();
}
然后定义了两个类Guitar 和Piano 继承Instrument 接口
package 二_工厂模式;
public class Guitar implements Instrument {
@Override
public void sing() {
System.out.println("吉他~");
}
}
package 二_工厂模式;
public class Piano implements Instrument {
@Override
public void sing() {
System.out.println("钢琴~");
}
}
package 二_工厂模式;
public class noFactory {
public static void main(String[] args) {
Instrument i1 = new Guitar();
Instrument i2 = new Piano();
i1.sing();
i2.sing();
}
}
发现实例化出Guitar和Piano的两个对象要和Instrument接口以及这两个实现类都要打交道,有些臃肿,于是我们引入了工厂模式
在前面代码的基础上定义一个工厂类InstrumentFactory,其中的方法都定义为静态方法,直接通过类调用,其中创建对象有两种实现方式,在一下代码中给出!!
package 二_工厂模式;
public class InstrumentFactory {
public static Guitar creatGuitar() {
return new Guitar();
}
public static Piano creatPiano() {
return new Piano();
}
//或者这样实现
public static Instrument creatInstrument(String type) {
Instrument i = null;
if ("吉他".equals(type))
i = new Guitar();
else if ("钢琴".equals(type))
i = new Piano();
return i;
}
}
然后我们进行实例化只用和工厂打交道
package 二_工厂模式;
public class simpleFactory {
public static void main(String[] args) {
InstrumentFactory.creatGuitar().sing();
InstrumentFactory.creatPiano().sing();
//或者这样实现
InstrumentFactory.creatInstrument("吉他").sing();
InstrumentFactory.creatInstrument("钢琴").sing();
}
}
相比没有工厂的情况下,我们减少了在主函数里创建一个对象需要接触的类或者接口,实现了创建者和调用者的分离,实例化对象,用工厂方法代替new操作!!!
但是要增加新的类,比如"贝斯"类,必须修改工厂里已有的代码!!这是简单工厂模式的一个弊端!!
同样在最前面的代码基础上增加一个工厂接口creatFactory
package 二_工厂模式;
public interface creatFactory {
Instrument creat();
}
然后再增加两个具体的工厂实现类GuitarCreat和PianoCreat继承creatFactory接口
package 二_工厂模式;
public class GuitarCreat implements creatFactory {
@Override
public Instrument creat() {
return new Guitar();
}
}
package 二_工厂模式;
public class PianoCreat implements creatFactory {
@Override
public Instrument creat() {
return new Piano();
}
}
package 二_工厂模式;
public class FunctionFactory {
public static void main(String[] args) {
new GuitarCreat().creat().sing();
new PianoCreat().creat().sing();
}
}
相比简单工厂法,如果要增加新的类,比如"贝斯"类,不用修改工厂里已有的代码,直接多加一个新的贝斯工厂实现工厂接口即可!!这是工厂方法模式的一个好处!!!
首先我们明白什么是产品族,接下来我会以实现一个汽车工厂为例
我们把汽车拆分为Engine(发动机)、Seat(座位)、Tyre(轮胎)三部分
分别创建这三个接口~~
汽车就是一种产品,我们将汽车这个产品分为两个产品族:
package 二_工厂模式_抽象工厂模式;
//发动机 public interface Engine { void noice();//噪音 void price();//价格 }
class LowEngine implements Engine { @Override public void noice() { System.out.println("噪音很大"); }
@Override public void price() { System.out.println("价格便宜"); } }
class LuxuryEngine implements Engine { @Override public void noice() { System.out.println("噪音很小"); }
@Override public void price() { System.out.println("价格昂贵"); } } |
|
package 二_工厂模式_抽象工厂模式;
//座位 public interface Seat { void comfortable();//舒适程度 void functionality();//功能性 }
class LowSeat implements Seat { @Override public void comfortable() { System.out.println("不舒服"); }
@Override public void functionality() { System.out.println("功能性很差"); } }
class LuxurySeat implements Seat { @Override public void comfortable() { System.out.println("很舒适"); }
@Override public void functionality() { System.out.println("功能性很强大"); } } |
|
package 二_工厂模式_抽象工厂模式;
//轮胎 public interface Tyre { void durability();//耐用性 void security();//安全性 }
class LowTyre implements Tyre { @Override public void durability() { System.out.println("耐用性很差"); }
@Override public void security() { System.out.println("安全性很差"); } }
class LuxuryTyre implements Tyre { public void durability() { System.out.println("耐用性很好"); }
@Override public void security() { System.out.println("安全性很好"); } } |
接下来,我们创建一个汽车工厂的接口CarFactory,并且为旗下的两个产品族分别创建工厂LowFactory、LuxuryFactory、实现以上接口,用来创建Engine(发动机)、Seat(座位)、Tyre(轮胎)
package 二_工厂模式_抽象工厂模式;
public interface CarFactory {
Engine createEngine();
Seat createSeat();
Tyre createTyre();
}
class LowFactory implements CarFactory {
@Override
public Engine createEngine() {
return new LowEngine();
}
@Override
public Seat createSeat() {
return new LowSeat();
}
@Override
public Tyre createTyre() {
return new LowTyre();
}
}
class LuxuryFactory implements CarFactory {
@Override
public Engine createEngine() {
return new LuxuryEngine();
}
@Override
public Seat createSeat() {
return new LuxurySeat();
}
@Override
public Tyre createTyre() {
return new LuxuryTyre();
}
}
最后,我们在一个主方法里测试,通过两个产品族的工厂直接分别创建两个产品族汽车的轮子,座椅和发动机
package 二_工厂模式_抽象工厂模式;
public class client {
public static void main(String[] args) {
//高端汽车产品族
CarFactory factory1 = new LuxuryFactory();
factory1.createEngine().noice();
factory1.createEngine().price();
factory1.createSeat().comfortable();
factory1.createSeat().functionality();
factory1.createTyre().durability();
factory1.createTyre().security();
//低端汽车产品族
CarFactory factory2 = new LowFactory();
factory2.createEngine().noice();
factory2.createEngine().price();
factory2.createSeat().comfortable();
factory2.createSeat().functionality();
factory2.createTyre().durability();
factory2.createTyre().security();
}
}
根据结果,我们已经创建成功,这就是关于抽象工厂模式的一个实例!!!