IT Blog

  • Blog
  • Technology
    • Architecture
    • CMS
    • CRM
    • Web
    • DotNET
    • Python
    • Database
    • BI
    • Program Language
  • Users
    • Login
    • Register
    • Forgot Password?
  • ENEN
    • ENEN
Architecture
DotNET

用设计模式降低循环复杂性

条件语句的作用是更改控制流,任何程序都离不开条件判断。但条件判断会增加程序的复杂度,过多的条件判断会导致循环复杂度(Cyclomatic Complexity)。 这种复杂度取决于3个因素: 分支变量数 分支数 条件嵌套深度 if else if else if else if switch case 1: ... case 2: ... end switch ...... end if end if end if end if 这种形状也叫 Arrow Anti Pattern。它不仅降低程序的可读性,难以扩展和重用,还会轻易地隐藏许多bug。是我们必须避免的代码。 设计模式注重于软件的重用性和扩展性,但大多数模式都可以用来降低循环复杂度。设计模式可以让不同参与者分担这些条件语句,每个参与者解决一部分问题,这样控制流程就更简单,从而降低他们的循环复杂性。 这里介绍一个用策略(Strategy)设计模式来降低循环复杂度的例子。 假设现在我们可以用 C# 写一个简单的计算器,代码如下: using System; public class Calculator { public double Calculate(double operand1, double operand2, char operater) { double result = 0.0; switch (operater) { case '+': result = operand1 + operand2; break; case '-': result = operand1 - operand2; break; case '*': result = operand1 * operand2; break; case '/': if (Math.Abs(operand2) > 0.0) { result = operand1 / operand2; } else { throw new ArithmeticException("分母为零。"); } break; default: throw new ArgumentException("未知运算符: " + operater); } return result; } public static void Main(String[] args) { args = new[] { "2", "*", "3" }; double operand1 = Double.Parse(args[0]); double operand2 = Double.Parse(args[2]); char operater = args[1][0]; double result = new Calculator().Calculate(operand1, operand2, operater); Console.WriteLine(operand1 + args[1] + operand2 + " = " + result); Console.ReadKey(); } } 现在用策略模式来重构这段代码: 模式角色: Strategy: IProcessor ConcreteStrategy: Adder, Subtractor, Multiplier, Divider Context: Calculator using System; using System.Collections.Generic; public interface IProcessor { double Process(double operand1, double operand2); } public class Adder : IProcessor { public double Process(double operand1, double operand2) { return operand1 + operand2; } } public class Subtractor : IProcessor { public double Process(double operand1, double operand2) { return operand1 - operand2; } } public class Multiplier : IProcessor { public double Process(double operand1, double operand2) { return operand1 * operand2; } } public class Divider : IProcessor { public double Process(double operand1, double operand2) { double…

2020年07月27日 0条评论 339点热度 1人点赞 阅读全文
Architecture

Visual Paradigm v16.1 Installation

Download Visual Paradigm Community https://www.visual-paradigm.com/download/community.jsp?platform=windows&arch=64bit Install Visual Paradigm Online Training https://www.visual-paradigm.com/training/visual-paradigm-essential/ User Guide User Guide

2020年05月14日 0条评论 299点热度 0人点赞 阅读全文
Pattern

Idempotency and Safety

