trabalho macio trabalho projecto de geminação

trabalho macio trabalho projecto de geminação

projeto conteúdo
Este trabalho pertence cursos Primavera 2020 Computer Software Engineering Institute (Roger Ren Jian)
Onde esta exigência no trabalho Geminação trabalho de projecto
aulas de ensino 006
endereço projeto https://github.com/Knowden/IntersectionPlus

A, PSP

PSP2.1 Estágios Personal Software Process Tempo estimado de consumo (minutos) As demoradas reais (minutos)
Planejamento plano
· Estimativa • Estimativa quanto tempo esta tarefa requer 10 10
Desenvolvimento desenvolver
· Análise · Análise de Necessidades (incluindo a aprendizagem de novas tecnologias) 180 300
· Projeto Spec Gerar documentos de projeto 5 5
· Revisão do projeto · Design Review (e seus colegas revisaram os documentos de projeto) 10 10
· Padrão de Codificação · Especificações de código (desenvolvimento de normas apropriadas para o desenvolvimento atual) 10 10
· Projeto · O projeto específico 120 120
· Codificação · Específica de codificação 240 300
· Revisão de código · Revisão de código 60 60
· Teste · Test (autoteste, modificar o código, submeter modificações) 60 60
Comunicando relatório
· Relatório de teste · Relatório de Ensaio 120 180
· Medição Tamanho · Carga de trabalho Computing 10 10
· Postmortem & Plano de Melhoria de Processos · Hindsight, e propor plano de melhoria de processos 10 10
- total 835 1075

Segundo, as informações se esconder, e design de interface de baixo acoplamento

  • ocultação de informações

Refere-se a esconder informações contidas no módulo de criação e determinação, de tal modo que a informação específica (dados ou processo) contidos dentro de um módulo, outros módulos não precisa esta informação, é inacessível. Concebemos o módulo de cálculo externo fornece os resultados, não o processo de cálculo dos dados de exposição e o processo de cálculo que produziram.

  • design de Interface

Nossa interface de jogo focado principalmente no fornecimento de informações funcionais. Essa informação é entrada pelo módulo de interface do usuário através do módulo de interface passa o calculado e, em seguida, apresentados graficamente pelo módulo de interface do usuário através da interface para ler o resultado dos calcula módulo de cálculo. módulo de interface do usuário só precisa saber a transmissão de informações tipo de dados, você não precisa saber qualquer outra informação.

  • fracamente acoplada

E não há nenhuma conexão lógica entre a exibição gráfica e da lógica de computação, apenas a simples transmissão de informações entre os dois módulos. No entanto, as informações de tipo de dados é definido mortos, esse módulo deve implementar o respectivo tipo de dados recebidos

Em terceiro lugar, o cálculo da concepção e implementação do módulo de interface

Em comparação com as implementações anteriores, o módulo de computação só acrescenta uma classe de interface para chamadas de front-end para

Comparado com o conteúdo anterior, isto adiciona segmentos e raios, sua essência é a fazer em torno da linha de fronteira limitado, por isso usamos a extensão dos originais Linemétodos da classe para apoiar esta estendida.

A extensão da Lineclasse adiciona propriedades ao redor da borda

  • linha reta : limites esquerdo e direito são infinitos (uso representação INT_MAX)
  • Linha : limites esquerdo e direito estão determinados valor
  • Ray : valor limite único é determinado, o outro é limite infinito

Assim, o método de cálculo do núcleo original pode ainda trabalho, apenas o específico calculado Pointjuiz para suas coordenadas de intersecção, ou seja, todas as linhas retas são calculados, e depois usar suas próprias fronteiras para filtrar os resultados

Além disso, a adição de manuseamento de excepção funções

Isto é, em parte, usando c++próprio mecanismo de exceção de alcançar.

Nós primeiro analisar o significado do título para uma série de possível situação anormal, então cada anormalidades segmento de código foram possível exceção é lançada, e lançar uma exceção que será criado no back-end informações de exceção , assim apenas detectar a excepção de que a extremidade dianteira, e, em seguida, repetiu para o utilizador, onde as informações de anormalidade para

