zoukankan      html  css  js  c++  java
  • 设计模式第一次作业

    设计模式第一次作业

    1、要求:某系统日志记录器要求支持多种日志记录方式,如文件记录、数据库记录等;用户可以根据要求动态选择日志记录方式。使用Factory模式来设计;如果系统中增加一个日志记录方式—控制台日志记录(ConsoleLog),类图将如何改变?

    类图如下:

    代码:

    abstract class factory{//工厂的抽象类
    	public abstract Log recordLogs();
    }
    
    class TextLogFactory extends factory{//文字日志工厂类
    
    	public Log recordLogs() {
    		// TODO Auto-generated method stub
    		return new TextLog();
    	}
    	
    }
    
    class DBLogFactory extends factory{//数据库日志工厂类
    
    	public Log recordLogs() {
    		// TODO Auto-generated method stub
    		return new DBLog();
    	}
    	
    }
    
    abstract class Log{//日志生成器抽象类
    	public abstract void WriteLogs();
    }
    
    class TextLog extends Log{//文字日志生成器
    
    	public void WriteLogs() {
    		// TODO Auto-generated method stub
    		System.out.println("textLog");
    	}
    	
    }
    
    class DBLog extends Log{//数据库日志生成器
    
    	public void WriteLogs() {
    		// TODO Auto-generated method stub
    		System.out.println("dbLog");
    	}
    	
    }
    
    //测试代码
    factory fa=new DBLogFactory();
    Log log = fa.recordLogs();
    log.WriteLogs();
    

    如果此时加入ConsoleLog,类图变为如下:

    2、要求:某系统为了改进数据库操作的性能,自定义数据连接对象Connection和语句对象Statement,可针对不同类型的数据库提供不同的连接对象和语句对象;用户可以通过配置文件等方式根据实际需要动态更换系统数据库;使用Abstract Factory模式来设计。

    类图如下:

    代码:

    abstract class Factory{//工厂抽象类
    	public abstract Statement setStatement();
    	public abstract Connection setConnection();
    }
    
    class AccessFactory extends Factory{//access数据库的工厂
    
    	public Statement setStatement() {
    		// TODO Auto-generated method stub
    		return new AccessStatement();
    	}
    
    	public Connection setConnection() {
    		// TODO Auto-generated method stub
    		return new AccessConnection();
    	}
    	
    }
    
    class SqlFactory extends Factory{//sql server数据库的工厂
    
    	public Statement setStatement() {
    		// TODO Auto-generated method stub
    		return new SqlStatement();
    	}
    
    	public Connection setConnection() {
    		// TODO Auto-generated method stub
    		return new SqlConnection();
    	}
    	
    }
    
    class Statement{
    	
    }
    
    class AccessStatement extends Statement{//access数据库的statement
    	
    	public AccessStatement() {//在这里假定在构造时即产生了statement
    		System.out.println("AccessStatement");
    	}
    	
    }
    
    class SqlStatement extends Statement{//sql server数据库的statement
    	
    	public SqlStatement() {//在这里假定在构造时已产生了statement
    		System.out.println("SqlStatement");
    	}
    	
    }
    
    class Connection{
    	
    	
    }
    
    class AccessConnection extends Connection{//access数据库的connection
    
    	public AccessConnection() {//在这里假定在构造时已产生了connection
    		System.out.println("AccessConnection");
    	}
    	
    }
    
    class SqlConnection extends Connection{//sql server数据库的connection
    	
    	public SqlConnection() {
    		System.out.println("SqlConnection");
    	}
    }
    
    //测试代码
    Factory fa=new SqlFactory();
    fa.setConnection();
    fa.setStatement();
    

    小结
    从这两题看出:

    • 使用工厂模式的情况下,数据与操作并未完全分离,如第一题的文字日志生成器与数据库日志生成器,他们虽然进行着不同的操作,但是他们的数据可以说是同一份或者说是来自同一个地方。
    • 工厂模式,形象的说,就是一个人面前有很多店,但是,一个店只能买到一个物品。比如,在米店只能买到米,在面店只能买到面。所以,在第一题中对应的是,在TextFactory中,返回TextLog对象,在DBLogFactory ,返回DBLog对象。
    • 使用抽象工厂模式的情况下,各个工厂的操作等均是完全分离的。如第二题的AccessFactory与SqlFactory,他们连接数据库所使用的statement与connection是完全不同的。
    • 抽象工厂模式,形象的说,就是一个人面前有很多超市,每个超市都可以大于一个的东西。比如AccessFactory里可以有AccessStatement和AccessConnection,在SqlFactory中可以有SqlStatement和SqlConnection。

    3、要求:KFC套餐是一个复杂对象,一般包括主食(如汉堡、鸡肉卷等)和饮料(如果汁、可乐等)组成部分,不同套餐有不同组成部分;KFC服务员要根据顾客要求,装配这些组成部分,构造一个完整套餐,返回给顾客;使用Builder模式来设计。

    类图如下:

    代码:

    abstract class FoodBuilder{//套餐builder  系统中真正的builder
    	FoodGetted foodGetted;
    	
    	public FoodBuilder() {
    		foodGetted=new FoodGetted();
    	}
    	public abstract void bulidFood();
    	public abstract void bulidDrink();
    	public FoodGetted getFood(){
    		
    		return foodGetted;
    	}
    }
    
    class PackageAFoodBuilder extends FoodBuilder{//套餐A的builder
    
    	public void bulidFood() {//套餐A的主食
    		// TODO Auto-generated method stub
    		foodGetted.setFood(" PackageA food-汉堡");
    	}
    
    	public void bulidDrink() {//套餐A的饮料
    		// TODO Auto-generated method stub
    		foodGetted.setDrink(" PackageA drink-可乐");
    	}
    	
    	
    }
    
    class PackageBFoodBuilder extends FoodBuilder{//套餐B的builder
    
    	public void bulidFood() {//套餐B的主食
    		// TODO Auto-generated method stub
    		foodGetted.setFood(" PackageA food-鸡肉卷");
    	}
    
    	public void bulidDrink() {//套餐B的饮料
    		// TODO Auto-generated method stub
    		foodGetted.setDrink(" PackageA drink-果汁");
    	}
    	
    }
    
    class Waiter{//服务员去调用建造命令
    	
    	
    	private FoodBuilder foodBuilder;
    	
    	public void setFoodBuilder(FoodBuilder foodBuilder) {
    		this.foodBuilder=foodBuilder;
    	}
    
    	public FoodGetted buildOrderedFood() {
    		// TODO Auto-generated method stub
    		foodBuilder.bulidFood();  
    		foodBuilder.bulidDrink();
    		return foodBuilder.getFood();
    	}
    }
    
    class Customer{//系统的点餐者  一定程度上也就充当了director  告知waiter该做什么
    	
    	private Waiter waiter;
    	public void  orderFoodA(Waiter w){
    		waiter=w;
    		waiter.setFoodBuilder(new  PackageAFoodBuilder());
    	}
    	public void orderFoodB(Waiter w){
    		waiter=w;
    		waiter.setFoodBuilder(new  PackageBFoodBuilder());
    	}
    	public void customerGetted(FoodGetted foodGetted){
    		System.out.println("customerGetted is "+foodGetted.getFood()+"  "+foodGetted.getDrink());
    	}
    }
    
    class FoodGetted{//通过调用最终得到的食物
    	private String drink;
    	private String food;
    	public String getDrink() {
    		return drink;
    	}
    	public void setDrink(String drink) {
    		this.drink = drink;
    	}
    	public String getFood() {
    		return food;
    	}
    	public void setFood(String food) {
    		this.food = food;
    	}
    	
    	
    }
    
    //测试代码
    //消费者进入 店内已有waiter  消费者点A套餐并告知waiter waiter去build点的餐  之后获取消费者得到的餐
    Customer c=new Customer();
    		
    Waiter waiter = new Waiter();
    c.orderFoodA(waiter);
    		
    c.customerGetted(waiter.buildOrderedFood());
    

    4、要求:游戏中的地图:包括天空、地面、背景;人物包括人体、服装、装备等组成部分,如采用Builder模式如何设计?

    类图如下:

    如果看不清,请点这里

    代码:

    class Map{  //对应的是最终生成的map的product
    	private String Sky;
    	private String Ground;
    	private String Background;
    	public String getSky() {
    		return Sky;
    	}
    	public void setSky(String sky) {
    		Sky = sky;
    	}
    	public String getGround() {
    		return Ground;
    	}
    	public void setGround(String ground) {
    		Ground = ground;
    	}
    	public String getBackground() {
    		return Background;
    	}
    	public void setBackground(String background) {
    		Background = background;
    	}
    	
    }
    
    
    abstract class MapBuilder{//map的builder  三个抽象方法 要求子类实现地图最基本的三个元素
    	//包括天空、地面、背景
    	Map map;
    	
    	public MapBuilder() {
    		map=new Map();
    	}
    	public abstract void buildSky();
    	public abstract void buildGround();
    	public abstract void buildBackground();
    	public Map getMap(){
    		return map;
    	}
    }
    
    class NormalMapBuilder extends MapBuilder{//正常map的builder 写三个具体的build方法来完成map的三个元素
    
    	public void buildSky() {
    		// TODO Auto-generated method stub
    		map.setSky("NormalMapBuilder Sky");
    	}
    
    	public void buildGround() {
    		// TODO Auto-generated method stub
    		map.setGround("NormalMapBuilder Ground");
    	}
    
    	public void buildBackground() {
    		// TODO Auto-generated method stub
    		map.setBackground("NormalMapBuilder Background");
    	}
    	
    }
    
    class AbnormalMapBuilder extends MapBuilder{//非正常map的builder 写三个具体的build方法来完成map的三个元素
    
    	public void buildSky() {
    		// TODO Auto-generated method stub
    		map.setSky("AbnormalMapBuilder Sky");
    	}
    
    	public void buildGround() {
    		// TODO Auto-generated method stub
    		map.setGround("AbnormalMapBuilder Ground");
    	}
    
    	public void buildBackground() {
    		// TODO Auto-generated method stub
    		map.setBackground("AbnormalMapBuilder Background");
    	}
    	
    }
    
    class People{//对听的是最终的people的product
    	private String Body;
    	private String Clothes;
    	private String Equipments;
    	public String getBody() {
    		return Body;
    	}
    	public void setBody(String body) {
    		Body = body;
    	}
    	public String getClothes() {
    		return Clothes;
    	}
    	public void setClothes(String clothes) {
    		Clothes = clothes;
    	}
    	public String getEquipments() {
    		return Equipments;
    	}
    	public void setEquipments(String equipments) {
    		Equipments = equipments;
    	}
    	
    
    abstract class PeopleBuilder{//三个抽象方法 对应人物的三个基本元素
    	//人物包括人体、服装、装备等组成部分
    	People people;
    	
    	public PeopleBuilder() {
    		people=new People();
    	}
    	public abstract void buildBody();
    	public abstract void buildClothes();
    	public abstract void buildEquipments();
    	public People getPeople(){
    		return people;
    	}
    }
    
    class LowLevelPeopleBuilder extends PeopleBuilder{//低等级的人物  具体实现三个方法
    
    	public void buildBody() {
    		// TODO Auto-generated method stub
    		people.setBody("LowLevelPeopleBuilder Body");
    	}
    
    	public void buildClothes() {
    		// TODO Auto-generated method stub
    		people.setClothes("LowLevelPeopleBuilder Clothes");
    	}
    
    	public void buildEquipments() {
    		// TODO Auto-generated method stub
    		people.setEquipments("LowLevelPeopleBuilder Eduipments");
    	}
    	
    }
    
    class HighLevelPeopleBuilder extends PeopleBuilder{//高等级的人物 具体实现的三个方法
    
    	public void buildBody() {
    		// TODO Auto-generated method stub
    		people.setBody("HighLevelPeopleBuilder Body");
    	}
    
    	public void buildClothes() {
    		// TODO Auto-generated method stub
    		people.setClothes("HighLevelPeopleBuilder Clothes");
    	}
    
    	public void buildEquipments() {
    		// TODO Auto-generated method stub
    		people.setEquipments("HighLevelPeopleBuilder Eduipments");
    	}
    	
    }
    
    class Creator{ //建造者 调用真正的建造者
    	private MapBuilder mm;
    	private PeopleBuilder peopleBuilder;
    	public Creator(MapBuilder m,PeopleBuilder p) {
    		mm=m;
    		peopleBuilder=p;
    	}
    	public Map creatMapBuilder() {
    		mm.buildSky();
    		mm.buildGround();
    		mm.buildBackground();
    		return mm.getMap();
    	}
    	public People creatPeopleBuilder() {
    		peopleBuilder.buildBody();
    		peopleBuilder.buildClothes();
    		peopleBuilder.buildEquipments();
    		return peopleBuilder.getPeople();
    	}
    	
    	public void GameGetted(Map map,People people){//使用creator生成的类来测验得到的game地图
    		System.out.println("The sky in game is "+map.getSky()+
    				",the ground in game is "+map.getGround()+
    				",the background in game is "+map.getBackground());
    		System.out.println("The body in game is "+people.getBody()+
    				",the clothes in game is "+people.getClothes()+
    				",the equipments in game is "+people.getEquipments());
    	}
    	
    }
    
    
    //测试代码
    //前两行充当一个director的角色
    MapBuilder m=new NormalMapBuilder();
    		
    PeopleBuilder p=new HighLevelPeopleBuilder();
    
    //得到传过来的map与people	
    Creator creator=new Creator(m,p);
    
    //进行构造  并将构造好的map与people的信息进行返回
    creator.GameGetted(creator.creatMapBuilder(), creator.creatPeopleBuilder());
    	
    

    小结
    从这两题看出:

    • 建造者模式,如同名字,就是去建造,需要的时候才构建,如第四题的creator,在需要的时候才会调用creatMap()与creatPeople(),creator只管调用,而真实的构建是在对应的MapBuilder与PeopleBuilder中。
    • 也就是,户主(client)要建房子,将要建房子的类型(三角顶,白瓷砖外墙)(对应代码的map、people)告诉包工头(Creator),包工头(Creator)吩咐手里的几个工程队(MapBuilder ,PeopleBuilder )去建造,所以,真正的实施,是由工程队完成。

    5、某系统需要提供一个加密模块,将用户信息(如密码等)加密之后再存储在数据库中,系统已经定义好数据库操作类。为了提高开发效率,现要重用已有的加密算法,这些算法由第三方提供,没有源码。如采用Adapter模式如何设计?

    类图如下:

    代码:

    class DBoperator {//已知的数据库操作类 
    
    	public String password;
    	Adapter ad;
    	public void setAdapter(){//在这个类中,一定会有设置adapter的方法
    		//构造一个adapter类继承自原来的adapter
    		ad=new EncryptAdapter();
    		//将密码传过去进行加密即可
    		password=ad.encryptPassword(password);
    	}
    }
    
    abstract class Adapter {
    
    	public abstract String encryptPassword(String password);
    	
    }
    
    class EncryptAdapter extends Adapter{//再新增的adapter中调用第三方算法
    	ThirdMethod method;
    	
    	public String encryptPassword(String password) {
    		// TODO Auto-generated method stub
                    method=new ThirdMethod();
    		return method.doEncrypt(password);
    	}
    	
    }
    
    class ThirdMethod{//adaptee
    	//这里由于不知道具体加密算法的源码 假定方法体是这样 主要是便于测试
    	public String doEncrypt(String pwd){
    		System.out.println("第三方加密pwd");
    		return pwd+"123213";
    		
    	}
    	
    }
    
    //测试代码
    DBoperator dbo=new DBoperator();
    dbo.password="23";
    dbo.setAdapter();
    System.out.println(dbo.password);
    

    小结

    • 适配器模式,就是将原本已存在的方法通过适配器来匹配当前的需求。比如将电脑充电器将电网中的220V标准电压转换成为电脑电池的充电电压。在本题中,已经有数据库操作类和第三方加密算法类,但是,他们无法通讯啊,就如同有电脑和墙壁插座,所以呢,需要一个适配器。将密码传给适配器,让适配器去调用第三方加密算法给出的方法进行操作,再将操作结果返回即可。
  • 相关阅读:
    python经典算法面试题1.5:如何找出单链表中的倒数第K个元素
    python经典面试算法题1.4:如何对链表进行重新排序
    巧妙利用引用,将数组转换成树形数组
    设计模式学习笔记
    Vue-cli项目部署到Nginx
    设计模式
    设计模式
    springboot原理
    类加载机制-深入理解jvm
    JVM内存调优原则及几种JVM内存调优方法
  • 原文地址:https://www.cnblogs.com/pwjaya/p/7782919.html
Copyright © 2011-2022 走看看