Idempotency it’s the ability to perform the same action multiple times while only producing “side effects” on the server once. An idempotent HTTP method is an HTTP method that can be called many times without different outcomes. Safe action: GET / HEAD / OPTIONS / TRACE Unsafe actions: PUT / POST / DELETE idempotent REST APIs POST is NOT idempotent. GET, PUT, DELETE, HEAD, OPTIONS and TRACE are idempotent. Safety and idempotency of HTTP methods Method Safe? Idempotent? GET Yes Yes HEAD Yes Yes OPTIONS Yes Yes PUT No Yes DELETE No Yes POST No No PATCH No No   How to make it idempotent call Constructing a retry mechanism for non-idempotent requests requires cooperation from the server. the client attaches a unique ID to each request (a GUID/UUID would suffice). When the server processes a request successfully, it saves the ID and a copy of the response it wants to send back. If that response never makes it back to the client, the client will send the request again, reusing the same ID. The server will recognize the ID, skip the actual processing of the request, and just send back the stored response. This makes all requests effectively idempotent from the client's point of view. private string Execute(string queryString){ // maxRequestTries is a private class member set to 3 by default, optionally set via a constructor parameter (not shown) var remainingTries = maxRequestTries; var exceptions = new List(); do { try { --remainingTries; return ExecuteSingle(queryString); } catch (Exception) { exceptions.Add(e); } } while (remainingTries > 0) throw new AggregateException(exceptions) //containing a list of all the exceptions thrown…

2018年10月01日 0条评论 387点热度 0人点赞 阅读全文
Architecture

Develop UNDO feature with Entity Framework 6 and trigger

EF 6.0 overview Entity Framework 6.0 maintains connection and transaction internally when SaveChanges() method is called. It maintains a transaction for multiple entity insert, update and delete in a single SaveChanges() method. Each time calling this method EF creates a new connection and transaction. This become an issue in our UNDO feature, because context_info only available in the same transaction scope. In earlier version of EF, System.Transaction.TransactionScope was used to control the transaction. So passing information to triggers is as easy as adding one additional call to a stored procedure. However, in EF6 this approach was out. New API with EF 6.0 EF 6.0 introduced two new APIs for transaction. DbContext.Database.BeginTransaction: It allows us to start a transaction manually. It allows us to combine several operations to be combined within the same transaction and hence all the transactions are either committed or rolled back. This method allows us to specify the isolation level for the transaction. It returns a DbContextTransaction object. The BeginTransaction method has two overloads, one has no argument and the other accepts an explicit Isolation Level. DbContext.Database.UseTransaction: It allows DbContext to use a transaction that was started outside of the Entity Framework. It means using this API we can use any existing transaction with Entity Framework. Implementation In application: using(var tran = _context.Database.BeginTransaction()) { try { await CallProcAsync("dbo.USP_HIS_ContextInfo @empId={0}, @recordId={1}", UserId, 0); await _context.SaveChangesAsync(); tran.Commit(); } catch { tran.Rollback(); } } In trigger: ALTER trigger [dbo].[trg_update_TBL_E2DIALER_MSI_CellCodes] on [dbo].[TBL_E2DIALER_MSI_CellCodes] after update as begin SET NOCOUNT ON declare @empId varchar(50), @recordId int, @changeID int, @info binary(128) select @info = context_info(),@empId=replace(convert(varchar(255),@info),0x0,'')…

2017年11月29日 0条评论 768点热度 0人点赞 阅读全文
最新 热点 随机
最新 热点 随机
Generating Test Data with SQL Scripts Remote connection to MySQL on SiteGround Hide author information from WordPress How to do some trick to improve WordPress performance Recovering user role in WordPress Sending email using gmail SMTP
How to do some trick to improve WordPress performanceRemote connection to MySQL on SiteGroundGenerating Test Data with SQL ScriptsRecovering user role in WordPressHide author information from WordPress
Fix text overlapping in textarea issue Get horizontal data from "contact-form-7-to-database-extension" plugin Add customized CSS for a wordpress site Open and close all links inside a page for testing Parallax One analysis Undo product custom field value in Ultimate Product Catalog
Categories
  • AdSense
  • Architecture
  • BI
  • C#
  • CSS
  • Database
  • Digital Marketing
  • DotNET
  • Hosting
  • HTML
  • JavaScript
  • PHP
  • Program Language
  • Python
  • Security
  • SEO
  • Technology
  • Web
  • Wordpress

COPYRIGHT © 20203-2021 Hostlike.com. ALL RIGHTS RESERVED.