Quanto ao processo de entrada, usamos uma C++11expressão regular para punho, de acordo com as exigências do assunto, especificar um conjunto de expressões regulares, para cada entrada gráficos acabar de verificar, quando o cheque não vai usar o mesmo elenco modo de processamento de anormalidade

Quatro, diagrama UML

Quinto, a seção de interface de módulo de cálculo de melhoria de desempenho

Para conseguir que o anterior, este tempo para fazer alguma otimização de processamento de ponto flutuante

Antes de adoptar uma long doubledireta hashe ==operações, não apenas hashdemorado, mas também há um problema de precisão, a fim de resolver os problemas nestas áreas, o processamento de ponto flutuante foi otimizado

Os primeiros dados intervalo determinado assunto, estima-se a precisão dos dados geralmente simplesmente floatpode, usamos primeira floatvez long doublepara hasha operação

Enquanto isso pode acelerar a hashvelocidade de operação, precisão, mas o problema ainda não for resolvido, não haverá 0.999999999e 1.000000000problemas, de modo a fim de resolver este problema, usamos $ \ epsilon $ é calculado.

Isto é, antes da adição de um valor mínimo para cada número de ponto flutuante de alta precisão, e, em seguida, truncado para float, tal como o acima mencionado problema seja resolvido.

Através de uma série de processar acima, não só hashdemorado cálculos para resolver o problema, mas também resolver o problema de precisão, fazer as duas coisas.

Os resultados da análise acima do desempenho do detector VS

Em um projeto pessoal, o count_line_with_lineponto principal na demorado comparee hashsobre, mas agora no caso do conteúdo função de cálculo sem grandes mudanças, get_intersection_withe comparecom hashos, shows de receita essencialmente plana demoradas que trouxeram essa otimização ainda é muito grande .

Sexto, a programação contrato

Design by Contract está de acordo com certas disposições do acordo para fazer alguns dados, se você exceder o programa acordado não será mais executado, tais como requisitos de parâmetros de entrada devem ser respeitadas determinadas condições. Tais exigências estritas da entrada e saída de programação pode ser uma boa especificação interface do programa. Deste modo facilitando meio eficiente para atingir a cobertura de teste elevada para assegurar exactidão programa.

O problema com esta abordagem é que a programação requer muita energia e tempo para implementar e validar as disposições do contrato e do contrato, é difícil conseguir uma cobertura grande em projectos de tempo crítico.

Nosso trabalho neste contrato é usado principalmente na interface do módulo de design, tipo de dados de entrada e saída concordou em garantir a precisão da transferência de informações entre os módulos.

módulo de cálculo de exibição sete do teste de unidade

Para algumas funções e exceção manipulação deste novo projeto, nós também testou a primeira fase do projeto para fazer um complemento muito e estender

O acima não é a única classe de teste é uma classe principal está localizado, pois para o teste correspondente na interface do usuário e exe, também, porque a entrada do arquivo de entrada relacionados com a unidade de teste seria mais influenciada pelo ambiente, por isso não não realizar o relevante teste.

	/*
	两个线段,他们可能只有一个端点相交
	*/
	TEST_METHOD(TestTwoSegmentIntersecInEnd) {
		Line line1("S 0 0 1 1");
		Line line2("S 0 0 1 -1");

		std::vector<Point> result = line1.get_intersection_with(line2);
		Assert::AreEqual(1, (int)result.size());
	}

	/*
	两线段共线,且有一个公共交点(端点)
	*/
	TEST_METHOD(TestTwoSegmentInSameLineHaveOneIntersection) {
		Line line1("S 0 0 1 1");
		Line line2("S 1 1 2 2");

		std::vector<Point> result = line1.get_intersection_with(line2);
		Assert::AreEqual(1, (int)result.size());
	}

	/*
	两线段共线,且无交点
	*/
	TEST_METHOD(TestTwoSegmentInSameLineHaveNoIntersection) {
		Line line1("S 0 0 1 1");
		Line line2("S 2 2 3 3");

		std::vector<Point> result = line1.get_intersection_with(line2);
		Assert::AreEqual(0, (int)result.size());
	}

