设计模式

文章目录

1 工厂模式

【实验内容和要求】
  有一个OEM制造商代理做HP笔记本电脑(Laptop),后来该制造商得到了更多的品牌笔记本电脑的订单Acer,Lenovo,Dell,该OEM商发现,如果一次同时做很多个牌子的本本,有些不利于管理。利用工厂模式改善设计,用JAVA语言实现 (或C#控制台应用程序实现)该OEM制造商的工厂模式。绘制该模式的UML图。
【模式UML图】
《设计模式》
【模式代码(JAVA语言实现)】
《设计模式》

public class FactoryMethod { 
	public static void main(String[] args) { 
		Computer c = null;
		Factory f = null;
		f = new DellFactory();
		c = f.getComputerType();
		c.ComputerType();
		f = new LenovoFactory();
		c = f.getComputerType();
		c.ComputerType();
		f = new AcerFactory();
		c = f.getComputerType();
		c.ComputerType();
	}
}
 
interface Factory{ 
	Computer getComputerType();
}
 
class DellFactory implements Factory{ 
 
	@Override
	public Computer getComputerType() { 
		return new Dell();
	}
}
 
class AcerFactory implements Factory{ 
 
	@Override
	public Computer getComputerType() { 
		return new Acer();
	}
}
 
class LenovoFactory implements Factory{ 
 
	@Override
	public Computer getComputerType() { 
		return new Lenovo();
	}
}
 
interface Computer{ 
	public void ComputerType();
}
 
class Dell implements Computer{ 
 
	@Override
	public void ComputerType() { 
		System.out.println("Dell Computer");
		
	}
	
}
 
class Acer implements Computer{ 
 
	@Override
	public void ComputerType() { 
		System.out.println("Acer Computer");
		
	}
	
}
 
class Lenovo implements Computer{ 
 
	@Override
	public void ComputerType() { 
		System.out.println("Lenovo Computer");
		
	}
	
}

【运行截图】
《设计模式》

四、心得体会:

通过本次实验,学会了使用工厂方法模式。工厂方法模式的适用性如下:
当一个类不知道它所必须创建的对象的类时。
当一个类希望由他的子类来指定它所创建的对象时。
当类创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类时代理这一信息局部化时。

2 抽象工厂模式

【实验内容和要求】
麦当劳(McDonalds)和肯德基(KFC)快餐店都经营汉堡(Hamburg)和可乐(Cole),用JAVA语言实现(C#控制台应用程序实现)这两个快餐店经营产品的抽象工厂模式。绘制该模式的UML图。
【模式UML图】
《设计模式》

【模式代码】

AbstractFactoryTest
public class AbstractFactoryTest { 
    public static void main(String[] args) { 
        Hamburg hamburg;
        Cola cola;
        AbstractFactory abstractFactory = new MDLFactory();
        hamburg = abstractFactory.createHamburg();
        cola = abstractFactory.createCola();
        hamburg.getHamburg();
        cola.getCola();

        abstractFactory = new KFCFactory();
        hamburg = abstractFactory.createHamburg();
        cola = abstractFactory.createCola();
        hamburg.getHamburg();
        cola.getCola();
    }
}

public interface Hamburg { 
    void getHamburg();
}

public interface Cola { 
    void getCola();
}

public interface AbstractFactory { 
    Hamburg createHamburg();
    Cola  createCola();
}

public class MDLCola implements Cola { 
    @Override
    public void getCola() { 
        System.out.println("这是麦当劳的可乐");
    }
}

public class MDLFactory implements AbstractFactory{ 
    @Override
    public Hamburg createHamburg() { 
        return new MDLHamburg();
    }

    @Override
    public Cola createCola() { 
        return new MDLCola();
    }
}

public class MDLHamburg implements Hamburg { 

    @Override
    public void getHamburg() { 
        System.out.println("这是麦当劳的汉堡包");
    }
}

public class KFCFactory implements AbstractFactory{ 
    @Override
    public Hamburg createHamburg() { 
        return new KFCHamburg();
    }

    @Override
    public Cola createCola() { 
        return new KFCCola();
    }
}

public class KFCHamburg implements Hamburg { 
    @Override
    public void getHamburg() { 
        System.out.println("这是肯德基的汉堡包");
    }
}

public class KFCCola implements Cola { 
    @Override
    public void getCola() { 
        System.out.println("这是肯德基的可乐");
    }
}



【运行截图】
《设计模式》

【实验小结】
抽象工厂模式主要适用于以下情况:
一系列要独立于它的产品的创建、组合和表示时。、
一个系统要由多个产品系列中的一个来配置时。
当要强调一系列相关的产品对象的设计以便进行联合使用时。
当要提供一个产品类库,而只要显示它们的接口而不是实现时。

3 建造者模式

实例:KFC套餐
建造者模式可以用于描述KFC如何创建套餐:套餐是一个复杂对象,它一般包含主食(如汉堡、鸡肉卷等)和饮料(如果汁、可乐等)等组成部分,不同的套餐有不同的组成部分,而KFC的服务员可以根据顾客的要求,一步一步装配这些组成部分,构造一份完整的套餐,然后返回给顾客。利用建造者模式设计,用JAVA语言实现 (或C#控制台应用程序实现)。绘制该模式的UML图。
【模式UML图】
《设计模式》
【模式代码(JAVA语言实现)】
《设计模式》

//客户端
public class Client { 
    public static void main(String[] args) { 
        //动态确定套餐种类
        MealBuilder mb = (MealBuilder) XMLUtil.getBean();
        //服务员是指挥者
        KFCWaiter waiter = new KFCWaiter();
        //服务员准备套餐
        waiter.setMealBuilder(mb);
        //客户获得套餐
        Meal meal = waiter.construct();

        System.out.println("套餐组成:");
        System.out.println(meal.getFood()+" "+meal.getDrink());

    }
}

//抽象类
public abstract class MealBuilder { 
    protected Meal meal=new Meal();
    public abstract void buildFood();
    public abstract void buildDrink();
    public Meal getMeal(){ 
        return meal;
    }
}

public class Meal { 
    //food和Drink是部件
    private String food;
    private String drink;

    public String getFood() { 
        return food;
    }

    public void setFood(String food) { 
        this.food = food;
    }

    public String getDrink() { 
        return drink;
    }

    public void setDrink(String drink) { 
        this.drink = drink;
    }
}

public class KFCWaiter { 
    private MealBuilder mb;

    public void setMealBuilder(MealBuilder mb) { 
        this.mb = mb;
    }

    public Meal construct(){ 
        mb.buildFood();;
        mb.buildDrink();
        return mb.getMeal();
    }
}

public class SubMealBuilderA extends MealBuilder { 
    @Override
    public void buildFood() { 
        meal.setFood("一个鸡腿堡");
    }

    @Override
    public void buildDrink() { 
        meal.setDrink("一杯可乐");
    }
}

public class SubMealBuilderB extends MealBuilder{ 

    @Override
    public void buildFood() { 
        meal.setFood("一个鸡肉卷");
    }

    @Override
    public void buildDrink() { 
        meal.setDrink("一杯果汁");
    }
}
package softwaredesign.three;

import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
public class XMLUtil
{ 
	//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
	public static Object getBean()
	{ 
		try
		{ 
			//创建文档对象
			DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = dFactory.newDocumentBuilder();
			Document doc;
			//这里填自己的config.xml路径
			doc = builder.parse(new File("D:\\learningappDataSave\\JAVA\\src\\softwaredesign\\three\\config.xml"));

			//获取包含类名的文本节点
			NodeList nl = doc.getElementsByTagName("className");
			Node classNode=nl.item(0).getFirstChild();
			String cName=classNode.getNodeValue();

			//通过类名生成实例对象并将其返回
			Class c=Class.forName(cName);
			Object obj=c.newInstance();
			return obj;
		}
		catch(Exception e)
		{ 
			e.printStackTrace();
			return null;
		}
	}
}

<?xml version="1.0"?>
xml文件:
<config>
	<className>SubMealBuilderA</className> 错误写法
    <className>softwaredesign.three.SubMealBuilderA</className> 正确写法,全类名=包名+类名
</config>

【运行截图】
《设计模式》
《设计模式》
【实验小结】
通过本次实验,学会了使用建造者模式。建造者模式的适用性如下:
1.关注按照步骤创建一个复杂的对象
2.将所建造的产品最后一次性返回,而不是一点一点地返回

4 单例模式

【实验内容和要求】
在操作系统中,打印池(Print Spooler)是一个用于管理打印任务的应用程序,通过打印池用户可以删除、中止或者改变打印任务的优先级,在一个系统中只允许运行一个打印池对象,如果重复创建打印池则抛出异常。现使用单例模式来模拟实现打印池的设计。用JAVA语言实现(C#控制台应用程序实现)该模式。绘制该模式的UML图。
【模式UML图】
《设计模式》
【模式代码】



package softwaredesign.four;
import java.util.Scanner;

/** * @Author cyh * @Date 2021/6/18 18:12 */
public class PrintSpoolerMain { 
    private static Scanner sc;

    public static void main(String[] args) { 
        System.out.println("打印。。。");

        try { 
            System.out.println("选择操作:");
            System.out.println(" D ――Delete");   //删除任务
            System.out.println(" S ――Suspension");  //中止任务
            System.out.println(" C ――Change priorities");   //改变任务优先级
            System.out.println(" E ――Exit");  //退出

            sc = new Scanner(System.in);
            while (true) { 
                switch (sc.next()) { 
                    case "D":
                        PrintSpoolerSingleton DeletePrint = PrintSpoolerSingleton.getInstance("Delete");
                        DeletePrint.manageJobs();
                        break;
                    case "S":
                        PrintSpoolerSingleton SuspensionPrint = PrintSpoolerSingleton.getInstance("Suspension");
                        SuspensionPrint.manageJobs();
                        break;
                    case "C":
                        PrintSpoolerSingleton ChangePrioritiesPrint = PrintSpoolerSingleton.getInstance("Change priorities");
                        ChangePrioritiesPrint.manageJobs();
                        break;
                    case "E":
                        System.exit(1);
                        break;
                    default:
                        break;
                }
            }
        } catch (Exception e) { 

        }
    }
}

package softwaredesign.four;

/** * @Author cyh * @Date 2021/6/18 18:06 */
public class PrintSpoolerSingleton { 
    private static PrintSpoolerSingleton instance;
    private String name;

    private PrintSpoolerSingleton(String name) { 
        this.name = name;
    }

    public static PrintSpoolerSingleton getInstance(String name) { 
        if (instance == null && !name.equals(null)) { 
            instance = new PrintSpoolerSingleton(name);
        }
        return instance;
    }

    public void manageJobs() { 
        System.out.println(name+"...");
    }
}

package softwaredesign.four;

/** * @Author cyh * @Date 2021/6/18 18:24 */
public class PrintSpoolerException { 
    public PrintSpoolerException(String message){ 
        System.out.println(message);
    }
}


【运行截图】
《设计模式》
四、心得体会:

要求生产唯一序列号。

WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。

创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。

当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

5 组合模式

【实验内容和要求】

文件浏览

文件有不同类型,不同类型的文件其浏览方式有所区别,如文本文件和图片文件的浏览方式就不相同。对文件夹的浏览实际上就是对其中所包含文件的浏览,而客户端可以一致地对文件和文件夹进行操作,无须关心它们的区别。使用组合模式来模拟文件的浏览操作。利用组合者模式设计,用JAVA语言实现 (或C#控制台应用程序实现)。绘制该模式的UML图。

【模式UML图】《设计模式》

【模式代码(JAVA语言实现)】

public abstract class AbstractFile { 

    public abstract void add(AbstractFile element);

    public abstract void remove(AbstractFile element);

    public abstract void display();

}

public class Folder extends AbstractFile{ 
    private String fileName;
    private ArrayList fileList = new ArrayList();

    public Folder(String fileName) { 
        this.fileName = fileName;
    }

    @Override
    public void add(AbstractFile element) { 
        fileList.add(element);
        System.out.println("Folder:add");
    }

    @Override
    public void remove(AbstractFile element) { 
        fileList.remove(element);
        System.out.println("Folder:remove");
    }

    @Override
    public void display() { 
        for (Object object : fileList) { 
            ((AbstractFile)object).display();
        }
        System.out.println("Folder:display");
    }
}

public class ImageFile extends AbstractFile{ 
    private String fileName;

    public ImageFile(String fileName) { 
        this.fileName = fileName;
    }

    @Override
    public void add(AbstractFile element) { 
        System.out.println("ImageFile:add");
    }

    @Override
    public void remove(AbstractFile element) { 
        System.out.println("ImageFile:remove");
    }

    @Override
    public void display() { 
        System.out.println(fileName);
        System.out.println("ImageFile:display");
    }
}

public class TextFile extends AbstractFile{ 
    private String fileName;

    public TextFile(String fileName) { 
        this.fileName = fileName;
    }

    @Override
    public void add(AbstractFile element) { 
        System.out.println("TextFile:add");
    }

    @Override
    public void remove(AbstractFile element) { 
        System.out.println("TextFile:remove");
    }

    @Override
    public void display() { 
        System.out.println(fileName);
        System.out.println("TextFile:display");
    }
}

public class VideoFile extends AbstractFile{ 
    private String fileName;

    public VideoFile(String fileName) { 
        this.fileName = fileName;
    }

    @Override
    public void add(AbstractFile element) { 
        System.out.println("VideoFile:add");
    }

    @Override
    public void remove(AbstractFile element) { 
        System.out.println("VideoFile:remove");
    }

    @Override
    public void display() { 
        System.out.println(fileName);
        System.out.println("VideoFile:display");
    }
}

public class Client { 
    public static void main(String[] args) { 
        //定义抽象类
        AbstractFile obj1,obj2,obj3,obj4,obj5;
        //定义几个文件夹
        Folder plate1,plate2,plate3;

        //建文件
        obj1 = new ImageFile("iii");
        obj2 = new TextFile("ttt");
        obj3 = new VideoFile("vvv1");
        obj4 = new VideoFile("vvv2");
        obj5 = new VideoFile("vvv3");
        //建文件夹
        plate1 = new Folder("fff1");
        plate2 = new Folder("fff2");
        plate3 = new Folder("fff3");


        //将文件加入文件夹1
        plate1.add(obj1);
        plate1.add(obj2);

        //将文件3,4加入问价夹2
        plate2.add(obj3);
        plate2.add(obj4);

        //将文件夹1以及文件夹2和文件5加入文件夹3
        plate3.add(plate1);
        plate3.add(plate2);
        plate3.add(obj5);

        plate3.display();
    }
}

【运行截图】
《设计模式》

心得体会:

组合模式的适用性如下:

(1)在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们。
(2)在一个使用面向对象语言开发的系统中需要处理一个树形结构。
(3)在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。

6 适配器模式

【实验内容和要求】

加密适配器

某系统需要提供一个加密模块,将用户信息(如密码等机密信息)加密之后再存储在数据库中,系统已经定义好了数据库操作类。为了提高开发效率,现需要重用已有的加密算法,这些算法封装在一些由第三方提供的类中,有些甚至没有源代码。使用适配器模式设计该加密模块,实现在不修改现有类的基础上重用第三方加密方法。

现使用适配器模式来模拟实现打印池的设计。用JAVA语言实现(C#控制台应用程序实现)该模式。绘制该模式的UML图。

【模式UML图】
《设计模式》
【模式代码(JAVA语言实现)】

public abstract class DataOperation { 
    public abstract String doEncrypt(String ps);
}
public class Caesar { 
    public String doEncrypt(String ps){ 
        return "原来的加密方法加密后的密码为:"+ps;
    }
}
public class NewCaesar { 
    public String doEncrypt(String ps){ 
        ps="new"+ps;
        return "新方法加密后的密码为:"+ps;
    }
}

public class CipherAdapter extends DataOperation{ 
    private Caesar cipher;

    public CipherAdapter() { 
        cipher=new Caesar();
    }

    @Override
    public String doEncrypt(String ps) { 
        return cipher.doEncrypt(ps);
    }
}

public class NewCipherAdapter extends DataOperation{ 
    private NewCaesar newCipher;

    public NewCipherAdapter() { 
        newCipher=new NewCaesar();
    }

    @Override
    public String doEncrypt(String ps) { 
        return newCipher.doEncrypt(ps);
    }
}


public class Client { 
    public static void main(String[] args) { 
        String s1 = "123456";
        String s2 = "";

        DataOperation data = null;

        data=new CipherAdapter();
        s2 = data.doEncrypt(s1);
        System.out.println(s2);

        data = new NewCipherAdapter();
        s2 = data.doEncrypt(s1);
        System.out.println(s2);
    }
}

【运行截图】《设计模式》
《设计模式》
四、心得体会:

适配器模式主要适用于以下情况:
1)统需要使用一些现有的类,而这些类的接口(如方法名)不符合系统的需要,甚至没有这些类的源代码。
2)创建一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。

    原文作者:我永远信仰
    原文地址: https://blog.csdn.net/qq_44769557/article/details/118030697
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