Java23种设计模式详解二

Java23种设计模式详解(二)

一.工厂方法模式(FactoryMethod Pattern)

1、普通工厂方法模式

就是建立一个工厂类,对实现了同一界面的一些类进行例项的建立。

举例:手机发简讯或微信。

手机:

public interface Phone {

public void send();

}

老年机:

public class oldMachine implements Phone{

@Override

public void send() {

//老年机只能发简讯

System.out.println(发简讯);

}

}

智慧机:

public class smartPhone implements Phone {

@Override

public void send() {

//智慧机可以发微信

System.out.println(发微信);

}

}

工厂:

public class Factory {

public Phone send(String type){

if(oldMachine.equals(type)){

return new oldMachine();

}else if(smartPhone.equals(type)){

return new smartPhone();

}

return null;

}

}

测试:

public class Test {

public static void main(String[] args){

Factory factory=new Factory();

Phone phone=factory.send(oldMachine);

phone.send();

}

}

结果:

2、多个工厂方法模式

是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字串出错,则不能正确建立物件,而多个工厂方法模式是提供多个工厂方法,分别建立物件。

工厂:

public class Factory {

public Phone sendMail(){

return new oldMachine();

}

public Phone sendWechat(){

return new smartPhone();

}

}

测试:

public class Test {

public static void main(String[] args){

Factory factory=new Factory();

Phone phone=factory.sendMail();

phone.send();

}

}

结果:

3、静态工厂方法模式

将上面的多个工厂方法模式里的方法置为静态的,不需要建立例项,直接呼叫即可。

工厂:

public class Factory {

public static Phone sendMail(){

return new oldMachine();

}

public static Phone sendWechat(){

return new smartPhone();

}

}

测试:

public class Test {

public static void main(String[] args){

Phone phone=Factory.sendMail();

phone.send();

}

}

结果:

二.抽象工厂方法模式(Abstract Factory)

工厂方法模式有一个问题就是,类的建立依赖工厂类,也就是说,如果想要拓展程式,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,建立多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的程式码。

手机界面:

public interface Phone {

public void send();

}

老年机:

public class oldMachine implements Phone{

@Override

public void send() {

//老年机只能发简讯

System.out.println(发简讯);

}

}

智慧机:

public class smartPhone implements Phone {

@Override

public void send() {

//智慧机可以发微信

System.out.println(发微信);

}

}

工厂界面:

public interface Send {

public Phone send();

}

老年机工厂:

public class oldMachineFactory implements Send {

@Override

public Phone send() {

return new oldMachine();

}

}

智慧机工厂:

public class smartPhoneFactory implements Send {

@Override

public Phone send() {

return new smartPhone();

}

}

测试:

public class Test {

public static void main(String[] args){

Send send= new smartPhoneFactory();

Phone phone=send.send();

phone.send();

}

}

结果:

其实这个模式的好处就是,如果你现在想增加一个功能:发及时资讯,则只需做一个实现类,实现Phone界面,同时做一个工厂类,实现Send界面,就OK了,无需去改动现成的程式码。这样做,拓展性较好!

三.门面模式(Facade Pattern)

比如说做饭,你得先买菜,然后洗菜,烹饪,吃;这几个过程顺序不能乱吧,而且缺一不可吧。你想想你上了一天班回来还得这么累,麻烦?麻烦!怎么解决?下馆子呗,告诉厨师你的需求,让他去干,你只需要吃就行。

做饭的过程:

//做饭的过程

public interface Cook {

//买菜(买哪些菜)

public void buyVegetables(String vegetables);

//洗菜

public void washVegetables();

//烹饪(什么口味)

public void cookVegetables(String flavour);

//吃

public void eat();

}

做饭的实现类:

//做饭的具体实现

public class cookImpl implements Cook{

@Override

public void buyVegetables(String vegetables) {

System.out.println(买菜。。。。);

}

@Override

public void washVegetables() {

System.out.println(洗菜。。。。);

}

@Override

public void cookVegetables(String flavour) {

System.out.println(烹饪。。。。);

}

@Override

public void eat() {

System.out.println(吃。。。。);

}

}