A descrição acima é parte do código de teste, você pode ver que temos um teste mais abrangente para alguns casos marginais, cobrindo cada combinação de circunstâncias, ao mesmo tempo, a fim de facilitar correções de bugs quando ocorre um erro, temos testes mais importantes foram interpretados comentários para facilitar a pós-manutenção.

Oito, o cálculo do módulo porção de manuseamento de excepção instruções

A manipulação de exceção que considera, principalmente, as seguintes categorias

  • formato de parâmetro não está correto (caracteres errados, múltiplos espaços)
  • Raio r <= 0
  • coordenar superação
  • pontos de entrada coincidem
  • Existe um número infinito de intersecção (ilustrações sobrepõem)

Para estes tipos de anomalias acima, serão acondicionados em uma exceção mensagem de erro apropriada jogado, por isso volta UI significativa

	/*
	圆半径异常
	*/
	TEST_METHOD(IllegalCircleRedix1) {
		auto func = [] {
			Solution s;
			s.add_component("C 0 0 0");
		};

		Assert::ExpectException<std::exception>(func);
	}
	/*
	非法字符输入(小写字母,特殊符号)
	*/
	TEST_METHOD(IllegalCharacterInput1) {
		auto func = [] {
			Solution s;
			s.add_component("l 0 0 1 1");
		};

		Assert::ExpectException<std::exception>(func);
	}
	/*
	输入点重合
	*/
	TEST_METHOD(PointCollision1) {
		auto func = [] {
			Solution s;
			s.add_component("L 0 0 0 0");
		};

		Assert::ExpectException<std::exception>(func);
	}
	/*
	两线段共线,且有多个交点(部分重合),期望抛出异常
	*/
	TEST_METHOD(TestTwoSegmentCoverPart) {
		auto func = [] {
			Line line1("S 0 0 3 3");
			Line line2("S 1 1 5 5");
			line1.get_intersection_with(line2);
		};

		Assert::ExpectException<std::exception>(func);
	}
	/*
	各种坐标超限
	*/
	TEST_METHOD(ArgumentOutOfBound1) {
		auto func = [] {
			Solution s;
			s.add_component("C 100001 0 1");
		};

		Assert::ExpectException<std::exception>(func);
	}

Nine, módulo de interface detalhado processo de design

O design da interface do usuário usando VS vem com MFC, MFC tenho que dizer que é um pouco velho, um monte de coisas e difícil de usar e não é fácil de usar, custo de aprendizagem é muito alto, mas o preço é relativamente baixo.

A ideia geral é a de UI projetar os dados lidos diretamente ao módulo de cálculo e os dados funções plotados cruzamento necessário é lido a partir do módulo de computação.

  • Importação de dados de um arquivo

Importar dados relacionados a clicar função está presente no botão IMPORT

void CUIDlg::OnBnClickedImport()
{
	// TODO: 在此添加控件通知处理程序代码
	m_strHistoryPath = "";//文件选择清空
	CFileDialog dlg(TRUE, _T("txt"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("文本文件|*.txt||"));
	if (dlg.DoModal() == IDOK)
	{
		m_strHistoryPath = dlg.GetPathName();
		if (m_strHistoryPath == "")
		{
			MessageBox(_T("未选择文件!"));
			return;
		}
	}
	else		//取消文件导入
	{
		return;
	}
	CStdioFile file;
	CString szLine;
	int i = 0;
	file.Open(m_strHistoryPath, CFile::modeRead);
    //处理文本第一行
	file.ReadString(szLine);
    //处理文本输入数据
	while (file.ReadString(szLine))
	{
		std::string str(CW2A(szLine.GetString()));
        //向计算模块中传递数据并捕获输入相关的异常
		try {
			core.add_component(str);
		}
		catch(std::exception e){
			CString cstr;
			std::string str;
			str = e.what();
			cstr = CA2W(str.c_str());
			MessageBox(cstr);
		}
	}
	//关闭文件
	file.Close();
    //更新图形列表
	getList(m_list);
}

Além disso anomalia ocorre quando um arquivo é importado, selecione um arquivo desses documentos anomalias identificadas pelo módulo de interface do usuário relacionadas ea entrada malformado entrada tal anomalia é identificado pelo módulo de cálculo, a UI capturas módulo tratamento destas anomalias. módulo importado UI dados serão repassados ​​pelo módulo de computação para o módulo de cálculo termina o processamento sem tratamento.

  • adicionar manualmente dados

A entrada de dados pelo usuário clique no botão Adicionar na função ADD é implementado

void CUIDlg::OnBnClickedAdd()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(true);
	std::string str(CW2A(m_input.GetString()));
    //向计算模块中传递数据并捕获输入相关的异常
	try {
		core.add_component(str);
	}
	catch (std::exception e) {
		CString cstr;
		std::string str;
		str = e.what();
		cstr = CA2W(str.c_str());
		MessageBox(cstr);
	}
    //更新图形列表
	m_list.DeleteAllItems();
	line_count = 0;
	getList(m_list);
}
  • Manter uma lista de gráficos

