设计模式第一次作业

设计模式第一次作业

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标准电压转换成为电脑电池的充电电压。在本题中,已经有数据库操作类和第三方加密算法类,但是,他们无法通讯啊,就如同有电脑和墙壁插座,所以呢,需要一个适配器。将密码传给适配器,让适配器去调用第三方加密算法给出的方法进行操作,再将操作结果返回即可。

posted on 2017-11-06 13:25  简单_J  阅读(773)  评论(2编辑  收藏  举报

导航