餐馆:

public class Restaurant {

private Cook cook=new cookImpl();

public void cook(String vegetables,String flavour){

cook.buyVegetables(vegetables);

cook.washVegetables();

cook.cookVegetables(flavour);

cook.eat();

}

}

你去下馆子:

public class Client {

public static void main(String[] args){

Restaurant rs=new Restaurant();

//想吃鱼

String vegetables=fish;

//酸辣味

String flavour=sour and hot;

rs.cook(vegetables,flavour);

}

}

结果:

如果厨师做饭的过程中,卫生局来检查了,刚好抽中了你这盘菜呢?

卫生局:

public class healthDepartment {

public void check(Cook cook){};

}

修改餐厅类:

public class Restaurant {

private Cook cook=new cookImpl();

private healthDepartment hd=new healthDepartment();

public void cook(String vegetables,String flavour){

cook.buyVegetables(vegetables);

cook.washVegetables();

cook.cookVegetables(flavour);

hd.check(cook);

cook.eat();

}

}

结果:

食材健康?健康,但是你看不到检查这个过程。

什么时候用呢?开发过程中,遇到水平比较渣的程序员,尽量安排他负责独立模组,然后封装成一个门面模式,让其他团队成员不至于看到这些烂程式码糟心。

四.界面卡模式(Adapter Pattern)

界面卡模式将某个类的界面转换成客户端期望的另一个界面表示,目的是消除由于界面不匹配所造成的类的相容性问题。主要分为三类:类的界面卡模式、物件的界面卡模式、界面的界面卡模式。

类的界面卡模式:

Source类:

public class Source {

public void method1(){

System.out.println(Source的method方法);

}

}

Target界面:

public interface Target {

//source类的方法

public void method1();

//新的方法

public void method2();

}

界面卡:

public class Adapter extends Source implements Target {

@Override

public void method2() {

System.out.println(Target的method方法);

}

}

测试:

public class Test {

public static void main(String[] args){

Target target=new Adapter();

target.method1();

target.method2();

}

}

结果:

这样Target界面的实现类就具有了Source类的功能。

物件的界面卡模式:

基本思路和类的界面卡模式相同,只是将Adapter类作修改,这次不继承Source类,而是持有Source类的例项,以达到解决相容性的问题。

修改Adapter类:

public class Adapter implements Target {

private Source source;

public Adapter(Source source) {

this.source = source;

}

@Override

public void method1() {

}

@Override

public void method2() {

System.out.println(Target的method方法);

}

}

测试:

public class Test {

public static void main(String[] args){

Source source=new Source();

Target target=new Adapter(source);

target.method1();

target.method2();

}

}

结果:

界面的界面卡模式:

有时我们一个界面中有多个抽象方法,当我们写该界面的实现类时,必须实现该界面的所有方法,这明显有时比较浪费,因为并不是所有的方法都是我们需要的,有时只需要某一些,此处为了解决这个问题,我们引入了界面的界面卡模式,借助于一个抽象类,该抽象类实现了该界面,实现了所有的方法,而我们不和原始的界面打交道,只和该抽象类取得联络,所以我们写一个类,继承该抽象类,重写我们需要的方法就行。

界面:

public interface Target {

//source类的方法

public void method1();

//新的方法

public void method2();

}

抽象类:

public abstract class Wraaper implements Target {

@Override

public void method1() {

}

@Override

public void method2() {

}

}

S1:

public class S1 extends Wraaper {

@Override

public void method1() {

System.out.println(S1);

}

}

S2:

public class S2 extends Wraaper {

@Override

public void method2() {

System.out.println(S2);

}

}

测试:

public class Test {

public static void main(String[] args){

S1 ss=new S1();

S2 sm=new S2();

ss.method1();

ss.method2();

sm.method1();

sm.method2();

}

}

结果:

关注微信公众号“Java大联盟”,关注即可获取海量学习干货,同时还有不定期送书,键盘,鼠标等粉丝福利。

赶快来关注一波,海量资源拿到手软。

猜你喜欢