No módulo de interface do usuário, o padrão de ação é uma lista de todas as informações utilizadas na prestação dos gráficos, e fornece o objeto selecionado é apagado apagado funções de execução. Ou seja, depois de clicar em funções gráficas na lista, pressione o botão Excluir para realização de exclusão de gráficos.

Mantém uma lista de escolhas de implementação gráficas pela lista função de clique pela getList()actualização da lista de funções para alcançar

void CUIDlg::OnNMClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;

	NMLISTVIEW* pNMListView = (NMLISTVIEW*)pNMHDR;
	if (pNMListView->iItem != -1)        // 如果iItem不是-1,就说明有列表项被选择
	{
		m_selected = m_list.GetItemText(pNMListView->iItem, 0);
		m_id = m_list.GetItemText(pNMListView->iItem, 1);
        //将选中的图形信息更新到选中的图形文本框中
		UpdateData(false);
	}
}
void CUIDlg::getList(CListCtrl &m_list)
{
	std::vector<Line>::iterator line_iter;
	std::vector<Circle>::iterator circle_iter;
	line_list = core.get_all_line();
	circle_list = core.get_all_circle();
    //处理直线类型的数据的信息
	for (line_iter = line_list.begin(); line_iter != line_list.end(); line_iter++) 
	{
		std::string str;
		if (line_iter->k == INT_MAX)
		{
			str = "x=" + std::to_string(line_iter->b);
		}
		else if (line_iter->k == 0)
		{
			str = "y=" + std::to_string(line_iter->b);
		}
		else
		{
			str = "y=" + std::to_string(line_iter->k) + "x+" + std::to_string(line_iter->b);
		}
		CString id;
		id.Format(_T("L%d"), line_iter->id);
		m_list.InsertItem(line_count, CA2W(str.c_str()));
		m_list.SetItemText(line_count++, 1, id);
	}
    //处理圆的数据的信息
	for (circle_iter = circle_list.begin(); circle_iter != circle_list.end(); circle_iter++)
	{
		std::string str;
		str = "(x-" + std::to_string(circle_iter->center->x) + ")^2 + (y-" 
			  + std::to_string(circle_iter->center->y) + ")^2 = " + std::to_string(circle_iter->r);
		CString id;
		id.Format(_T("C%d"), circle_iter->id);
		m_list.InsertItem(line_count, CA2W(str.c_str()));
		m_list.SetItemText(line_count++, 1, id);
	}
}
  • função de exclusão

Clique função Eliminar é implementado no botão DELETE função, excluir o objeto selecionado pelo usuário na lista de gráficos.

void CUIDlg::OnBnClickedDelete()
{
	// TODO: 在此添加控件通知处理程序代码
	CString t;
	CString id;
	int id_int;
	t = m_id.Left(1);
	id = m_id.Right(1);
	if (t == _T("L"))
	{
		id_int = _ttoi(id);
		core.delete_line_component(id_int);
	}
	else if (t == _T("C"))
	{
		id_int = _ttoi(id);
		core.delete_circle_component(id_int);
	}
	else return;
    //更新图形列表
	m_list.DeleteAllItems();
	line_count = 0;
	getList(m_list);
}
  • desenhar função

Empate o botão é pressionado, uma lista de todos o padrão de módulo de interface gráfica do usuário serão sorteados na prancheta. função Desenhar é implementado em PINTURA função de clique do botão

void CUIDlg::OnBnClickedPaint()
{
	std::vector<Line>::iterator line_iter;
	std::vector<Circle>::iterator circle_iter;
	//获取画板信息
	CRect rect;
	CWnd* pWin = GetDlgItem(IDC_DRAW);
	pWin->GetClientRect(rect);
	CDC* pDc = pWin->GetDC();
	pDc->Rectangle(rect);
	CBrush myBrush;
	CBrush blueBrush;
	CPen blackPen;
	CPen redPen;
	CPen bluePen;
	myBrush.CreateSolidBrush(RGB(192, 250, 233));
	blueBrush.CreateSolidBrush(RGB(0, 0, 255));
	blackPen.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
	redPen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
	bluePen.CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
	//将画板重置
	pDc->FillRect(rect, &myBrush);
	//绘制坐标轴
	pDc->SelectObject(&blackPen);
	pDc->MoveTo(rect.left, rect.bottom / 2);
	pDc->LineTo(rect.right, rect.bottom / 2);
	pDc->MoveTo(rect.right, rect.bottom / 2);
	pDc->LineTo(rect.right - 20, rect.bottom / 2 + 10);
	pDc->MoveTo(rect.right, rect.bottom / 2);
	pDc->LineTo(rect.right - 20, rect.bottom / 2 - 10);
	pDc->MoveTo(rect.right / 2, rect.bottom);
	pDc->LineTo(rect.right / 2, rect.top);
	pDc->MoveTo(rect.right / 2, rect.top);
	pDc->LineTo(rect.right / 2 + 10, rect.top + 20);
	pDc->MoveTo(rect.right / 2, rect.top);
	pDc->LineTo(rect.right / 2 - 10, rect.top + 20);
	int R_MAX = rect.right / 2/ ratio;
	//将原点设为坐标轴心
	pDc->SetViewportOrg(rect.right / 2, rect.bottom / 2);
	// TODO: 在此添加控件通知处理程序代码
	line_list = core.get_all_line();
	//画线类型的图形
	pDc->SelectObject(&redPen);
	for (line_iter = line_list.begin(); line_iter != line_list.end(); line_iter++)
	{
		float k = line_iter->k;
		float b = line_iter->b;
		float left_limit = line_iter->leftLimit < -10000 ? -10000 : line_iter->leftLimit;
		float right_limit = line_iter->rightLimit > 10000 ? 10000 : line_iter->rightLimit;
		if (k == INT_MAX)
		{
			if (b > R_MAX)b = 10000;
			pDc->MoveTo(b*ratio, -(int)left_limit*ratio);
			pDc->LineTo(b*ratio, -(int)right_limit*ratio);
		}
		else
		{
			if (right_limit > R_MAX) right_limit = R_MAX;
			pDc->MoveTo((int)left_limit*ratio, -(int)calY(left_limit, k, b)*ratio);
			pDc->LineTo((int)right_limit*ratio, -(int)calY(right_limit, k, b)*ratio);
		}
	}
	//画圆的图形
	for (circle_iter = circle_list.begin(); circle_iter != circle_list.end(); circle_iter++)
	{
		float x = circle_iter->center->x*ratio;
		float y = circle_iter->center->y*ratio;
		float r = circle_iter->r*ratio;
		CPoint pLeftUp((int)(x - r), (int)(-y - r));
		CPoint pRightDown((int)(x + r), (int)(-y + r));
		if (pLeftUp.x > R_MAX*ratio) continue;
		CRect circle(pLeftUp.x, pLeftUp.y, pRightDown.x, pRightDown.y);
		pDc->SelectStockObject(NULL_BRUSH);
		pDc->Ellipse(&circle);
	}

	std::unordered_set<Point> points;
	std::unordered_set<Point>::iterator point_iter;
	try {
		points = core.get_all_intersection(true);
	}
	catch (std::exception e) {
		CString cstr;
		std::string str;
		str = e.what();
		cstr = CA2W(str.c_str());
		MessageBox(cstr);
	}
    //画交点
	pDc->SelectObject(&bluePen);	//蓝笔标点,点实际是一个实心方块
	for (point_iter = points.begin(); point_iter != points.end(); point_iter++)
	{
		float x = point_iter->x * ratio;
		float y = point_iter->y * ratio;
		if (x > R_MAX*ratio) continue;
		CRect point(x - ratio/4, -y - ratio/4, x + ratio/4, -y + ratio/4);
		pDc->FillRect(point, &blueBrush);
	}
    //在交点个数文本框中更新交点的个数
	m_result = points.size();
	UpdateData(false);
}

Porque MFC não fornece qualquer maneira fácil para desenhar sistema de coordenadas, e, por conseguinte, este método vai começar a desenhar os eixos (semelhante ao princípio e desenhar uma linha recta). Por outro lado, ela não fornece o MFC desenho método e rectas raios, raios, e, portanto, para conseguir uma linha recta predeterminada utilizando a direita e secções restantes alcançado (isto é, desenhar uma linha para além da placa de desenho) para um método de valor fixo. Para além do padrão da placa de desenho, o método de detecção de coordenadas e para além da porção truncada da sua placa de desenho.

Para a exibição do cruzamento, o usuário é capaz de ver claramente a intersecção de localização, nós usamos um determinado comprimento de lado sólida do quadrado azul para representar.

Desde o cálculo das coordenadas não suportam decimal MFC (ou seja MFC menor inteiro unidades de desenho), por isso usamos o módulo coordenar cálculo dado um certo coordenar método de transformação que o módulo de UI na escalado meia- desenho para reduzir erros.

módulo de ancoragem X. ea interface módulo de computação

class _declspec(dllexport) core {
private:
	Solution s;

public:
	void add_component(std::string component);
    void delete_line_component(int id);
	void delete_circle_component(int id);
    
	std::unordered_set<Point> get_all_intersection(bool force);
	std::vector<Line> get_all_line();
	std::vector<Circle> get_all_circle();
};
  • interface de entrada

módulo de interface do usuário add_component(std::string component)de dados de entrada do usuário transmitir para o módulo de computação

UI módulo delete_line_component(int id)impart linear tipo de gráfico a ser excluído para o id módulo de cálculo

UI módulo de delete_circle_component(int id)transferência tipo id círculo padrão a ser excluído para o módulo de computação

  • interface de saída

módulo de interface do usuário através de std::unordered_set<Point> get_all_intersection(bool force)informações recebidas da computação módulo de intersecção

módulo de interface do usuário std::vector<Line> get_all_line()recebe informações do módulo de cálculo padrão de estilo de linha

módulo de interface do usuário através de std::vector<Circle> get_all_circle()informações recebidas do módulo de cálculo padrão tipo circular

XI descrever o processo de geminação

A programação em pares usando o QQ participação ao vivo VS e compartilhamento de tela. participação ao vivo muito poderoso, nós podemos conseguir duas pessoas juntas para modificar o código, mas muitas vezes Caton, e os convidados não podem acessar livremente o arquivo, haverá uma série de transtornos na Bolsa.

compartilhamento de tela QQ-definição apresenta, enquanto baixo, mas relativamente suave, fácil de troca. No entanto, a funcionalidade limitada, naturalmente, não pode fazer edição de código comum.

vantagens e desvantagens XII par de programação

  • vantagens programação em pares

Você pode fazer um homem um homem a revisão do código de escrita, a taxa correta de código de saída, confiabilidade

A habilidade de ser capaz de fazer complementar, emparelhar ambos os lados desempenhar as suas forças

Durante a escola pode amarrar nó nos pontos fortes de cada um, ganhar experiência

  • desvantagem junção de programação

Quando a diferença entre as duas cores é grande, haverá atrito, mas menor eficiência

Algumas pessoas preferem uma programação pessoa, mas a programação com mais de distracção

Se os dois níveis serão muito diferentes circunstâncias uma pessoa que tem escrito um olhar, 1 + 1 <2

  • minha vantagem

Melhor capacidade de aprendizagem, ferramenta de início rápido não pode entrar em contacto com

análise lógica e estruturada pode ser realizada

Fortes habilidades de comunicação, ser capaz de se adaptar a um muito bom companheiro de equipe, e seus companheiros de equipe em execução

  • minha fraqueza

programação fraco, estilo de código um pouco fezes

A capacidade de resolver independentemente problemas dos pobres, muitas vezes não pode rapidamente resolver o bug

  • benefícios para parceiros

habilidades de programação fortes, pode rapidamente escrever código bonita

Ênfase em testes, testando a fazer muito detalhado

Boa comunicação, muitas vezes somos capazes de discutir alguns problemas com a voz

  • deficiências parceiros

Não detalhes no lugar

Treze, módulos fracamente acoplados

Desde o outro grupo não discutiu com antecedência com uma interface boa, por isso a necessidade de adaptação no módulo de interface do usuário após a troca dll mudar mais.

  • Comutação Módulo Alterações
class GeometryFactory{
public:
	GeometryFactory();
	/* Modification */
	int addLine(int type, long long x1, long long x2, long long y1, long long y2);		// 添加直线,传入四个参数,其中type详见constant.h, 返回值为id,会抛出各种异常
	int addCircle(long long x, long long y, long long r);							    // 添加圆, 返回值为id,会抛出各种异常
	void remove(int id);										                        // 删除几何对象,传入参数为id
	/* Query */
	Line getLine(int id);										                        // 获取已经添加的直线,传入参数为id
	Circle getCircle(int id);									                        // 获取已添加的原,传入参数为id
	vector<Point> getPoints();									                        // 获取所有的交点
	int getPointsCount();										                        // 获取交点总数
	int addObjectFromFile(string & message);							                // 解析文件内的一行输入,如“L 0 0 1 1”或“C 0 0 3”,会抛出各种异常
};

Este é o outro lado da interface. Você pode ver, temos a principal diferença entre os dois grupos:

  • linha de armazenamento

O nosso grupo usa métodos oblíquas armazenamento ponto, isto é, k e b são representadas por linhas rectas, e os outros grupos utilizando o modo fórmula geral linear de armazenar, isto é, a utilização de a, b, c para representar uma linha recta. Essa diferença afeta o gráfico método de desenho e exibição método de uma função do módulo de interface do usuário na lista

  • métodos de aquisição de dados gráficos

Podemos agrupar todos os dados gráficos diretamente, enquanto o outro grupo necessidade de passar a fim de propagação id gráficos correspondentes dados gráficos, o que afeta os gráficos atualizar a lista.

  • Método de armazenamento de dados gráfico

Estabelecemos os círculos e linhas retas são divididos em duas categorias, ID único para determinar um padrão único em cada uma das categorias principais. Enquanto o outro grupo, embora os círculos e linhas retas são divididos em duas categorias, mas id não classificou id único para determinar um padrão único em todos os gráficos

Em resumo, o módulo de interface do usuário muda principalmente em getList()função e desenho funções

Alterando a getList()função:

void CUIDlg::getList(CListCtrl &m_list)
{
	std::map<int, string>::iterator id_iter;
	std::vector<Line>::iterator line_iter;
	std::vector<Circle>::iterator circle_iter;
	for (id_iter = id_list.begin(); id_iter != id_list.end(); id_iter++)
	{
		if (id_iter->second == "L")
		{
			Line line;
			line = core.getLine(id_iter->first);
			line_list.push_back(line);
			std::string str;
			if (line_iter->b == 0)
			{
				str = std::to_string(line_iter->a) + "x+" + std::to_string(line_iter->c) + " = 0";
			}
			else if (line_iter->a == 0)
			{
				str = std::to_string(line_iter->b) + "y+" + std::to_string(line_iter->c) + " = 0";
			}
			else
			{
				str = std::to_string(line_iter->a) + "x+" + std::to_string(line_iter->b) + "y+" + std::to_string(line_iter->c) + " = 0";
			}
			CString id;
			id.Format(_T("%d"), id_iter->first);
			m_list.InsertItem(line_count, CA2W(str.c_str()));
			m_list.SetItemText(line_count++, 1, id);
		}
		else
		{
			Circle circle;

			CString id;
			id.Format(_T("%d"), id_iter->first);
			MessageBox(id);

			circle = core.getCircle(id_iter->first);
			circle_list.push_back(circle);
			std::string str;
			str = "(x-" + std::to_string(circle_iter->a) + ")^2 + (y-"
				+ std::to_string(circle_iter->b) + ")^2 = " + std::to_string(circle_iter->r);
			//CString id;
			id.Format(_T("%d"), id_iter->first);
			m_list.InsertItem(line_count, CA2W(str.c_str()));
			m_list.SetItemText(line_count++, 1, id);
		}
	}
}

Porque, independentemente da categoria ID, então IU parte é um map<int, string>recipiente para armazenar a ID, o valor de ID para a chave, o valor para a categoria (linear ou circular) do ID gráfico correspondente pertence, no fim de cada outro pela DLL Line getLine(int id)e Circle getCircle(int id) leitura dados gráficos.

A função principal é a de mudar o método de tiragem para tiragem de uma linha recta, isto é, o ponto oblíquo para a fórmula geral, que é, por conseguinte, não descrita aqui. Também apagar e adicionar métodos pouco fizeram para alterar a finalidade principal é para atender o armazenamento id uns aos outros de dll.

  • Os problemas surgem módulo de troca

Desde que estabelecemos módulo de interface do usuário para leitura de dados é processado sem qualquer lance direta módulo de computação, por isso depois de trocar dll nosso módulo de interface do usuário não pode usar os outros módulos int addLine(int type, long long x1, long long x2, long long y1, long long y2)e int addCircle(long long x, long long y, long long r)interfaces de só pode ser usado int addObjectFromFile(string & message)para processamento de entrada. Mas o outro lado dessa interface parece que há certos problemas, que não trabalhem corretamente cordas, como mostrado também relatou a exceção de erro de formato de seqüência correta e, portanto, não pode alcançar a intersecção correta de calcular e desenhar funções

Testado int addLine(int type, long long x1, long long x2, long long y1, long long y2)e int addCircle(long long x, long long y, long long r)interfaces é nenhum problema, então nós adicionamos uma string manipulação interface UI para encaixar essas duas interfaces, a fim de resolver este problema.

Aumento da seguinte manipulador de entrada para a cadeia

void CUIDlg::addStr(std::string str)
{
	vector<string> strs = testSplit11(str, " ");
	int id;
	if (strs.at(0) == "L")
	{
		id = core.addLine(1, atoi(strs.at(1).c_str()), atoi(strs.at(3).c_str()), atoi(strs.at(2).c_str()), atoi(strs.at(4).c_str()));
		id_list.insert(pair<int, string>(id, "L"));
	}
	else if (strs.at(0) == "R")
	{
		id = core.addLine(2, atoi(strs.at(1).c_str()), atoi(strs.at(3).c_str()), atoi(strs.at(2).c_str()), atoi(strs.at(4).c_str()));
		id_list.insert(pair<int, string>(id, "L"));
	}
	else if (strs.at(0) == "S")
	{
		id = core.addLine(3, atoi(strs.at(1).c_str()), atoi(strs.at(3).c_str()), atoi(strs.at(2).c_str()), atoi(strs.at(4).c_str()));
		id_list.insert(pair<int, string>(id, "L"));
	}
	else if (strs.at(0) == "C")
	{
		id = core.addCircle(atoi(strs.at(1).c_str()), atoi(strs.at(2).c_str()), atoi(strs.at(3).c_str()));
		id_list.insert(pair<int, string>(id, "C"));
	}
}
vector<string> CUIDlg::testSplit11(const string& in, const string& delim)
{
	vector<string> ret;
	regex re{delim};
	return vector<string>{
		sregex_token_iterator(in.begin(), in.end(), re, -1),
			sregex_token_iterator()
	};
	return ret;
}

Após o aumento de exibição de gráficos e uma lista de adições e exclusões podem ser executados corretamente

Acho que você gosta

Origin www.cnblogs.com/huangxianhao/p/12556734.html
Recomendado
Clasificación